import { app, ipcMain, Notification } from 'electron';

import { getAutoLaunchEnabled, setAutoLaunchEnabled } from './auto-launch';
import { applyBadge } from './badge';
import { printHtml, type PrintHtmlOptions } from './printer';
import { getSettings, updateSettings, type DesktopSettings } from './settings';
import { refreshTrayMenu } from './tray';
import { checkForUpdates } from './updater';
import { getMainWindow, isTrustedPageUrl, showMainWindow } from './window';

/**
 * IPC 汇总：preload 暴露的 desktopAPI 全部经由这里进入主进程
 * 所有 handler 先校验调用方来源（app:// 或开发服务器），
 * 防止页面内嵌第三方 iframe 等场景越权调用桌面能力
 */

/** 校验 IPC 调用来源，不可信来源直接抛错拒绝 */
function assertTrustedSender(event: Electron.IpcMainInvokeEvent): void {
  const url = event.senderFrame?.url ?? '';
  if (!isTrustedPageUrl(url)) {
    throw new Error(`拒绝来自不可信来源的 IPC 调用: ${url}`);
  }
}

/** 系统通知参数（route 用于点击通知后让渲染端跳转对应页面） */
interface NotifyPayload {
  title: string;
  body: string;
  route?: string;
}

export function registerIpcHandlers(): void {
  // 应用版本号（渲染端「关于/设置」展示用）
  ipcMain.handle('desktop:get-version', (event) => {
    assertTrustedSender(event);
    return app.getVersion();
  });

  // 系统通知：点击后唤起主窗口，并把目标路由回传渲染端执行 router.push
  ipcMain.handle('desktop:notify', (event, payload: NotifyPayload) => {
    assertTrustedSender(event);
    if (!Notification.isSupported()) return false;
    const notification = new Notification({
      title: payload.title,
      body: payload.body,
    });
    notification.on('click', () => {
      showMainWindow();
      if (payload.route) {
        getMainWindow()?.webContents.send('desktop:navigate', payload.route);
      }
    });
    notification.show();
    return true;
  });

  // 未读角标（mac Dock 数字 / Windows 任务栏覆盖图标，图由 preload canvas 绘制）
  ipcMain.handle('desktop:set-badge', (event, payload: { count: number; image?: string }) => {
    assertTrustedSender(event);
    applyBadge(payload.count, payload.image);
  });

  // 任务栏闪烁提醒：仅窗口未聚焦时触发（聚焦状态下闪烁是干扰），聚焦后由窗口 focus 事件自动清除
  ipcMain.handle('desktop:flash-frame', (event) => {
    assertTrustedSender(event);
    const win = getMainWindow();
    if (win && !win.isFocused()) win.flashFrame(true);
  });

  // 开机自启读取/设置（设置后同步刷新托盘菜单勾选态）
  ipcMain.handle('desktop:get-auto-launch', (event) => {
    assertTrustedSender(event);
    return getAutoLaunchEnabled();
  });
  ipcMain.handle('desktop:set-auto-launch', (event, enable: boolean) => {
    assertTrustedSender(event);
    const result = setAutoLaunchEnabled(enable);
    refreshTrayMenu();
    return result;
  });

  // 打印机列表（渲染端打印设置下拉用）
  ipcMain.handle('desktop:get-printers', async (event) => {
    assertTrustedSender(event);
    const win = getMainWindow();
    if (!win) return [];
    return await win.webContents.getPrintersAsync();
  });

  // 静默打印：渲染端拼好完整 HTML 传入，主进程隐藏窗口出纸
  ipcMain.handle('desktop:print-html', (event, options: PrintHtmlOptions) => {
    assertTrustedSender(event);
    return printHtml(options);
  });

  // 桌面端设置（打印机选择、静默开关等）读取/增量更新
  ipcMain.handle('desktop:get-settings', (event) => {
    assertTrustedSender(event);
    return getSettings();
  });
  ipcMain.handle('desktop:set-settings', (event, patch: Partial<DesktopSettings>) => {
    assertTrustedSender(event);
    return updateSettings(patch);
  });

  // 手动检查更新（渲染端设置页/关于入口）
  ipcMain.handle('desktop:check-update', (event) => {
    assertTrustedSender(event);
    checkForUpdates(true);
  });

  // 渲染端主动唤起主窗口（如页内提醒的「查看」动作）
  ipcMain.handle('desktop:focus-window', (event) => {
    assertTrustedSender(event);
    showMainWindow();
  });
}
