/**
 * MetonaAI Desktop — Electron 主进程入口
 *
 * 启动流程（按架构规范强制顺序）：
 * 1. 初始化日志系统
 * 2. 选择/创建工作空间 → 校验必需文件（缺失自动创建）
 * 3. 连接 SQLite → 执行 schema 迁移 → 加载配置
 * 4. 初始化 Provider Adapter
 * 5. 加载 4 个磁盘文件 → 构建 System Prompt
 * 6. 注册内置工具 + 连接 MCP Servers
 * 7. 启动 React UI → Agent 就绪
 *
 * @see docs/MetonaAI-Desktop 架构与交互设计.html — 启动流程
 * @see docs/MetonaAI-Desktop UI UX 设计集成方案.html — 窗口管理
 */

import { app, shell, Menu } from 'electron';
import { join } from 'path';
import { electronApp, optimizer } from '@electron-toolkit/utils';
import log from 'electron-log';
import { DatabaseService } from './services/database.service';
import { SessionService } from './services/session.service';
import { ConfigService } from './services/config.service';
import { WorkspaceService } from './services/workspace.service';
import { AuditService } from './services/audit.service';
import { SessionRecorder } from './services/session-recorder.service';
import { TrayManager } from './services/tray-manager.service';
import { WindowManager } from './services/window-manager.service';
import { MCPManager } from './services/mcp-manager.service';
import { ContextBuilder } from './harness/prompts/context-builder';
import { MemoryManager } from './harness/memory/manager';
import { registerAllIPCHandlers } from './ipc/handlers';
import { AgentLoopEngine } from './harness/agent-loop';
import { ToolRegistry } from './harness/tools/registry';
import { DeepSeekAdapter } from './harness/adapters/deepseek.adapter';
import { AgnesAdapter } from './harness/adapters/agnes-ai.adapter';
import { OllamaAdapter } from './harness/adapters/ollama.adapter';
import {
  ReadFileTool, WriteFileTool, ListDirectoryTool, SearchFilesTool,
  WebSearchTool, WebExtractTool,
  MemoryStoreTool, MemorySearchTool,
  RunCommandTool,
} from './harness/tools/built-in';
import { AuditLogHook, MemoryTriggerHook, PermissionCheckHook, RateLimitHook } from './harness/hooks';
import { PolicyEngine } from './harness/sandbox/permissions';
import { SandboxManager } from './harness/sandbox/sandbox';
import { PromptInjectionDefender } from './harness/security/prompt-injection-defense';
import { OutputValidator } from './harness/verification/output-validator';

// ===== 步骤 1: 初始化日志系统（SYS 层）=====
log.transports.file.level = 'info';
log.transports.console.level = 'debug';

let databaseService: DatabaseService | null = null;
let trayManager: TrayManager | null = null;
let windowManager: WindowManager | null = null;

