import { contextBridge, ipcRenderer } from 'electron';

/**
 * 预加载脚本：通过 contextBridge 向渲染层暴露受控的 desktopAPI
 * - 渲染层（web-antd）通过 window.desktopAPI 使用桌面能力；浏览器环境没有该对象，
 *   前端封装层（apps/web-antd/src/util/desktop.ts）会自动 no-op 降级
 * - sandbox 模式下本文件必须是 CJS 产物（electron-vite 已按包配置输出 CJS），
 *   且只能使用 Electron 提供的受限 API（contextBridge / ipcRenderer 等）
 */

/**
 * Windows 任务栏角标图：用 canvas 画「红底白字」数字返回 dataURL
 * 为什么在 preload 画：主进程没有 DOM/canvas；preload 运行在渲染进程内有 DOM，
 * 由主进程 setOverlayIcon 消费，这是 Windows 数字角标的社区标准做法
 */
function drawBadgeImage(count: number): string | undefined {
  try {
    const size = 32;
    const canvas = document.createElement('canvas');
    canvas.width = size;
    canvas.height = size;
    const ctx = canvas.getContext('2d');
    if (!ctx) return undefined;
    // 红色圆底
    ctx.beginPath();
    ctx.arc(size / 2, size / 2, size / 2, 0, Math.PI * 2);
    ctx.fillStyle = '#f5222d';
    ctx.fill();
    // 白色数字，超过 99 显示 99+
    const text = count > 99 ? '99+' : String(count);
    ctx.fillStyle = '#ffffff';
    ctx.font = `bold ${text.length > 2 ? 13 : 18}px Arial`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(text, size / 2, size / 2 + 1);
    return canvas.toDataURL('image/png');
  } catch {
    // canvas 不可用时退化为无图（主进程会清除角标），不影响业务
    return undefined;
  }
}

/** 暴露给渲染层的桌面能力集合，字段语义与 web 侧 desktop.ts 封装一一对应 */
const desktopAPI = {
  /** 渲染层判断是否运行在桌面端的唯一标记 */
  isElectron: true as const,
  /** 当前平台：win32 / darwin / linux */
  platform: process.platform,
  /** 获取桌面端版本号（关于/设置展示用） */
  getVersion: (): Promise<string> => ipcRenderer.invoke('desktop:get-version'),
  /** 发送系统通知；route 为点击通知后要跳转的前端路由 */
  notify: (options: { title: string; body: string; route?: string }): Promise<boolean> =>
    ipcRenderer.invoke('desktop:notify', options),
  /** 设置未读角标数量（0 表示清除）；Windows 角标图在此侧 canvas 生成 */
  setBadge: (count: number): Promise<void> =>
    ipcRenderer.invoke('desktop:set-badge', {
      count,
      image: count > 0 && process.platform === 'win32' ? drawBadgeImage(count) : undefined,
    }),
  /** 任务栏闪烁提醒（窗口未聚焦时生效，聚焦后自动清除） */
  flashFrame: (): Promise<void> => ipcRenderer.invoke('desktop:flash-frame'),
  /** 读取开机自启状态 */
  getAutoLaunch: (): Promise<boolean> => ipcRenderer.invoke('desktop:get-auto-launch'),
  /** 设置开机自启，返回设置后的实际状态 */
  setAutoLaunch: (enable: boolean): Promise<boolean> =>
    ipcRenderer.invoke('desktop:set-auto-launch', enable),
  /** 获取系统打印机列表（打印设置下拉用） */
  getPrinters: (): Promise<Array<{ name: string; displayName: string; isDefault: boolean }>> =>
    ipcRenderer.invoke('desktop:get-printers'),
  /** 静默打印：传入拼好的完整 HTML，主进程隐藏窗口出纸 */
  printHTML: (options: {
    html: string;
    deviceName?: string;
    silent?: boolean;
  }): Promise<{ ok: boolean; message?: string }> =>
    ipcRenderer.invoke('desktop:print-html', options),
  /** 读取桌面端设置（打印机名称、静默打印开关等） */
  getSettings: (): Promise<{ printerName: string; silentPrint: boolean }> =>
    ipcRenderer.invoke('desktop:get-settings'),
  /** 增量更新桌面端设置，返回更新后的完整设置 */
  setSettings: (
    patch: Partial<{ printerName: string; silentPrint: boolean }>,
  ): Promise<{ printerName: string; silentPrint: boolean }> =>
    ipcRenderer.invoke('desktop:set-settings', patch),
  /** 手动检查更新（结果由主进程弹窗反馈） */
  checkUpdate: (): Promise<void> => ipcRenderer.invoke('desktop:check-update'),
  /** 唤起并聚焦主窗口 */
  focusWindow: (): Promise<void> => ipcRenderer.invoke('desktop:focus-window'),
  /** 监听「通知点击跳转」事件：主进程通知被点击后回传目标路由，渲染层执行 router.push */
  onNavigate: (callback: (route: string) => void): void => {
    ipcRenderer.on('desktop:navigate', (_event, route: string) => callback(route));
  },
  /** 监听更新事件（available / progress / downloaded / not-available / error），渲染层做轻量提示 */
  onUpdateEvent: (callback: (payload: { type: string; data?: unknown }) => void): void => {
    ipcRenderer.on('desktop:update-event', (_event, payload) => callback(payload));
  },
};

contextBridge.exposeInMainWorld('desktopAPI', desktopAPI);

/** 供 web 侧类型声明引用（apps/web-antd/src/types/desktop.d.ts 与此保持同步） */
export type DesktopAPI = typeof desktopAPI;
