/**
 * 基于 expo-file-system 的磁盘日志持久化后端（ExpoLogFileBackend）。
 *
 * 将日志按照 app-YYYY-MM-DD.log 格式追加写入手机本地 documentDirectory/logs/ 目录。
 */

import * as FileSystem from 'expo-file-system/legacy';
import type { LogFileBackend, LogFileInfo } from '../utils/logger';

const LOG_DIR = `${FileSystem.documentDirectory ?? ''}logs/`;

export class ExpoLogFileBackend implements LogFileBackend {
  private dirChecked = false;

  private async ensureDir(): Promise<void> {
    if (this.dirChecked) return;
    try {
      const info = await FileSystem.getInfoAsync(LOG_DIR);
      if (!info.exists) {
        await FileSystem.makeDirectoryAsync(LOG_DIR, { intermediates: true });
      }
      this.dirChecked = true;
    } catch {
      // 忽略创建失败，下次重试
    }
  }

  async appendLog(dateStr: string, logLine: string): Promise<void> {
    await this.ensureDir();
    const filePath = `${LOG_DIR}app-${dateStr}.log`;
    try {
      const info = await FileSystem.getInfoAsync(filePath);
      let existing = '';
      if (info.exists) {
        existing = await FileSystem.readAsStringAsync(filePath);
      }
      await FileSystem.writeAsStringAsync(filePath, existing + logLine);
    } catch {
      // 极罕见写入异常，静默处理
    }
  }

  async readLogFile(dateStr: string): Promise<string> {
    await this.ensureDir();
    const filePath = `${LOG_DIR}app-${dateStr}.log`;
    try {
      const info = await FileSystem.getInfoAsync(filePath);
      if (!info.exists) return '';
      return await FileSystem.readAsStringAsync(filePath);
    } catch {
      return '';
    }
  }

  async listLogFiles(): Promise<LogFileInfo[]> {
    await this.ensureDir();
    try {
      const files = await FileSystem.readDirectoryAsync(LOG_DIR);
      const results: LogFileInfo[] = [];

      for (const fileName of files) {
        // 匹配 app-YYYY-MM-DD.log
        const match = /^app-(\d{4}-\d{2}-\d{2})\.log$/.exec(fileName);
        if (!match) continue;

        const dateStr = match[1];
        const filePath = `${LOG_DIR}${fileName}`;
        const info = await FileSystem.getInfoAsync(filePath);
        const size = info.exists && 'size' in info ? (info.size ?? 0) : 0;

        results.push({
          name: fileName,
          path: filePath,
          size,
          date: dateStr,
        });
      }

      // 按日期倒序排列（最新在前）
      results.sort((a, b) => b.date.localeCompare(a.date));
      return results;
    } catch {
      return [];
    }
  }

  async deleteLogFile(dateStr: string): Promise<void> {
    await this.ensureDir();
    const filePath = `${LOG_DIR}app-${dateStr}.log`;
    try {
      await FileSystem.deleteAsync(filePath, { idempotent: true });
    } catch {
      // 忽略删除失败
    }
  }

  async clearAllLogFiles(): Promise<void> {
    await this.ensureDir();
    try {
      const files = await FileSystem.readDirectoryAsync(LOG_DIR);
      for (const fileName of files) {
        if (fileName.startsWith('app-') && fileName.endsWith('.log')) {
          await FileSystem.deleteAsync(`${LOG_DIR}${fileName}`, { idempotent: true });
        }
      }
    } catch {
      // 忽略清理失败
    }
  }
}

/** 全局导出的单例日志文件后端。 */
export const expoLogBackend = new ExpoLogFileBackend();
