/**
 * Window Manager — 多窗口管理
 *
 * 职责：
 * 1. 创建和管理多个窗口（每个工作空间可独立开窗口）
 * 2. 窗口状态持久化（位置、大小）
 * 3. 全局快捷键注册（Cmd+Shift+M 切换到 Metona）
 * 4. 关闭到托盘行为
 *
 * @see docs/MetonaAI-Desktop UI UX 设计集成方案.html — 窗口管理
 */

import { BrowserWindow, globalShortcut, app, shell } from 'electron';
import { join } from 'path';
import { existsSync } from 'fs';
import { is } from '@electron-toolkit/utils';
import log from 'electron-log';

export interface WindowState {
  x?: number;
  y?: number;
  width: number;
  height: number;
  isMaximized?: boolean;
}

export class WindowManager {
  private windows = new Map<string, BrowserWindow>();
  private activeWindowId: string | null = null;

  /**
   * 创建新窗口
   */
  createWindow(options: {
    id?: string;
    workspacePath?: string;
    title?: string;
    state?: WindowState;
    beforeLoad?: (win: BrowserWindow) => void;
  }): BrowserWindow {
    const id = options.id ?? `window_${Date.now()}`;
    const state = options.state ?? { width: 1440, height: 900 };

    const win = new BrowserWindow({
      width: state.width,
      height: state.height,
      x: state.x,
      y: state.y,
      minWidth: 960,
      minHeight: 600,
      icon: this.getIconPath(),
      show: false,
      titleBarStyle: 'hiddenInset',
      title: options.title ?? 'MetonaAI Desktop',
      webPreferences: {
        preload: join(__dirname, '../preload/preload.mjs'),
        // sandbox: false — preload 使用 ESM 格式（.mjs + import 语法），
        //   Electron sandbox 不支持 ESM preload（官方 ESM 支持矩阵: Sandboxed = Unsupported）。
        //   若启用 sandbox: true，preload.mjs 的 import 语句无法解析，contextBridge 不执行，
        //   window.metona 为 undefined，所有 IPC 调用静默失败。
        //   要启用 sandbox，需先将 preload 改为 CJS 格式 + require 语法（工程改动较大）。
        sandbox: false,
        contextIsolation: true,
        nodeIntegration: false,
      },
    });

    // P2-11 修复: 在 loadURL 之前执行回调，确保 IPC handler 在渲染进程加载前注册
    if (options.beforeLoad) options.beforeLoad(win);

    // 加载页面
    if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
      win.loadURL(process.env['ELECTRON_RENDERER_URL']);
    } else {
      win.loadFile(join(__dirname, '../../dist/index.html'));
    }

    // 窗口事件
    win.on('ready-to-show', () => {
      if (state.isMaximized) {
        win.maximize();
      }
      win.show();
    });

    win.on('closed', () => {
      this.windows.delete(id);
      if (this.activeWindowId === id) {
        this.activeWindowId = this.windows.size > 0 ? this.windows.keys().next().value ?? null : null;
      }
    });

    win.webContents.setWindowOpenHandler(({ url }) => {
      // C-8 修复: 校验 URL 协议，只允许 http/https，防止 javascript:/file: 等协议执行代码
      try {
        const parsed = new URL(url);
        if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {
          shell.openExternal(url);
        } else {
          log.warn(`[WindowManager] Blocked window.open with unsafe protocol: ${parsed.protocol}`);
        }
      } catch {
        log.warn(`[WindowManager] Blocked window.open with invalid URL: ${url.slice(0, 100)}`);
      }
      return { action: 'deny' };
    });

    this.windows.set(id, win);
    this.activeWindowId = id;

    log.info(`Window created: ${id} (${options.title ?? 'MetonaAI Desktop'})`);

    return win;
  }

  /**
   * 获取窗口
   */
  getWindow(id: string): BrowserWindow | undefined {
    return this.windows.get(id);
  }

  /**
   * 获取活动窗口
   */
  getActiveWindow(): BrowserWindow | null {
    if (this.activeWindowId) {
      return this.windows.get(this.activeWindowId) ?? null;
    }
    return null;
  }

  /**
   * 获取所有窗口
   */
  getAllWindows(): BrowserWindow[] {
    return Array.from(this.windows.values());
  }

  /**
   * 聚焦到窗口（从任意应用切换）
   */
  focusWindow(): void {
    const win = this.getActiveWindow();
    if (win) {
      if (win.isMinimized()) {
        win.restore();
      }
      win.show();
      win.focus();
    }
  }

  /**
   * 注册全局快捷键
   */
  registerGlobalShortcuts(): void {
    // Cmd/Ctrl+Shift+M — 从任意应用切换到 Metona
    const registered = globalShortcut.register('CommandOrControl+Shift+M', () => {
      this.focusWindow();
      log.info('Global shortcut: Switch to Metona');
    });

    if (!registered) {
      log.warn('Failed to register global shortcut: Cmd+Shift+M');
    } else {
      log.info('Global shortcut registered: Cmd+Shift+M');
    }
  }

  /**
   * 注销全局快捷键
   */
  unregisterGlobalShortcuts(): void {
    globalShortcut.unregisterAll();
    log.info('Global shortcuts unregistered');
  }

  /**
   * 获取窗口状态（用于持久化）
   */
  getWindowState(id: string): WindowState | null {
    const win = this.windows.get(id);
    if (!win) return null;

    const bounds = win.getBounds();
    return {
      x: bounds.x,
      y: bounds.y,
      width: bounds.width,
      height: bounds.height,
      isMaximized: win.isMaximized(),
    };
  }

  /**
   * 关闭所有窗口
   */
  closeAll(): void {
    for (const [id, win] of this.windows) {
      try {
        win.destroy();
      } catch {
        log.warn(`Failed to close window: ${id}`);
      }
    }
    this.windows.clear();
    this.activeWindowId = null;
  }

  /**
   * 获取窗口数量
   */
  get count(): number {
    return this.windows.size;
  }

  /**
   * 获取应用图标路径
   */
  private getIconPath(): string | undefined {
    const candidates = [
      join(__dirname, '../../assets/logo.ico'),
      join(__dirname, '../../assets/logo.png'),
      join(process.resourcesPath || '', 'app.asar.unpacked', 'assets/logo.ico'),
      join(process.resourcesPath || '', 'app.asar.unpacked', 'assets/logo.png'),
      join(process.resourcesPath || '', 'assets/logo.ico'),
      join(process.resourcesPath || '', 'assets/logo.png'),
    ];
    for (const p of candidates) {
      if (existsSync(p)) return p;
    }
    return undefined;
  }
}
