import { app, dialog, shell } from 'electron';
import log from 'electron-log/main';
import { autoUpdater } from 'electron-updater';

import { DOWNLOAD_PAGE_URL } from './config';
import { getMainWindow, markQuitting, showMainWindow } from './window';

/**
 * 自动更新（electron-updater + generic 静态托管）
 * - 启动 10 秒后自动检查一次 + 每 4 小时轮询 + 托盘/渲染端手动触发
 * - autoDownload：发现新版本自动后台下载，进度事件转发渲染端展示
 * - 下载完成弹窗询问「立即重启安装 / 退出时自动安装」
 * - mac 未签名包 electron-updater 签名校验会报错：捕获后降级为「打开下载页手动安装」
 */

/** 手动检查标记：手动触发时才提示「已是最新版本」，自动轮询保持安静 */
let isManualCheck = false;
/** 检查中防重入 */
let isChecking = false;

/** 把更新事件转发给渲染端（web 侧在 basic.vue 里做轻量提示） */
function sendToRenderer(type: string, data?: unknown): void {
  getMainWindow()?.webContents.send('desktop:update-event', { type, data });
}

/** 判断是否 mac 未签名导致的更新失败（这类错误重试无意义，直接引导手动下载） */
function isMacSignatureError(message: string): boolean {
  return (
    process.platform === 'darwin' &&
    /code signature|not signed|codesign|could not get code signature/i.test(message)
  );
}

/**
 * 初始化自动更新：仅打包后生效（开发模式没有 app-update.yml，检查必然失败）
 */
export function initUpdater(): void {
  if (!app.isPackaged) return;

  autoUpdater.logger = log;
  autoUpdater.autoDownload = true;
  autoUpdater.autoInstallOnAppQuit = true;

  autoUpdater.on('update-available', (info) => {
    log.info(`发现新版本: ${info.version}`);
    sendToRenderer('available', { version: info.version });
  });

  autoUpdater.on('update-not-available', () => {
    sendToRenderer('not-available');
    if (isManualCheck) {
      dialog.showMessageBox({
        type: 'info',
        title: '检查更新',
        message: `当前已是最新版本（v${app.getVersion()}）`,
      });
    }
    isManualCheck = false;
  });

  autoUpdater.on('download-progress', (progress) => {
    sendToRenderer('progress', { percent: Math.round(progress.percent) });
  });

  autoUpdater.on('update-downloaded', async (info) => {
    sendToRenderer('downloaded', { version: info.version });
    // 唤起窗口再弹对话框，避免用户看不到安装确认
    showMainWindow();
    const { response } = await dialog.showMessageBox({
      type: 'question',
      title: '发现新版本',
      message: `新版本 v${info.version} 已下载完成`,
      detail: '立即重启安装，或在退出应用时自动安装。',
      buttons: ['立即重启安装', '退出时自动安装'],
      defaultId: 0,
      cancelId: 1,
    });
    if (response === 0) {
      // 放行窗口 close 拦截，否则 quitAndInstall 会被「关闭进托盘」逻辑挡住
      markQuitting();
      autoUpdater.quitAndInstall();
    }
  });

  autoUpdater.on('error', async (error) => {
    const message = error?.message ?? String(error);
    log.error('自动更新失败', message);
    sendToRenderer('error', { message });
    // mac 未签名：自动更新走不通，引导用户手动下载安装
    if (isMacSignatureError(message)) {
      const { response } = await dialog.showMessageBox({
        type: 'info',
        title: '检查更新',
        message: '当前安装包不支持自动更新',
        detail: '请前往下载页获取最新版本手动安装。',
        buttons: ['打开下载页', '取消'],
        defaultId: 0,
        cancelId: 1,
      });
      if (response === 0) shell.openExternal(DOWNLOAD_PAGE_URL);
    } else if (isManualCheck) {
      dialog.showMessageBox({
        type: 'warning',
        title: '检查更新',
        message: '检查更新失败，请稍后重试',
        detail: message,
      });
    }
    isManualCheck = false;
    isChecking = false;
  });

  // 启动延时自动检查一次 + 每 4 小时轮询（内部工具常开着，轮询保证及时收到发版）
  setTimeout(() => checkForUpdates(false), 10_000);
  setInterval(() => checkForUpdates(false), 4 * 60 * 60 * 1000);
}

/**
 * 触发一次更新检查
 * @param manual 是否手动触发（手动时「已是最新/失败」都会弹窗反馈，自动轮询保持安静）
 */
export async function checkForUpdates(manual: boolean): Promise<void> {
  if (!app.isPackaged) {
    if (manual) {
      dialog.showMessageBox({ type: 'info', title: '检查更新', message: '开发模式不支持检查更新' });
    }
    return;
  }
  if (isChecking) return;
  isChecking = true;
  isManualCheck = manual;
  try {
    await autoUpdater.checkForUpdates();
  } catch {
    // 错误已在 error 事件里统一处理
  } finally {
    isChecking = false;
  }
}
