import { NeedleXRSession } from "@needle-tools/engine";
import { findMenuController } from "./findMenuController.js";
import { whenCatalogDishesReady } from "./loadCatalogDishes.js";
import type { MenuController } from "./scripts/MenuController.js";

/**
 * HTML overlay: drives {@link MenuController} prev/next (same GLB as Gitea AR-Menu) — no `src` swap.
 * Requires Unity export with MenuController + dish Object3Ds on the scene GLB.
 */

function whenDomReady(fn: () => void): void {
  if (document.readyState !== "loading") fn();
  else document.addEventListener("DOMContentLoaded", () => fn(), { once: true });
}

function initAssetPicker(): void {
  const needle = document.querySelector("needle-engine");
  const prev = document.querySelector<HTMLButtonElement>("#asset-picker-prev");
  const next = document.querySelector<HTMLButtonElement>("#asset-picker-next");
  const arBtn = document.querySelector<HTMLButtonElement>("#asset-picker-ar");
  const labelEl = document.querySelector("#asset-picker-label");
  const indexEl = document.querySelector("#asset-picker-index");

  if (!needle || !prev || !next || !labelEl || !indexEl) return;

  let menuController: MenuController | null = null;
  let immersiveSessionActive = false;
  let arSupported = false;
  let arStarting = false;

  const syncUi = (): void => {
    if (menuController && menuController.getDishSlotCount() > 0) {
      labelEl.textContent = menuController.getPickerLabel();
      indexEl.textContent = "";
    } else if (menuController) {
      labelEl.textContent = "Menu (assign dishes in Unity)";
      indexEl.textContent = "";
    } else {
      labelEl.textContent = "Menu scene";
      indexEl.textContent = "—";
    }

    const canNav = menuController !== null && menuController.getDishSlotCount() > 1;

    prev.disabled = !canNav;
    next.disabled = !canNav;

    if (arBtn) {
      arBtn.disabled =
        !arSupported ||
        arStarting ||
        immersiveSessionActive;
    }
  };

  const bindMenuController = async (): Promise<void> => {
    try {
      const ctx = await needle.getContext();
      menuController = findMenuController(ctx);
    } catch {
      menuController = null;
    }
    syncUi();
  };

  void NeedleXRSession.isARSupported().then((ok: boolean) => {
    arSupported = ok;
    syncUi();
  });

  const requestNavigate = (delta: number): void => {
    if (!menuController || menuController.getDishSlotCount() <= 1) return;
    if (delta < 0) menuController.selectPreviousDish();
    else menuController.selectNextDish();
    syncUi();
  };

  const startAr = async (): Promise<void> => {
    if (!arSupported || arStarting || immersiveSessionActive) return;
    arStarting = true;
    syncUi();
    try {
      const ctx = await needle.getContext();
      await whenCatalogDishesReady();
      menuController = findMenuController(ctx);
      menuController?.prepareForAR();
      await NeedleXRSession.start("immersive-ar", undefined, ctx);
    } catch (err) {
      console.warn("[assetPicker] Failed to start AR session:", err);
    } finally {
      arStarting = false;
      syncUi();
    }
  };

  prev.addEventListener("click", () => requestNavigate(-1));
  next.addEventListener("click", () => requestNavigate(1));
  arBtn?.addEventListener("click", () => void startAr());

  needle.addEventListener("enter-ar", () => {
    immersiveSessionActive = true;
    syncUi();
  });
  needle.addEventListener("exit-ar", () => {
    immersiveSessionActive = false;
    syncUi();
  });
  needle.addEventListener("enter-vr", () => {
    immersiveSessionActive = true;
    syncUi();
  });
  needle.addEventListener("exit-vr", () => {
    immersiveSessionActive = false;
    syncUi();
  });

  needle.addEventListener("loadfinished", () => void bindMenuController());
  needle.addEventListener("menu-dishes-updated", () => void bindMenuController());

  whenDomReady(() => {
    requestAnimationFrame(() => void bindMenuController());
  });
}

initAssetPicker();
