/**
 * MetonaAI Desktop — Preload 脚本
 *
 * 通过 contextBridge 安全地将 IPC 通道暴露给渲染进程。
 * 渲染进程无 Node.js 访问权限，只能通过此桥接层通信。
 */

import { contextBridge, ipcRenderer } from 'electron';
import { electronAPI } from '@electron-toolkit/preload';

/**
 * Metona API — 暴露给渲染进程的安全接口
 */
const metonaAPI = {
  // ===== Agent 交互 =====
  agent: {
    /** 发送用户消息 */
    sendMessage: (message: unknown, sessionId: string) => ipcRenderer.invoke('agent:sendMessage', message, sessionId),
    /** 监听流式事件 */
    onStreamEvent: (callback: (event: unknown) => void) => {
      const listener = (_event: Electron.IpcRendererEvent, data: unknown) => callback(data);
      ipcRenderer.on('agent:streamEvent', listener);
      return () => ipcRenderer.removeListener('agent:streamEvent', listener);
    },
    /** 监听状态变化 */
    onStateChange: (callback: (state: unknown) => void) => {
      const listener = (_event: Electron.IpcRendererEvent, data: unknown) => callback(data);
      ipcRenderer.on('agent:stateChange', listener);
      return () => ipcRenderer.removeListener('agent:stateChange', listener);
    },
    /** 中断会话 */
    abortSession: (sessionId: string) => ipcRenderer.invoke('agent:abortSession', sessionId),
    /** 监听 Provider 切换通知 */
    onProviderSwitched: (callback: (data: unknown) => void) => {
      const listener = (_event: Electron.IpcRendererEvent, data: unknown) => callback(data);
      ipcRenderer.on('agent:providerSwitched', listener);
      return () => ipcRenderer.removeListener('agent:providerSwitched', listener);
    },
  },

  // ===== 会话管理 =====
  sessions: {
    list: () => ipcRenderer.invoke('sessions:list'),
    create: (title?: string) => ipcRenderer.invoke('sessions:create', title),
    rename: (sessionId: string, title: string) => ipcRenderer.invoke('sessions:rename', sessionId, title),
    delete: (sessionId: string) => ipcRenderer.invoke('sessions:delete', sessionId),
    getMessages: (sessionId: string) => ipcRenderer.invoke('sessions:getMessages', sessionId),
    pin: (sessionId: string, pinned: boolean) => ipcRenderer.invoke('sessions:pin', sessionId, pinned),
    archive: (sessionId: string, archived: boolean) => ipcRenderer.invoke('sessions:archive', sessionId, archived),
    deleteMessage: (messageId: string) => ipcRenderer.invoke('sessions:deleteMessage', messageId),
    clearMessages: (sessionId: string) => ipcRenderer.invoke('sessions:clearMessages', sessionId),
    saveTrace: (sessionId: string, data: unknown) => ipcRenderer.invoke('sessions:saveTrace', sessionId, data),
    getTrace: (sessionId: string) => ipcRenderer.invoke('sessions:getTrace', sessionId),
  },

  // ===== MCP 管理 =====
  mcp: {
    listServers: () => ipcRenderer.invoke('mcp:listServers'),
    addServer: (config: unknown) => ipcRenderer.invoke('mcp:addServer', config),
    removeServer: (name: string) => ipcRenderer.invoke('mcp:removeServer', name),
    toggleServer: (name: string, enabled: boolean) => ipcRenderer.invoke('mcp:toggleServer', name, enabled),
  },

  // ===== 记忆系统 =====
  memory: {
    search: (query: string, options?: unknown) => ipcRenderer.invoke('db:searchMemories', query, options),
    listAll: (options?: { type?: string; limit?: number }) =>
      ipcRenderer.invoke('memory:listAll', options),
    delete: (type: string, id: string) => ipcRenderer.invoke('memory:delete', type, id),
  },

  // ===== v0.2.0: 任务管理 =====
  tasks: {
    list: (sessionId?: string) => ipcRenderer.invoke('tasks:list', sessionId),
    create: (data: { sessionId: string; title: string; description?: string; priority?: string; parentId?: string }) =>
      ipcRenderer.invoke('tasks:create', data),
    update: (id: string, updates: { title?: string; description?: string; status?: string; priority?: string; assignedTo?: string }, sessionId: string) =>
      ipcRenderer.invoke('tasks:update', id, updates, sessionId),
    delete: (id: string, sessionId: string) => ipcRenderer.invoke('tasks:delete', id, sessionId),
    // P2（v0.3.13）: 订阅任务变更事件（Agent 通过 task_manager 写入后触发）
    onTaskChanged: (callback: (sessionId: string) => void) => {
      const listener = (_event: unknown, sessionId: string): void => callback(sessionId);
      ipcRenderer.on('task:changed', listener);
      return () => ipcRenderer.removeListener('task:changed', listener);
    },
  },

  // ===== v0.2.0: 审计日志 =====
  audit: {
    verifyChain: () => ipcRenderer.invoke('audit:verifyChain'),
    query: (filters?: { sessionId?: string; eventType?: string; limit?: number }) =>
      ipcRenderer.invoke('audit:query', filters),
  },

  // ===== v0.2.0: 工具确认请求 =====
  tool: {
    onConfirmationRequest: (callback: (request: unknown) => void) => {
      const listener = (_event: Electron.IpcRendererEvent, data: unknown) => callback(data);
      ipcRenderer.on('tool:confirmationRequest', listener);
      return () => ipcRenderer.removeListener('tool:confirmationRequest', listener);
    },
    sendConfirmationResponse: (response: { toolCallId: string; approved: boolean; remember: boolean; autoExecute?: boolean }) =>
      ipcRenderer.send('tool:confirmationResponse', response),
    // v0.3.2: 批量确认响应（并行工具一次性审批）
    sendConfirmationResponseBatch: (response: { toolCallIds: string[]; approved: boolean; remember: boolean; autoExecute?: boolean }) =>
      ipcRenderer.send('tool:confirmationResponseBatch', response),
    // v0.3.2: 拉取当前所有 pending 确认（前端弹框打开时调用，防止 state 覆盖丢失）
    getPendingConfirmations: () =>
      ipcRenderer.invoke('tool:getPendingConfirmations') as Promise<{
        success: boolean;
        data: Array<{
          toolCallId: string;
          toolName: string;
          args: Record<string, unknown>;
          riskLevel: string;
          reason: string;
          expiresAt?: number;
        }>;
      }>,
    // v0.2.0: 持久化自动执行设置
    setAutoExecute: (toolName: string, enabled: boolean) =>
      ipcRenderer.invoke('tool:setAutoExecute', toolName, enabled),
    getAutoExecuteList: () => ipcRenderer.invoke('tool:getAutoExecuteList'),
  },

  // ===== 配置 =====
  config: {
    get: (key: string) => ipcRenderer.invoke('config:get', key),
    set: (key: string, value: unknown) => ipcRenderer.invoke('config:set', key, value),
    // v0.3.9: 批量保存配置，避免串行保存中间态触发 reloadAdapter 失败
    setBatch: (entries: Array<{ key: string; value: unknown }>) =>
      ipcRenderer.invoke('config:setBatch', entries),
    // v0.3.17: 监听配置变更广播（后端 config:set/setBatch 后触发，用于前端 store 实时更新）
    onChanged: (callback: (data: { key: string; value: unknown }) => void) => {
      const listener = (_event: Electron.IpcRendererEvent, data: { key: string; value: unknown }) =>
        callback(data);
      ipcRenderer.on('config:changed', listener);
      return () => ipcRenderer.removeListener('config:changed', listener);
    },
  },

  // ===== 应用工具 =====
  app: {
    getVersion: () => ipcRenderer.invoke('app:getVersion'),
    getAppDataPath: () => ipcRenderer.invoke('app:getAppDataPath'),
    openExternal: (url: string) => ipcRenderer.invoke('app:openExternal', url),
    showItemInFolder: (path: string) => ipcRenderer.invoke('app:showItemInFolder', path),
    selectFolder: (defaultPath?: string) => ipcRenderer.invoke('app:selectFolder', defaultPath),
    restart: () => ipcRenderer.invoke('app:restart'),
    // #49 修复: 前端错误上报通道（主进程可注册 'error:report' handler 记录到 electron-log/审计日志）
    // 使用 send（单向）而非 invoke，即使主进程未注册 handler 也不会 reject
    reportError: (payload: unknown) => ipcRenderer.send('error:report', payload),
  },

  // ===== 工作空间管理 =====
  workspace: {
    check: (targetPath: string) => ipcRenderer.invoke('workspace:check', targetPath),
    inheritFiles: (params: { targetPath: string; sourcePath: string; files: string[] }) =>
      ipcRenderer.invoke('workspace:inheritFiles', params),
    getInfo: () => ipcRenderer.invoke('workspace:getInfo'),
    // #51 修复: 校验源数据库完整性（PRAGMA integrity_check），用于 inheritDatabase 前置校验
    checkDatabaseIntegrity: (sourcePath: string) =>
      ipcRenderer.invoke('workspace:checkDatabaseIntegrity', sourcePath),
  },

  // ===== 工具管理 =====
  tools: {
    list: () => ipcRenderer.invoke('tools:list'),
    toggle: (toolName: string, enabled: boolean) => ipcRenderer.invoke('tools:toggle', toolName, enabled),
    /** v0.3.18 修复: 监听工具就绪事件（MCP 初始化完成后触发） */
    onReady: (callback: (data: { toolCount: number }) => void) => {
      const listener = (_event: Electron.IpcRendererEvent, data: { toolCount: number }) => callback(data);
      ipcRenderer.on('tools:ready', listener);
      return () => ipcRenderer.removeListener('tools:ready', listener);
    },
    /** v0.3.18 修复: 查询工具当前是否已就绪（解决事件竞态，前端注册监听器后立即查询一次） */
    isReady: () => ipcRenderer.invoke('tools:isReady') as Promise<{ ready: boolean; toolCount: number }>,
  },

  // ===== 数据管理 =====
  data: {
    exportData: (sessionId?: string) => ipcRenderer.invoke('data:export', sessionId),
    clearSessions: () => ipcRenderer.invoke('data:clearSessions'),
    clearMemories: () => ipcRenderer.invoke('data:clearMemories'),
    clearAuditLogs: () => ipcRenderer.invoke('data:clearAuditLogs'),
  },

  // ===== SearXNG =====
  searxng: {
    testConnection: (url: string, authKey: string, authType: string) =>
      ipcRenderer.invoke('searxng:testConnection', url, authKey, authType),
  },

  // ===== Toast 通知桥接 =====
  toast: {
    onShow: (callback: (data: { type: string; message: string; options?: unknown }) => void) => {
      const listener = (_event: Electron.IpcRendererEvent, data: { type: string; message: string; options?: unknown }) =>
        callback(data);
      ipcRenderer.on('toast:show', listener);
      return () => ipcRenderer.removeListener('toast:show', listener);
    },
  },
};

