// electron/main/ipc/cache.ts
import { ipcMain, shell, dialog, app } from 'electron'
import * as fs from 'fs/promises'
import * as fsSync from 'fs'
import * as path from 'path'
import type { IpcContext } from './types'
import {
  getAppDataDir,
  getDatabaseDir,
  getCacheDir,
  getAiDataDir,
  getLogsDir,
  getDownloadsDir,
  ensureDir,
  getCustomDataDir,
  setCustomDataDir,
  ensureAppDirs,
} from '../paths'
import { isInsideAppInstallDir } from '../utils/pathUtils'

/**
 * 递归计算目录大小
 */
async function getDirSize(dirPath: string): Promise<number> {
  let totalSize = 0
  try {
    const exists = fsSync.existsSync(dirPath)
    if (!exists) return 0

    const files = await fs.readdir(dirPath, { withFileTypes: true })
    for (const file of files) {
      const filePath = path.join(dirPath, file.name)
      if (file.isDirectory()) {
        totalSize += await getDirSize(filePath)
      } else {
        const stat = await fs.stat(filePath)
        totalSize += stat.size
      }
    }
  } catch (error) {
    console.error('[Cache] Error getting dir size:', dirPath, error)
  }
  return totalSize
}

/**
 * 获取目录中的文件数量
 */
async function getFileCount(dirPath: string): Promise<number> {
  let count = 0
  try {
    const exists = fsSync.existsSync(dirPath)
    if (!exists) return 0

    const files = await fs.readdir(dirPath, { withFileTypes: true })
    for (const file of files) {
      const filePath = path.join(dirPath, file.name)
      if (file.isDirectory()) {
        count += await getFileCount(filePath)
      } else {
        count++
      }
    }
  } catch (error) {
    console.error('[Cache] Error getting file count:', dirPath, error)
  }
  return count
}

