import log4js from "log4js";
import { BrowserWindow, Updater } from "electrobun/bun";
import { loadConfig } from "../config.js";
import { startWaiting, stopWaiting } from "../spinner.js";
import { createAppRpc, registerMainWindow } from "./rpc.js";

const config = loadConfig();
const logger = log4js.getLogger("Desktop");
logger.level = config.logLevel;

const DEV_SERVER_PORT = 5287;
const DEV_SERVER_URL = `http://localhost:${DEV_SERVER_PORT}`;

export async function getMainViewUrl() {
  const channel = await Updater.localInfo.channel();
  if (channel === "dev" || process.env.NODE_ENV === "development") {
    try {
      await fetch(DEV_SERVER_URL, { method: "HEAD" });
      logger.info(`Using Vite dev server at ${DEV_SERVER_URL}`);
      return DEV_SERVER_URL;
    } catch {
      logger.warn(
        "Vite dev server not running. Start it with `bun run dev:renderer`.",
      );
    }
  }

  return "views://mainview/index.html";
}

export async function createDesktopWindow() {
  const url = await getMainViewUrl();
  const rpc = createAppRpc();

  startWaiting("Creating desktop window...", logger);
  logger.info(`Loading main view: ${url}`);

  const mainWindow = new BrowserWindow({
    title: "Farm Control Server",
    url,
    rpc,
    titleBarStyle: "hiddenInset",
    trafficLightOffset: { x: 14, y: 12 },
    frame: {
      width: 900,
      height: 600,
      x: 100,
      y: 100,
    },
  });

  registerMainWindow(mainWindow);
  mainWindow.show();

  return new Promise((resolve) => {
    let settled = false;

    const finish = async (reason) => {
      if (settled) {
        return;
      }
      settled = true;
      clearTimeout(timeout);
      logger.info(`Desktop window ready (${reason})`);
      await stopWaiting();
      resolve(mainWindow);
    };

    const timeout = setTimeout(() => {
      logger.warn(
        "Desktop window dom-ready timed out after 15s; continuing startup",
      );
      finish("timeout");
    }, 15000);

    mainWindow.webview.on("dom-ready", () => finish("dom-ready"));
    mainWindow.webview.on("did-navigate", () => finish("did-navigate"));
    mainWindow.webview.on("did-commit-navigation", () =>
      finish("did-commit-navigation"),
    );
  });
}