async function initialize(): Promise<void> {
  log.info('MetonaAI Desktop starting...');
  electronApp.setAppUserModelId('com.metona.ai-desktop');

  // 移除原生菜单栏
  Menu.setApplicationMenu(null);

  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window);
  });

  // ===== 步骤 2: 工作空间 =====
  const workspaceService = new WorkspaceService();
  const workspaceInfo = workspaceService.initialize();
  log.info(`Workspace: ${workspaceInfo.path} (missing: ${workspaceInfo.missingFiles.join(', ') || 'none'})`);

  // ===== 步骤 3: SQLite =====
  databaseService = new DatabaseService(workspaceInfo.path);
  databaseService.initialize();
  const db = databaseService.getDB();

  const sessionService = new SessionService(() => db);
  const configService = new ConfigService(() => db);

  // ===== 日志服务 =====
  const auditService = new AuditService(() => db);
  const sessionRecorder = new SessionRecorder(workspaceInfo.path);

  // ===== 记忆系统 =====
  const memoryManager = new MemoryManager(() => db);
  memoryManager.initialize();

  // ===== 步骤 4: Provider Adapter =====
  const provider = configService.get<string>('llm.provider') ?? '';
  const model = configService.get<string>('llm.model') ?? '';
  const apiKey = configService.get<string>('llm.apiKey') ?? '';
  const baseURL = configService.get<string>('llm.baseURL') ?? '';

  if (!provider || !baseURL || !model) {
    log.warn('LLM not configured. Please set provider, baseURL, and model in Settings.');
  }

  const adapterConfig = { provider, baseURL, apiKey, defaultModel: model };
  let adapter;
  switch (provider) {
    case 'agnes': adapter = new AgnesAdapter(adapterConfig); break;
    case 'ollama': adapter = new OllamaAdapter(adapterConfig); break;
    default: adapter = new DeepSeekAdapter(adapterConfig); break;
  }

  // ===== 步骤 5: 工作空间文件 + System Prompt =====
  const contextBuilder = new ContextBuilder();

  // ===== 步骤 6: 注册 9 个内置工具 =====
  const toolRegistry = new ToolRegistry();
  toolRegistry.registerBuiltin(new ReadFileTool());
  toolRegistry.registerBuiltin(new WriteFileTool());
  toolRegistry.registerBuiltin(new ListDirectoryTool());
  toolRegistry.registerBuiltin(new SearchFilesTool());
  toolRegistry.registerBuiltin(new WebSearchTool());
  toolRegistry.registerBuiltin(new WebExtractTool());
  toolRegistry.registerBuiltin(new MemoryStoreTool(memoryManager));
  toolRegistry.registerBuiltin(new MemorySearchTool(memoryManager));
  toolRegistry.registerBuiltin(new RunCommandTool());
  log.info(`Registered ${toolRegistry.size} built-in tools`);

  // ===== MCP Manager =====
  const mcpManager = new MCPManager(() => db, toolRegistry);
  mcpManager.initialize().catch((err) => {
    log.warn('MCP Manager initialization error:', err);
  });

  // ===== 安全模块 =====
  const policyEngine = new PolicyEngine();
  const sandboxManager = new SandboxManager({
    allowedPaths: [workspaceInfo.path],
    networkPolicy: 'allowlist',
  });
  const promptDefender = new PromptInjectionDefender();
  const outputValidator = new OutputValidator();

  // ===== Hooks =====
  const preToolHooks = [
    new PermissionCheckHook(policyEngine),
    new RateLimitHook(20),
  ];
  const postToolHooks = [
    new AuditLogHook(auditService),
    new MemoryTriggerHook(memoryManager),
  ];

  // ===== Agent Loop =====
  const ollamaNumCtx = configService.get<number>('ollama.numCtx');
  const agentMaxIter = configService.get<number>('agent.maxIterations');
  const agentTimeout = configService.get<number>('agent.totalTimeoutMs');
  const agentLoop = new AgentLoopEngine(
    {
      maxIterations: agentMaxIter ?? 20,
      totalTimeoutMs: agentTimeout ?? 600_000,
      contextLength: ollamaNumCtx ?? undefined,
    },
    adapter, toolRegistry, preToolHooks, postToolHooks,
  );
  agentLoop.setTools(toolRegistry.listTools());
  agentLoop.setWorkspacePath(workspaceInfo.path);

  // ===== 窗口管理 =====
  windowManager = new WindowManager();
  const mainWindow = windowManager.createWindow({
    id: 'main',
    workspacePath: workspaceInfo.path,
    title: 'MetonaAI Desktop',
  });

  // ===== 系统托盘 =====
  const resourcesPath = join(__dirname, '../../assets');
  trayManager = new TrayManager(resourcesPath);
  trayManager.initialize(mainWindow);

  // ===== 全局快捷键 =====
  windowManager.registerGlobalShortcuts();

  // ===== Agent 状态同步到托盘 =====
  agentLoop.on('stateChange', (data: { previous: string; current: string }) => {
    const statusMap: Record<string, 'idle' | 'thinking' | 'executing' | 'error'> = {
      INIT: 'idle', THINKING: 'thinking', PARSING: 'thinking',
      EXECUTING: 'executing', OBSERVING: 'executing', REFLECTING: 'thinking',
      COMPRESSING: 'thinking', TERMINATED: 'idle',
    };
    trayManager?.setStatus(statusMap[data.current] ?? 'idle');
  });

  // ===== Agent 完成时发送系统通知 =====
  agentLoop.on('complete', (data: { sessionId: string; durationMs: number }) => {
    trayManager?.sendNotification(
      'MetonaAI — 任务完成',
      `Agent 已完成任务 (${(data.durationMs / 1000).toFixed(1)}s)`,
      () => windowManager?.focusWindow(),
    );
  });

  // ===== 注册 IPC =====
  registerAllIPCHandlers(
    mainWindow, sessionService, configService, workspaceService,
    contextBuilder, agentLoop, toolRegistry, auditService,
    sessionRecorder, memoryManager, mcpManager,
  );

  // ===== 应用生命周期 =====
  app.on('window-all-closed', () => {
    // macOS: 保持应用运行（托盘模式）
  });

  app.on('activate', () => {
    if (windowManager && windowManager.count === 0) {
      windowManager.createWindow({ id: 'main', workspacePath: workspaceInfo.path });
    } else {
      windowManager?.focusWindow();
    }
  });

  app.on('before-quit', () => {
    // 标记为正在退出，允许窗口关闭
    (global as Record<string, unknown>).isQuitting = true;
    windowManager?.unregisterGlobalShortcuts();
    trayManager?.destroy();
    windowManager?.closeAll();
    mcpManager.shutdown().catch(() => {});
    if (databaseService) { databaseService.close(); databaseService = null; }
  });

  log.info(`MetonaAI Desktop initialized [Provider: ${provider}, Model: ${model}, Tools: ${toolRegistry.size}]`);
}

app.whenReady().then(initialize);

app.on('web-contents-created', (_, contents) => {
  contents.setWindowOpenHandler(({ url }) => { shell.openExternal(url); return { action: 'deny' }; });
});