// ===== 安全暴露到渲染进程 =====
if (process.contextIsolated) {
  try {
    contextBridge.exposeInMainWorld('electron', electronAPI);
    contextBridge.exposeInMainWorld('metona', metonaAPI);
  } catch (error) {
    console.error('Failed to expose APIs via contextBridge:', error);
    // #7 修复: 生产环境强制失败，防止以不安全状态启动（contextBridge 失败意味着
    // context isolation 边界已破坏，继续运行可能导致渲染进程直接访问 Node API）
    // 开发环境降级到 globalThis 以便调试
    // 审查修复: process.defaultApp 在 sandbox: true 下可能为 undefined，
    // 导致开发环境也无法降级。补充 process.env.NODE_ENV 判断（sandbox 下 process.env 仍可用）
    if (process.env.NODE_ENV === 'development' || process.defaultApp) {
      console.warn('[DEV] Falling back to globalThis assignment — context isolation is weakened');
      (globalThis as unknown as Record<string, unknown>).electron = electronAPI;
      (globalThis as unknown as Record<string, unknown>).metona = metonaAPI;
    } else {
      // 审查修复 M19: 在 throw 前记录详细错误，便于在 DevTools 中排查白屏问题。
      // 生产环境 contextBridge 失败时用户只看到白屏，console.error 至少能在 DevTools 中留下线索。
      console.error('[FATAL] contextBridge failed in production:', error);
      throw error;
    }
  }
} else {
  // context isolation 未启用（不推荐，仅开发环境）
  (globalThis as unknown as Record<string, unknown>).electron = electronAPI;
  (globalThis as unknown as Record<string, unknown>).metona = metonaAPI;
}
