/**
 * Bluetooth / USB HID numpad shortcuts (browser focus required).
 *
 * Numpad1–9,0     → zone 1–10 (visible zone list order)
 * NumpadEnter     → sequence beat sync (step), same as S
 * NumpadDecimal   → sequence beat sync (pass), same as Shift+S
 * NumpadMultiply  → reset audio detector
 * NumpadAdd       → brightness +16
 * NumpadSubtract  → brightness −16
 * NumpadDivide    → stop zone sequence playback
 */
(() => {
  const BRIGHTNESS_STEP = 16;

  function isTypingTarget(target) {
    if (!target || typeof target !== "object") return false;
    const tag = String(target.tagName || "").toLowerCase();
    return tag === "input" || tag === "textarea" || tag === "select" || target.isContentEditable;
  }

  function zoneIdsInListOrder() {
    return [...document.querySelectorAll("#zones-list .zone-button[data-zone-id]")]
      .map((el) => el.getAttribute("data-zone-id"))
      .filter((id) => id != null && id !== "");
  }

  async function selectZoneByListIndex(oneBased) {
    const order = zoneIdsInListOrder();
    if (oneBased < 1 || oneBased > order.length) return;
    const zoneId = order[oneBased - 1];
    if (window.tabsManager && typeof window.tabsManager.selectZone === "function") {
      await window.tabsManager.selectZone(zoneId);
    } else if (typeof selectZone === "function") {
      await selectZone(zoneId);
    }
  }

  async function syncSequenceBeatPhase(mode) {
    const res = await fetch("/sequences/sync-phase", {
      method: "POST",
      headers: { "Content-Type": "application/json", Accept: "application/json" },
      body: JSON.stringify({ mode: mode || "step" }),
    });
    if (!res.ok) {
      const data = await res.json().catch(() => ({}));
      throw new Error(data.error || `Sync failed (${res.status})`);
    }
  }

  async function resetAudioTracking() {
    const res = await fetch("/api/audio/reset", {
      method: "POST",
      headers: { Accept: "application/json" },
    });
    if (!res.ok) {
      const data = await res.json().catch(() => ({}));
      throw new Error(data.error || `Reset failed (${res.status})`);
    }
  }

  function adjustZoneBrightness(delta) {
    const zoneId =
      (window.tabsManager && typeof window.tabsManager.getCurrentTabId === "function"
        ? window.tabsManager.getCurrentTabId()
        : null) ||
      (window.tabsManager && typeof window.tabsManager.getCurrentZoneId === "function"
        ? window.tabsManager.getCurrentZoneId()
        : null);
    if (!zoneId) return;
    const slider =
      document.getElementById("header-brightness-slider") ||
      document.getElementById("menu-brightness-slider");
    if (!slider) return;
    const cur = parseInt(slider.value, 10);
    const base = Number.isFinite(cur) ? cur : 127;
    const next = Math.max(0, Math.min(255, base + delta));
    if (String(slider.value) === String(next)) return;
    slider.value = String(next);
    slider.dispatchEvent(new Event("input", { bubbles: true }));
  }

  async function stopSequencePlayback() {
    if (typeof window.stopZoneSequencePlayback === "function") {
      await window.stopZoneSequencePlayback(true);
    }
  }

  /** @type {Record<string, () => void | Promise<void>>} */
  const actions = {
    NumpadEnter: () => syncSequenceBeatPhase("step"),
    NumpadDecimal: () => syncSequenceBeatPhase("pass"),
    NumpadMultiply: () => resetAudioTracking(),
    NumpadAdd: () => adjustZoneBrightness(BRIGHTNESS_STEP),
    NumpadSubtract: () => adjustZoneBrightness(-BRIGHTNESS_STEP),
    NumpadDivide: () => stopSequencePlayback(),
    Numpad1: () => selectZoneByListIndex(1),
    Numpad2: () => selectZoneByListIndex(2),
    Numpad3: () => selectZoneByListIndex(3),
    Numpad4: () => selectZoneByListIndex(4),
    Numpad5: () => selectZoneByListIndex(5),
    Numpad6: () => selectZoneByListIndex(6),
    Numpad7: () => selectZoneByListIndex(7),
    Numpad8: () => selectZoneByListIndex(8),
    Numpad9: () => selectZoneByListIndex(9),
    Numpad0: () => selectZoneByListIndex(10),
  };

  document.addEventListener("keydown", (ev) => {
    if (ev.defaultPrevented || ev.repeat || isTypingTarget(ev.target)) return;
    const code = ev.code;
    if (!code || !code.startsWith("Numpad")) return;
    const action = actions[code];
    if (!action) return;
    ev.preventDefault();
    Promise.resolve(action()).catch((e) => console.warn("numpad shortcut failed:", e));
  });
})();
