import { BrowserWindow, Menu, screen } from "electron";
import path from "node:path";

export interface AppWindowManagerOptions {
  preloadPath: string;
  rendererUrl?: string;
  rendererFilePath: string;
  onMainReadyToShow?: () => void | Promise<void>;
}

export interface AppWindowManager {
  createMainWindow: () => void;
  focusMainWindow: () => { ok: boolean };
  hasMainWindow: () => boolean;
  getMainWindow: () => BrowserWindow | null;
  sendScannerCommand: (command: unknown) => void;
  createOverlayWindow: () => void;
  hideOverlayWindow: () => { ok: boolean };
}

export function createAppWindowManager({
  preloadPath,
  rendererUrl,
  rendererFilePath,
  onMainReadyToShow,
}: AppWindowManagerOptions): AppWindowManager {
  let mainWindow: BrowserWindow | null = null;
  let overlayWindow: BrowserWindow | null = null;

  function createMainWindow() {
    Menu.setApplicationMenu(null);

    mainWindow = new BrowserWindow({
      width: 1320,
      height: 860,
      minWidth: 1120,
      minHeight: 720,
      backgroundColor: "#090711",
      title: "Genshin Artifact Assistant",
      show: false,
      autoHideMenuBar: true,
      webPreferences: {
        preload: preloadPath,
        contextIsolation: true,
        nodeIntegration: false,
      },
    });

    mainWindow.setMenuBarVisibility(false);
    mainWindow.on("closed", () => {
      mainWindow = null;
    });
    mainWindow.once("ready-to-show", () => {
      void onMainReadyToShow?.();
      focusMainWindow();
    });
    mainWindow.webContents.once("did-finish-load", () => {
      setTimeout(() => focusMainWindow(), 350);
    });

    if (rendererUrl) {
      mainWindow.loadURL(rendererUrl);
    } else {
      mainWindow.loadFile(rendererFilePath);
    }
  }

  function focusMainWindow() {
    if (!mainWindow || mainWindow.isDestroyed()) return { ok: false };

    if (mainWindow.isMinimized()) mainWindow.restore();
    mainWindow.show();
    // Genshin often keeps foreground focus after a scan click. Toggling
    // always-on-top for one tick nudges Windows to surface the dashboard again
    // without leaving it pinned above other apps.
    mainWindow.setAlwaysOnTop(true, "screen-saver");
    mainWindow.focus();
    setTimeout(() => {
      if (!mainWindow || mainWindow.isDestroyed()) return;
      mainWindow.setAlwaysOnTop(false);
      mainWindow.focus();
    }, 250);
    return { ok: true };
  }

  function sendScannerCommand(command: unknown) {
    if (!mainWindow || mainWindow.isDestroyed()) return;
    mainWindow.webContents.send("scanner:command", command);
  }

  function createOverlayWindow() {
    if (overlayWindow) {
      overlayWindow.show();
      return;
    }

    const display = screen.getPrimaryDisplay();
    overlayWindow = new BrowserWindow({
      x: display.workArea.x,
      y: display.workArea.y,
      width: display.workArea.width,
      height: display.workArea.height,
      transparent: true,
      frame: false,
      alwaysOnTop: true,
      skipTaskbar: true,
      resizable: false,
      focusable: false,
      webPreferences: {
        preload: preloadPath,
        contextIsolation: true,
        nodeIntegration: false,
      },
    });

    overlayWindow.setIgnoreMouseEvents(true, { forward: true });

    if (rendererUrl) {
      overlayWindow.loadURL(`${rendererUrl}?overlay=1`);
    } else {
      overlayWindow.loadFile(rendererFilePath, {
        query: { overlay: "1" },
      });
    }

    overlayWindow.on("closed", () => {
      overlayWindow = null;
    });
  }

  function hideOverlayWindow() {
    overlayWindow?.close();
    return { ok: true };
  }

  return {
    createMainWindow,
    focusMainWindow,
    hasMainWindow: () => Boolean(mainWindow && !mainWindow.isDestroyed()),
    getMainWindow: () => mainWindow,
    sendScannerCommand,
    createOverlayWindow,
    hideOverlayWindow,
  };
}
