/**
 * Metona Ollama Desktop - Preload 脚本
 */

import { contextBridge, ipcRenderer } from 'electron';
import * as os from 'os';

contextBridge.exposeInMainWorld('metonaDesktop', {
  isDesktop: true,
  info: () => ipcRenderer.invoke('app:info'),
  sys: {
    homeDir: os.homedir(),
    tmpDir: os.tmpdir(),
    shell: process.env.SHELL || process.env.ComSpec || (process.platform === 'win32' ? 'cmd.exe' : 'bash'),
    arch: os.arch(),
    platform: os.platform(),
    hostname: os.hostname(),
    username: os.userInfo().username,
  },
  dialog: {
    openFile: (options?: unknown) => ipcRenderer.invoke('dialog:openFile', options),
    saveFile: (options?: unknown) => ipcRenderer.invoke('dialog:saveFile', options),
    openDirectory: () => ipcRenderer.invoke('dialog:openDirectory')
  },
  fs: {
    readFile: (filePath: string) => ipcRenderer.invoke('fs:readFile', filePath),
    readFileBase64: (filePath: string) => ipcRenderer.invoke('fs:readFileBase64', filePath),
    writeFile: (filePath: string, content: string, encoding?: string) => ipcRenderer.invoke('fs:writeFile', filePath, content, encoding)
  },
  tool: {
    execute: (toolName: string, args: Record<string, unknown>) => ipcRenderer.invoke('tool:execute', toolName, args),
    getConfig: () => ipcRenderer.invoke('tool:getConfig'),
    setAllowedDirs: (dirs: string[]) => ipcRenderer.invoke('tool:setAllowedDirs', dirs),
    setTimeouts: (timeouts: { http?: number; mcp?: number }) => ipcRenderer.invoke('tool:setTimeouts', timeouts)
  },
  notify: (title: string, body: string) => ipcRenderer.invoke('notify', title, body),
  window: {
    minimize: () => ipcRenderer.invoke('window:minimize'),
    maximize: () => ipcRenderer.invoke('window:maximize'),
    close: () => ipcRenderer.invoke('window:close')
  },
  openExternal: (url: string) => ipcRenderer.invoke('shell:openExternal', url),
  onMenuAction: (callback: (action: string) => void) => {
    ipcRenderer.on('menu-action', (_: unknown, action: string) => callback(action));
  },
  onTrayAction: (callback: (action: string) => void) => {
    ipcRenderer.on('tray-action', (_: unknown, action: string) => callback(action));
  },
  onAppQuit: (callback: () => void) => {
    ipcRenderer.on('app-quit', () => callback());
  },
  removeAllListeners: (channel: string) => {
    ipcRenderer.removeAllListeners(channel);
  },
  onMainLog: (callback: (data: { level: string; message: string; detail?: string }) => void) => {
    ipcRenderer.on('main:log', (_: unknown, data: { level: string; message: string; detail?: string }) => callback(data));
  },
  db: {
    saveSession: (session: unknown) => ipcRenderer.invoke('db:saveSession', session),
    getSession: (id: string) => ipcRenderer.invoke('db:getSession', id),
    getAllSessions: () => ipcRenderer.invoke('db:getAllSessions'),
    deleteSession: (id: string) => ipcRenderer.invoke('db:deleteSession', id),
    clearAllSessions: () => ipcRenderer.invoke('db:clearAllSessions'),
    saveMessage: (msg: unknown) => ipcRenderer.invoke('db:saveMessage', msg),
    getMessages: (sessionId: string) => ipcRenderer.invoke('db:getMessages', sessionId),
    saveSetting: (key: string, value: unknown) => ipcRenderer.invoke('db:saveSetting', key, value),
    getSetting: (key: string, defaultValue?: unknown) => ipcRenderer.invoke('db:getSetting', key, defaultValue),
    saveToolCall: (tc: unknown) => ipcRenderer.invoke('db:saveToolCall', tc),
    getToolCalls: (sessionId: string) => ipcRenderer.invoke('db:getToolCalls', sessionId),
    saveTrace: (trace: unknown) => ipcRenderer.invoke('db:saveTrace', trace),
    getTraces: (sessionId: string) => ipcRenderer.invoke('db:getTraces', sessionId),
    exportSessions: () => ipcRenderer.invoke('db:exportSessions'),
    importSessions: (data: unknown) => ipcRenderer.invoke('db:importSessions', data),

    getAllTokenStats: () => ipcRenderer.invoke('db:getAllTokenStats'),
  },
  workspace: {
    getDir: () => ipcRenderer.invoke('workspace:getDir'),
    setDir: (dir: string) => ipcRenderer.invoke('workspace:setDir', dir),
    listDir: (dirPath?: string) => ipcRenderer.invoke('workspace:listDir', dirPath),
    readFile: (filePath: string) => ipcRenderer.invoke('workspace:readFile', filePath),
    exec: (params: { id: string; command: string; cwd?: string }) => {
      ipcRenderer.send('workspace:exec', params);
    },
    kill: (id: string) => {
      ipcRenderer.send('workspace:kill', id);
    },
    onOutput: (callback: (data: { id: string; type: 'stdout' | 'stderr'; data: string }) => void) => {
      ipcRenderer.on('workspace:output', (_: unknown, data: { id: string; type: 'stdout' | 'stderr'; data: string }) => callback(data));
    },
    onExit: (callback: (data: { id: string; code: number | null }) => void) => {
      ipcRenderer.on('workspace:exit', (_: unknown, data: { id: string; code: number | null }) => callback(data));
    },
    /** 无超时工具命令执行，用于 AI Tool Calling */
    execTool: (command: string, cwd?: string) => ipcRenderer.invoke('tool:execute', 'run_command', { command, cwd }),
    /** AI 命令实时输出推送到工作空间终端 */
    onCmdOutput: (callback: (data: { command: string; type: 'stdout' | 'stderr'; data: string }) => void) => {
      ipcRenderer.on('cmd:output', (_: unknown, data: { command: string; type: 'stdout' | 'stderr'; data: string }) => callback(data));
    },
    /** AI 命令执行完毕 */
    onCmdDone: (callback: (data: { command: string; exitCode: number | null }) => void) => {
      ipcRenderer.on('cmd:done', (_: unknown, data: { command: string; exitCode: number | null }) => callback(data));
    },
    /** 终止当前 AI 命令 */
    cmdKill: () => ipcRenderer.invoke('cmd:kill')
  },
  mcp: {
    startServer: (config: { name: string; command: string; args: string[]; enabled: boolean; description?: string }) => ipcRenderer.invoke('mcp:startServer', config),
    stopServer: (name: string) => ipcRenderer.invoke('mcp:stopServer', name),
    stopAll: () => ipcRenderer.invoke('mcp:stopAll'),
    callTool: (serverName: string, toolName: string, args: Record<string, unknown>) => ipcRenderer.invoke('mcp:callTool', serverName, toolName, args),
    getTools: () => ipcRenderer.invoke('mcp:getTools'),
    getStatuses: () => ipcRenderer.invoke('mcp:getStatuses'),
    refreshTools: (name: string) => ipcRenderer.invoke('mcp:refreshTools', name)
  },
  video: {
    extractFrames: (filePath: string, options?: { maxFrames?: number; maxWidth?: number; maxSize?: number }) =>
      ipcRenderer.invoke('video:extractFrames', filePath, options),
    onProgress: (callback: (data: { current: number }) => void) => {
      ipcRenderer.on('video:progress', (_: unknown, data: { current: number }) => callback(data));
    },
    removeProgressListener: () => {
      ipcRenderer.removeAllListeners('video:progress');
    }
  },
  memoryAccess: {
    read: () => ipcRenderer.invoke('memory:read'),
    write: (content: string) => ipcRenderer.invoke('memory:write', content),
    init: () => ipcRenderer.invoke('memory:init'),
  }
});