export function registerCacheHandlers(_context: IpcContext): void {
  console.log('[IPC] Registering cache handlers...')

  /**
   * 获取所有缓存目录信息
   */
  ipcMain.handle('cache:getInfo', async () => {
    const appDataDir = getAppDataDir()

    // 定义缓存目录（应用数据目录下的子目录）
    const cacheDirectories = [
      {
        id: 'databases',
        name: 'settings.storage.cache.databases.name',
        description: 'settings.storage.cache.databases.description',
        path: getDatabaseDir(),
        icon: 'i-heroicons-circle-stack',
        canClear: false, // 不允许一键清理，因为是重要数据
      },
      {
        id: 'ai',
        name: 'settings.storage.cache.ai.name',
        description: 'settings.storage.cache.ai.description',
        path: getAiDataDir(),
        icon: 'i-heroicons-sparkles',
        canClear: false, // 不允许一键清理
      },
      {
        id: 'cache',
        name: 'settings.storage.cache.statsCache.name',
        description: 'settings.storage.cache.statsCache.description',
        path: getCacheDir(),
        icon: 'i-heroicons-bolt',
        canClear: true,
      },
      // 临时文件已有自动清理机制（应用启动时、合并完成后），无需暴露给用户
      {
        id: 'logs',
        name: 'settings.storage.cache.logs.name',
        description: 'settings.storage.cache.logs.description',
        path: getLogsDir(),
        icon: 'i-heroicons-document-text',
        canClear: true, // 可以清理
      },
    ]

    // 获取每个目录的信息
    const results = await Promise.all(
      cacheDirectories.map(async (dir) => {
        const size = await getDirSize(dir.path)
        const fileCount = await getFileCount(dir.path)
        const exists = fsSync.existsSync(dir.path)

        return {
          ...dir,
          size,
          fileCount,
          exists,
        }
      })
    )

    return {
      baseDir: appDataDir,
      directories: results,
      totalSize: results.reduce((sum, dir) => sum + dir.size, 0),
    }
  })

  /**
   * 获取当前数据目录
   */
  ipcMain.handle('cache:getDataDir', async () => {
    return {
      path: getAppDataDir(),
      isCustom: Boolean(getCustomDataDir()),
    }
  })

  /**
   * 选择数据目录（仅返回路径，不修改设置）
   */
  ipcMain.handle('cache:selectDataDir', async () => {
    try {
      const result = await dialog.showOpenDialog({
        properties: ['openDirectory', 'createDirectory'],
        defaultPath: getAppDataDir(),
        title: '选择数据目录',
        buttonLabel: '选择',
      })

      if (result.canceled || result.filePaths.length === 0) {
        return { success: false }
      }

      const selectedPath = result.filePaths[0]

      // 安全检查：禁止选择应用安装目录（更新时会被清空）
      try {
        const exePath = app.getPath('exe')
        if (isInsideAppInstallDir(selectedPath, exePath)) {
          return {
            success: false,
            error: 'INSTALL_DIR_FORBIDDEN',
          }
        }
      } catch {
        // 获取 exe 路径失败时跳过此检查
      }

      return { success: true, path: selectedPath }
    } catch (error) {
      console.error('[Cache] Error selecting data dir:', error)
      return { success: false, error: String(error) }
    }
  })

  /**
   * 设置数据目录
   */
  ipcMain.handle('cache:setDataDir', async (_, payload: { path?: string | null; migrate?: boolean }) => {
    const targetPath = typeof payload?.path === 'string' ? payload.path : null
    const migrate = payload?.migrate !== false

    const result = setCustomDataDir(targetPath, migrate)
    if (!result.success) {
      return { success: false, error: result.error }
    }

    // 确保新目录结构完整
    ensureAppDirs()

    return {
      success: true,
      from: result.from,
      to: result.to,
    }
  })

  /**
   * 清理指定缓存目录
   */
  ipcMain.handle('cache:clear', async (_, cacheId: string) => {
    const allowedDirs: Record<string, string> = {
      cache: getCacheDir(),
      logs: getLogsDir(),
    }

    const dirPath = allowedDirs[cacheId]
    if (!dirPath) {
      return { success: false, error: '不允许清理此目录' }
    }

    try {
      const exists = fsSync.existsSync(dirPath)
      if (!exists) {
        return { success: true, message: '目录不存在，无需清理' }
      }

      // 删除目录下的所有文件
      const files = await fs.readdir(dirPath)
      for (const file of files) {
        const filePath = path.join(dirPath, file)
        const stat = await fs.stat(filePath)
        if (stat.isDirectory()) {
          await fs.rm(filePath, { recursive: true })
        } else {
          await fs.unlink(filePath)
        }
      }

      console.log(`[Cache] Cleared directory: ${dirPath}`)
      return { success: true }
    } catch (error) {
      console.error('[Cache] Error clearing cache:', error)
      return { success: false, error: String(error) }
    }
  })

  /**
   * 保存文件到系统下载目录
   * 支持两种 data URL 格式：
   * 1. base64: data:image/png;base64,xxx
   * 2. URL 编码: data:text/plain;charset=utf-8,xxx
   */
  ipcMain.handle('cache:saveToDownloads', async (_, filename: string, dataUrl: string) => {
    const downloadsDir = getDownloadsDir()

    try {
      // 系统下载目录应该已存在，但以防万一还是确保一下
      ensureDir(downloadsDir)

      let buffer: Buffer

      // 解析 data URL
      if (dataUrl.includes(';base64,')) {
        // Base64 编码格式（图片等二进制数据）
        const base64Data = dataUrl.split(';base64,')[1]
        buffer = Buffer.from(base64Data, 'base64')
      } else if (dataUrl.includes('charset=utf-8,')) {
        // URL 编码格式（文本数据）
        const textData = dataUrl.split('charset=utf-8,')[1]
        const decodedText = decodeURIComponent(textData)
        buffer = Buffer.from(decodedText, 'utf-8')
      } else {
        // 默认尝试作为 base64 处理
        const base64Data = dataUrl.replace(/^data:[^,]+,/, '')
        buffer = Buffer.from(base64Data, 'base64')
      }

      // 写入文件
      const filePath = path.join(downloadsDir, filename)
      await fs.writeFile(filePath, buffer)

      console.log(`[Cache] Saved file to downloads: ${filePath}`)
      return { success: true, filePath }
    } catch (error) {
      console.error('[Cache] Error saving to downloads:', error)
      return { success: false, error: String(error) }
    }
  })

  /**
   * 在文件管理器中打开缓存目录
   */
  ipcMain.handle('cache:openDir', async (_, cacheId: string) => {
    const dirPaths: Record<string, string> = {
      base: getAppDataDir(),
      databases: getDatabaseDir(),
      cache: getCacheDir(),
      ai: getAiDataDir(),
      logs: getLogsDir(),
      downloads: getDownloadsDir(), // 系统下载目录
    }

    const dirPath = dirPaths[cacheId]
    if (!dirPath) {
      return { success: false, error: '未知的目录' }
    }

    try {
      // 确保目录存在（系统下载目录应该已存在）
      if (!fsSync.existsSync(dirPath)) {
        await fs.mkdir(dirPath, { recursive: true })
      }

      await shell.openPath(dirPath)
      return { success: true }
    } catch (error) {
      console.error('[Cache] Error opening directory:', error)
      return { success: false, error: String(error) }
    }
  })

  /**
   * 获取最新的导入日志文件路径
   */
  ipcMain.handle('cache:getLatestImportLog', async () => {
    const importLogDir = path.join(getLogsDir(), 'import')

    try {
      if (!fsSync.existsSync(importLogDir)) {
        return { success: false, error: '日志目录不存在' }
      }

      const files = await fs.readdir(importLogDir)
      const logFiles = files.filter((f) => f.startsWith('import_') && f.endsWith('.log'))

      if (logFiles.length === 0) {
        return { success: false, error: '没有找到导入日志' }
      }

      // 按修改时间排序，获取最新的
      const fileStats = await Promise.all(
        logFiles.map(async (f) => {
          const filePath = path.join(importLogDir, f)
          const stat = await fs.stat(filePath)
          return { name: f, path: filePath, mtime: stat.mtime.getTime() }
        })
      )

      fileStats.sort((a, b) => b.mtime - a.mtime)
      const latestLog = fileStats[0]

      return { success: true, path: latestLog.path, name: latestLog.name }
    } catch (error) {
      console.error('[Cache] Error getting latest import log:', error)
      return { success: false, error: String(error) }
    }
  })

  /**
   * 在文件管理器中显示并高亮文件
   */
  ipcMain.handle('cache:showInFolder', async (_, filePath: string) => {
    try {
      if (!fsSync.existsSync(filePath)) {
        return { success: false, error: '文件不存在' }
      }

      shell.showItemInFolder(filePath)
      return { success: true }
    } catch (error) {
      console.error('[Cache] Error showing file in folder:', error)
      return { success: false, error: String(error) }
    }
  })
}
