/**
 * 聊天记录导入与分析 IPC 处理器
 */

import { ipcMain, app, dialog } from 'electron'
import * as databaseCore from '../database/core'
import * as worker from '../worker/workerManager'
import * as parser from '../parser'
import { detectFormat, diagnoseFormat, type ParseProgress } from '../parser'
import type { IpcContext } from './types'
import { CURRENT_SCHEMA_VERSION, getPendingMigrationInfos, type MigrationInfo } from '../database/migrations'

/**
 * 注册聊天记录相关 IPC 处理器
 */
export function registerChatHandlers(ctx: IpcContext): void {
  const { win } = ctx

  // ==================== 数据库迁移 ====================

  /**
   * 检查是否需要数据库迁移
   */
  ipcMain.handle('chat:checkMigration', async () => {
    try {
      const result = databaseCore.checkMigrationNeeded()
      // 获取待执行的迁移信息（从最低版本开始）
      const pendingMigrations = getPendingMigrationInfos(result.lowestVersion)
      return {
        needsMigration: result.count > 0,
        count: result.count,
        currentVersion: CURRENT_SCHEMA_VERSION,
        pendingMigrations,
      }
    } catch (error) {
      console.error('[IpcMain] 检查迁移失败:', error)
      return { needsMigration: false, count: 0, currentVersion: CURRENT_SCHEMA_VERSION, pendingMigrations: [] }
    }
  })

  /**
   * 执行数据库迁移
   */
  ipcMain.handle('chat:runMigration', async () => {
    try {
      const result = databaseCore.migrateAllDatabases()
      return result
    } catch (error) {
      console.error('[IpcMain] 执行迁移失败:', error)
      return { success: false, migratedCount: 0, error: String(error) }
    }
  })

  // ==================== 聊天记录导入与分析 ====================

  /**
   * 选择聊天记录文件
   */
  ipcMain.handle('chat:selectFile', async () => {
    try {
      const { canceled, filePaths } = await dialog.showOpenDialog({
        title: '选择聊天记录文件',
        defaultPath: app.getPath('documents'),
        properties: ['openFile'],
        filters: [
          { name: '聊天记录', extensions: ['json', 'jsonl', 'txt'] },
          { name: '所有文件', extensions: ['*'] },
        ],
        buttonLabel: '导入',
      })

      if (canceled || filePaths.length === 0) {
        return null
      }

      const filePath = filePaths[0]

      // 检测文件格式（使用流式检测，只读取文件开头）
      const formatFeature = detectFormat(filePath)
      const format = formatFeature?.name || null
      if (!format) {
        // 使用诊断功能获取详细的错误信息
        const diagnosis = diagnoseFormat(filePath)
        // 返回详细的错误信息
        return {
          error: 'error.unrecognized_format',
          diagnosis: {
            suggestion: diagnosis.suggestion,
            partialMatches: diagnosis.partialMatches.map((m) => ({
              formatName: m.formatName,
              missingFields: m.missingFields,
            })),
          },
        }
      }

      return { filePath, format }
    } catch (error) {
      console.error('[IpcMain] Error selecting file:', error)
      return { error: String(error) }
    }
  })

  /**
   * 导入聊天记录（流式版本）
   */
  ipcMain.handle('chat:import', async (_, filePath: string) => {
    try {
      // Send progress: detecting format (message not used by frontend, stage-based translation)
      win.webContents.send('chat:importProgress', {
        stage: 'detecting',
        progress: 5,
        message: '', // Frontend translates based on stage
      })

      // 使用流式导入（在 Worker 线程中执行）
      const result = await worker.streamImport(filePath, (progress: ParseProgress) => {
        // 转发进度到渲染进程
        win.webContents.send('chat:importProgress', {
          stage: progress.stage,
          progress: progress.percentage,
          message: progress.message,
          bytesRead: progress.bytesRead,
          totalBytes: progress.totalBytes,
          messagesProcessed: progress.messagesProcessed,
        })
      })

      if (result.success) {
        console.log('[IpcMain] Stream import successful, sessionId:', result.sessionId)
        return { success: true, sessionId: result.sessionId, diagnostics: result.diagnostics }
      } else {
        console.error('[IpcMain] Stream import failed:', result.error)
        win.webContents.send('chat:importProgress', {
          stage: 'error',
          progress: 0,
          message: result.error,
        })

        // 如果是格式不识别错误，提供诊断信息
        if (result.error === 'error.unrecognized_format') {
          const diagnosis = diagnoseFormat(filePath)
          return {
            success: false,
            error: result.error,
            diagnosis: {
              suggestion: diagnosis.suggestion,
              partialMatches: diagnosis.partialMatches.map((m) => ({
                formatName: m.formatName,
                missingFields: m.missingFields,
              })),
            },
            diagnostics: result.diagnostics,
          }
        }

        return { success: false, error: result.error, diagnostics: result.diagnostics }
      }
    } catch (error) {
      console.error('[IpcMain] Import failed:', error)

      win.webContents.send('chat:importProgress', {
        stage: 'error',
        progress: 0,
        message: String(error),
      })

      return { success: false, error: String(error) }
    }
  })

  /**
   * 获取所有分析会话列表
   */
  ipcMain.handle('chat:getSessions', async () => {
    try {
      const sessions = await worker.getAllSessions()
      return sessions
    } catch (error) {
      console.error('[IpcMain] Error getting sessions:', error)
      return []
    }
  })

  /**
   * 获取单个会话信息
   */
  ipcMain.handle('chat:getSession', async (_, sessionId: string) => {
    try {
      return await worker.getSession(sessionId)
    } catch (error) {
      console.error('获取会话信息失败：', error)
      return null
    }
  })

  /**
   * 删除会话
   */
  ipcMain.handle('chat:deleteSession', async (_, sessionId: string) => {
    try {
      // 先关闭 Worker 中的数据库连接
      await worker.closeDatabase(sessionId)
      // 然后删除文件（使用核心模块）
      const result = databaseCore.deleteSession(sessionId)
      return result
    } catch (error) {
      console.error('删除会话失败：', error)
      return false
    }
  })

  /**
   * 重命名会话
   */
  ipcMain.handle('chat:renameSession', async (_, sessionId: string, newName: string) => {
    try {
      // 先关闭 Worker 中的数据库连接（确保没有其他进程占用）
      await worker.closeDatabase(sessionId)
      // 执行重命名
      return databaseCore.renameSession(sessionId, newName)
    } catch (error) {
      console.error('重命名会话失败：', error)
      return false
    }
  })

  /**
   * 获取可用年份列表
   */
  ipcMain.handle('chat:getAvailableYears', async (_, sessionId: string) => {
    try {
      return await worker.getAvailableYears(sessionId)
    } catch (error) {
      console.error('获取可用年份失败：', error)
      return []
    }
  })

  /**
   * 获取成员活跃度排行
   */
  ipcMain.handle(
    'chat:getMemberActivity',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getMemberActivity(sessionId, filter)
      } catch (error) {
        console.error('获取成员活跃度失败：', error)
        return []
      }
    }
  )

  /**
   * 获取成员历史昵称
   */
  ipcMain.handle('chat:getMemberNameHistory', async (_, sessionId: string, memberId: number) => {
    try {
      return await worker.getMemberNameHistory(sessionId, memberId)
    } catch (error) {
      console.error('获取成员历史昵称失败：', error)
      return []
    }
  })

  /**
   * 获取每小时活跃度分布
   */
  ipcMain.handle(
    'chat:getHourlyActivity',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getHourlyActivity(sessionId, filter)
      } catch (error) {
        console.error('获取小时活跃度失败：', error)
        return []
      }
    }
  )

  /**
   * 获取每日活跃度趋势
   */
  ipcMain.handle(
    'chat:getDailyActivity',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getDailyActivity(sessionId, filter)
      } catch (error) {
        console.error('获取日活跃度失败：', error)
        return []
      }
    }
  )

  /**
   * 获取星期活跃度分布
   */
  ipcMain.handle(
    'chat:getWeekdayActivity',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getWeekdayActivity(sessionId, filter)
      } catch (error) {
        console.error('获取星期活跃度失败：', error)
        return []
      }
    }
  )

  /**
   * 获取月份活跃度分布
   */
  ipcMain.handle(
    'chat:getMonthlyActivity',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getMonthlyActivity(sessionId, filter)
      } catch (error) {
        console.error('获取月份活跃度失败：', error)
        return []
      }
    }
  )

  /**
   * 获取年份活跃度分布
   */
  ipcMain.handle(
    'chat:getYearlyActivity',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getYearlyActivity(sessionId, filter)
      } catch (error) {
        console.error('获取年份活跃度失败：', error)
        return []
      }
    }
  )

  /**
   * 获取消息长度分布
   */
  ipcMain.handle(
    'chat:getMessageLengthDistribution',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getMessageLengthDistribution(sessionId, filter)
      } catch (error) {
        console.error('获取消息长度分布失败：', error)
        return []
      }
    }
  )

  /**
   * 获取消息类型分布
   */
  ipcMain.handle(
    'chat:getMessageTypeDistribution',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getMessageTypeDistribution(sessionId, filter)
      } catch (error) {
        console.error('获取消息类型分布失败：', error)
        return []
      }
    }
  )

  /**
   * 获取时间范围
   */
  ipcMain.handle('chat:getTimeRange', async (_, sessionId: string) => {
    try {
      return await worker.getTimeRange(sessionId)
    } catch (error) {
      console.error('获取时间范围失败：', error)
      return null
    }
  })

  /**
   * 获取数据库存储目录
   */
  ipcMain.handle('chat:getDbDirectory', async () => {
    try {
      return worker.getDbDirectory()
    } catch (error) {
      console.error('获取数据库目录失败：', error)
      return null
    }
  })

  /**
   * 获取支持的格式列表
   */
  ipcMain.handle('chat:getSupportedFormats', async () => {
    return parser.getSupportedFormats()
  })

  /**
   * 获取复读分析数据
   */
  ipcMain.handle(
    'chat:getRepeatAnalysis',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getRepeatAnalysis(sessionId, filter)
      } catch (error) {
        console.error('获取复读分析失败：', error)
        return { originators: [], initiators: [], breakers: [], totalRepeatChains: 0 }
      }
    }
  )

  /**
   * 获取口头禅分析数据
   */
  ipcMain.handle(
    'chat:getCatchphraseAnalysis',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getCatchphraseAnalysis(sessionId, filter)
      } catch (error) {
        console.error('获取口头禅分析失败：', error)
        return { members: [] }
      }
    }
  )

  /**
   * 获取夜猫分析数据
   */
  ipcMain.handle(
    'chat:getNightOwlAnalysis',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getNightOwlAnalysis(sessionId, filter)
      } catch (error) {
        console.error('获取夜猫分析失败：', error)
        return {
          nightOwlRank: [],
          lastSpeakerRank: [],
          firstSpeakerRank: [],
          consecutiveRecords: [],
          champions: [],
          totalDays: 0,
        }
      }
    }
  )

  /**
   * 获取龙王分析数据
   */
  ipcMain.handle(
    'chat:getDragonKingAnalysis',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getDragonKingAnalysis(sessionId, filter)
      } catch (error) {
        console.error('获取龙王分析失败：', error)
        return { rank: [], totalDays: 0 }
      }
    }
  )

  /**
   * 获取潜水分析数据
   */
  ipcMain.handle(
    'chat:getDivingAnalysis',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getDivingAnalysis(sessionId, filter)
      } catch (error) {
        console.error('获取潜水分析失败：', error)
        return { rank: [] }
      }
    }
  )

  /**
   * 获取自言自语分析数据
   */
  ipcMain.handle(
    'chat:getMonologueAnalysis',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getMonologueAnalysis(sessionId, filter)
      } catch (error) {
        console.error('获取自言自语分析失败：', error)
        return { rank: [], maxComboRecord: null }
      }
    }
  )

  /**
   * 获取 @ 互动分析数据
   */
  ipcMain.handle(
    'chat:getMentionAnalysis',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getMentionAnalysis(sessionId, filter)
      } catch (error) {
        console.error('获取 @ 互动分析失败：', error)
        return { topMentioners: [], topMentioned: [], oneWay: [], twoWay: [], totalMentions: 0, memberDetails: [] }
      }
    }
  )

  /**
   * 获取 @ 互动关系图数据
   */
  ipcMain.handle(
    'chat:getMentionGraph',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getMentionGraph(sessionId, filter)
      } catch (error) {
        console.error('获取 @ 互动关系图失败：', error)
        return { nodes: [], links: [], maxLinkValue: 0 }
      }
    }
  )

  /**
   * 获取含笑量分析数据
   */
  ipcMain.handle(
    'chat:getLaughAnalysis',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }, keywords?: string[]) => {
      try {
        return await worker.getLaughAnalysis(sessionId, filter, keywords)
      } catch (error) {
        console.error('获取含笑量分析失败：', error)
        return {
          rankByRate: [],
          rankByCount: [],
          typeDistribution: [],
          totalLaughs: 0,
          totalMessages: 0,
          groupLaughRate: 0,
        }
      }
    }
  )

  /**
   * 获取斗图分析数据
   */
  ipcMain.handle(
    'chat:getMemeBattleAnalysis',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getMemeBattleAnalysis(sessionId, filter)
      } catch (error) {
        console.error('获取斗图分析失败：', error)
        return {
          longestBattle: null,
          rankByCount: [],
          rankByImageCount: [],
          totalBattles: 0,
        }
      }
    }
  )

  /**
   * 获取打卡分析数据（火花榜 + 忠臣榜）
   */
  ipcMain.handle(
    'chat:getCheckInAnalysis',
    async (_, sessionId: string, filter?: { startTs?: number; endTs?: number }) => {
      try {
        return await worker.getCheckInAnalysis(sessionId, filter)
      } catch (error) {
        console.error('获取打卡分析失败：', error)
        return {
          streakRank: [],
          loyaltyRank: [],
          totalDays: 0,
        }
      }
    }
  )

  // ==================== 成员管理 ====================

  /**
   * 获取所有成员列表（含消息数和别名）
   */
  ipcMain.handle('chat:getMembers', async (_, sessionId: string) => {
    try {
      return await worker.getMembers(sessionId)
    } catch (error) {
      console.error('获取成员列表失败：', error)
      return []
    }
  })

  /**
   * 更新成员别名
   */
  ipcMain.handle('chat:updateMemberAliases', async (_, sessionId: string, memberId: number, aliases: string[]) => {
    try {
      return await worker.updateMemberAliases(sessionId, memberId, aliases)
    } catch (error) {
      console.error('更新成员别名失败：', error)
      return false
    }
  })

  /**
   * 删除成员及其所有消息
   */
  ipcMain.handle('chat:deleteMember', async (_, sessionId: string, memberId: number) => {
    try {
      // 先关闭数据库连接
      await worker.closeDatabase(sessionId)
      // 执行删除
      return await worker.deleteMember(sessionId, memberId)
    } catch (error) {
      console.error('删除成员失败：', error)
      return false
    }
  })

  /**
   * 更新会话的所有者（ownerId）
   */
  ipcMain.handle('chat:updateSessionOwnerId', async (_, sessionId: string, ownerId: string | null) => {
    try {
      // 先关闭数据库连接
      await worker.closeDatabase(sessionId)
      // 执行更新
      return databaseCore.updateSessionOwnerId(sessionId, ownerId)
    } catch (error) {
      console.error('更新会话所有者失败：', error)
      return false
    }
  })

  // ==================== SQL 实验室 ====================

  /**
   * 执行用户 SQL 查询
   */
  ipcMain.handle('chat:executeSQL', async (_, sessionId: string, sql: string) => {
    try {
      return await worker.executeRawSQL(sessionId, sql)
    } catch (error) {
      console.error('执行 SQL 失败：', error)
      throw error
    }
  })

  /**
   * 获取数据库 Schema
   */
  ipcMain.handle('chat:getSchema', async (_, sessionId: string) => {
    try {
      return await worker.getSchema(sessionId)
    } catch (error) {
      console.error('获取 Schema 失败：', error)
      return []
    }
  })

  // ==================== 会话索引 ====================

  /**
   * 生成会话索引
   */
  ipcMain.handle('session:generate', async (_, sessionId: string, gapThreshold?: number) => {
    try {
      return await worker.generateSessions(sessionId, gapThreshold)
    } catch (error) {
      console.error('生成会话索引失败：', error)
      throw error
    }
  })

  /**
   * 检查是否已生成会话索引
   */
  ipcMain.handle('session:hasIndex', async (_, sessionId: string) => {
    try {
      return await worker.hasSessionIndex(sessionId)
    } catch (error) {
      console.error('检查会话索引失败：', error)
      return false
    }
  })

  /**
   * 获取会话索引统计信息
   */
  ipcMain.handle('session:getStats', async (_, sessionId: string) => {
    try {
      return await worker.getSessionStats(sessionId)
    } catch (error) {
      console.error('获取会话统计失败：', error)
      return { sessionCount: 0, hasIndex: false, gapThreshold: 1800 }
    }
  })

  /**
   * 清空会话索引
   */
  ipcMain.handle('session:clear', async (_, sessionId: string) => {
    try {
      await worker.clearSessions(sessionId)
      return true
    } catch (error) {
      console.error('清空会话索引失败：', error)
      return false
    }
  })

  /**
   * 更新会话切分阈值
   */
  ipcMain.handle('session:updateGapThreshold', async (_, sessionId: string, gapThreshold: number | null) => {
    try {
      await worker.updateSessionGapThreshold(sessionId, gapThreshold)
      return true
    } catch (error) {
      console.error('更新阈值失败：', error)
      return false
    }
  })

  /**
   * 获取会话列表（用于时间线导航）
   */
  ipcMain.handle('session:getSessions', async (_, sessionId: string) => {
    try {
      return await worker.getSessions(sessionId)
    } catch (error) {
      console.error('获取会话列表失败：', error)
      return []
    }
  })

  // ==================== 会话摘要 ====================

  /**
   * 生成单个会话摘要
   */
  ipcMain.handle(
    'session:generateSummary',
    async (_, dbSessionId: string, chatSessionId: number, locale?: string, forceRegenerate?: boolean) => {
      console.log('[IPC] session:generateSummary 收到请求:', { dbSessionId, chatSessionId, locale, forceRegenerate })
      try {
        const { generateSessionSummary } = await import('../ai/summary')
        const result = await generateSessionSummary(dbSessionId, chatSessionId, locale || 'zh-CN', forceRegenerate || false)
        console.log('[IPC] session:generateSummary 返回:', result)
        return result
      } catch (error) {
        console.error('[IPC] 生成会话摘要失败：', error)
        return { success: false, error: String(error) }
      }
    }
  )

  /**
   * 批量生成会话摘要
   */
  ipcMain.handle(
    'session:generateSummaries',
    async (_, dbSessionId: string, chatSessionIds: number[], locale?: string) => {
      try {
        const { generateSessionSummaries } = await import('../ai/summary')
        return await generateSessionSummaries(dbSessionId, chatSessionIds, locale || 'zh-CN')
      } catch (error) {
        console.error('批量生成会话摘要失败：', error)
        return { success: 0, failed: chatSessionIds.length, skipped: 0 }
      }
    }
  )

  /**
   * 批量检查会话是否可以生成摘要
   */
  ipcMain.handle(
    'session:checkCanGenerateSummary',
    async (_, dbSessionId: string, chatSessionIds: number[]) => {
      try {
        const { checkSessionsCanGenerateSummary } = await import('../ai/summary')
        const results = checkSessionsCanGenerateSummary(dbSessionId, chatSessionIds)
        // 将 Map 转换为普通对象以便 IPC 传输
        const obj: Record<number, { canGenerate: boolean; reason?: string }> = {}
        for (const [id, result] of results) {
          obj[id] = result
        }
        return obj
      } catch (error) {
        console.error('批量检查会话摘要失败：', error)
        return {}
      }
    }
  )

  /**
   * 根据时间范围查询会话列表
   */
  ipcMain.handle(
    'session:getByTimeRange',
    async (_, dbSessionId: string, startTs: number, endTs: number) => {
      console.log('[session:getByTimeRange] 查询参数:', { dbSessionId, startTs, endTs })
      console.log('[session:getByTimeRange] 时间范围:', {
        start: new Date(startTs * 1000).toISOString(),
        end: new Date(endTs * 1000).toISOString(),
      })

      try {
        const { openDatabase } = await import('../database/core')
        const db = openDatabase(dbSessionId, true)
        if (!db) {
          console.log('[session:getByTimeRange] 数据库打开失败')
          return []
        }

        // 先查询总数和时间范围
        const stats = db.prepare('SELECT COUNT(*) as count, MIN(start_ts) as minTs, MAX(start_ts) as maxTs FROM chat_session').get() as { count: number; minTs: number; maxTs: number }
        console.log('[session:getByTimeRange] 数据库会话统计:', {
          count: stats.count,
          minTs: stats.minTs ? new Date(stats.minTs * 1000).toISOString() : null,
          maxTs: stats.maxTs ? new Date(stats.maxTs * 1000).toISOString() : null,
        })

        const sessions = db
          .prepare(
            `
            SELECT
              id,
              start_ts as startTs,
              end_ts as endTs,
              message_count as messageCount,
              summary
            FROM chat_session
            WHERE start_ts >= ? AND start_ts <= ?
            ORDER BY start_ts DESC
          `
          )
          .all(startTs, endTs) as Array<{
          id: number
          startTs: number
          endTs: number
          messageCount: number
          summary: string | null
        }>

        console.log('[session:getByTimeRange] 查询结果数量:', sessions.length)
        return sessions
      } catch (error) {
        console.error('查询时间范围会话失败：', error)
        return []
      }
    }
  )

  /**
   * 获取最近 N 条会话
   */
  ipcMain.handle('session:getRecent', async (_, dbSessionId: string, limit: number) => {
    console.log('[session:getRecent] 查询参数:', { dbSessionId, limit })
    try {
      const { openDatabase } = await import('../database/core')
      const db = openDatabase(dbSessionId, true)
      if (!db) {
        console.log('[session:getRecent] 数据库打开失败')
        return []
      }

      // 先检查表是否存在
      const tableInfo = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='chat_session'").get()
      console.log('[session:getRecent] chat_session 表:', tableInfo ? '存在' : '不存在')

      if (!tableInfo) {
        return []
      }

      const sessions = db
        .prepare(
          `
          SELECT
            id,
            start_ts as startTs,
            end_ts as endTs,
            message_count as messageCount,
            summary
          FROM chat_session
          ORDER BY start_ts DESC
          LIMIT ?
        `
        )
        .all(limit) as Array<{
        id: number
        startTs: number
        endTs: number
        messageCount: number
        summary: string | null
      }>

      console.log('[session:getRecent] 查询结果数量:', sessions.length)
      return sessions
    } catch (error) {
      console.error('查询最近会话失败：', error)
      return []
    }
  })

  // ==================== 增量导入 ====================

  /**
   * 分析增量导入（检测去重后能新增多少消息）
   */
  ipcMain.handle('chat:analyzeIncrementalImport', async (_, sessionId: string, filePath: string) => {
    try {
      // 检测文件格式
      const formatFeature = detectFormat(filePath)
      if (!formatFeature) {
        const diagnosis = diagnoseFormat(filePath)
        return {
          error: 'error.unrecognized_format',
          diagnosis: {
            suggestion: diagnosis.suggestion,
          },
        }
      }

      // 使用 Worker 分析
      const result = await worker.analyzeIncrementalImport(sessionId, filePath)
      return result
    } catch (error) {
      console.error('[IpcMain] 分析增量导入失败:', error)
      return { error: String(error) }
    }
  })

  /**
   * 执行增量导入
   */
  ipcMain.handle('chat:incrementalImport', async (_, sessionId: string, filePath: string) => {
    try {
      // 发送进度
      win.webContents.send('chat:importProgress', {
        stage: 'saving',
        progress: 0,
        message: '',
      })

      const result = await worker.incrementalImport(sessionId, filePath, (progress) => {
        win.webContents.send('chat:importProgress', {
          stage: progress.stage,
          progress: progress.percentage,
          message: progress.message,
        })
      })

      if (result.success) {
        // 重新生成会话索引
        try {
          await worker.generateSessions(sessionId)
        } catch (e) {
          console.error('[IpcMain] 重新生成会话索引失败:', e)
        }
      }

      return result
    } catch (error) {
      console.error('[IpcMain] 执行增量导入失败:', error)
      return { success: false, error: String(error) }
    }
  })
}
