import { autoUpdater } from "electron-updater";
import { ipcMain, BrowserWindow } from "electron";

let updateAvailable = false;
let updateDownloaded = false;

export function setupUpdater(appName: string): void {
  autoUpdater.autoDownload = false;
  autoUpdater.autoInstallOnAppQuit = true;
  autoUpdater.logger = {
    info: (msg) => console.log("[updater]", msg),
    warn: (msg) => console.warn("[updater]", msg),
    error: (msg) => console.error("[updater]", msg),
    debug: (msg) => console.debug("[updater]", msg),
  };

  autoUpdater.on("checking-for-update", () => {
    console.log("[updater] Checking for updates...");
  });

  autoUpdater.on("update-available", (info) => {
    updateAvailable = true;
    console.log("[updater] Update available:", info.version);
    broadcast("updater:available", info);
  });

  autoUpdater.on("update-not-available", (info) => {
    console.log("[updater] Up to date:", info.version);
  });

  autoUpdater.on("download-progress", (progress) => {
    broadcast("updater:progress", {
      percent: progress.percent,
      bytesPerSecond: progress.bytesPerSecond,
      transferred: progress.transferred,
      total: progress.total,
    });
  });

  autoUpdater.on("update-downloaded", (info) => {
    updateDownloaded = true;
    console.log("[updater] Update downloaded:", info.version);
    broadcast("updater:downloaded", info);
  });

  autoUpdater.on("error", (err) => {
    console.error("[updater] Error:", err.message);
    broadcast("updater:error", err.message);
  });

  ipcMain.handle("updater:check", async () => {
    try {
      const result = await autoUpdater.checkForUpdates();
      return result?.updateInfo ?? null;
    } catch (err) {
      console.error("[updater] Check failed:", err);
      return null;
    }
  });

  ipcMain.handle("updater:download", async () => {
    if (!updateAvailable) return;
    try {
      await autoUpdater.downloadUpdate();
    } catch (err) {
      console.error("[updater] Download failed:", err);
    }
  });

  ipcMain.on("updater:quitAndInstall", () => {
    if (updateDownloaded) {
      autoUpdater.quitAndInstall(false, true);
    }
  });

  setTimeout(() => {
    autoUpdater.checkForUpdates().catch(() => {});
  }, 10_000);
}

function broadcast(channel: string, data: unknown): void {
  for (const win of BrowserWindow.getAllWindows()) {
    if (!win.isDestroyed()) {
      win.webContents.send(channel, data);
    }
  }
}
