/* ========================================================================
   LUMINA — Quick Launcher (Cmd/Ctrl+K command palette)
   Search and trigger any visualizer, FX, behavior, board, scene, action.
   ======================================================================== */
(function () {
  const { useState, useEffect, useRef } = React;

  function QuickLauncher() {
    const [open, setOpen] = useState(false);
    const [query, setQuery] = useState("");
    const [sel, setSel] = useState(0);
    const inputRef = useRef(null);

    useEffect(() => {
      const onKey = (e) => {
        if ((e.metaKey || e.ctrlKey) && e.key === "k") {
          e.preventDefault();
          setOpen(o => !o);
          setQuery("");
          setSel(0);
        } else if (e.key === "Escape" && open) {
          setOpen(false);
        }
      };
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }, [open]);

    useEffect(() => {
      if (open && inputRef.current) inputRef.current.focus();
    }, [open]);

    if (!open) return (
      <button
        onClick={() => { setOpen(true); setQuery(""); }}
        style={{
          position: "fixed", bottom: 230, left: 18, zIndex: 591,
          padding: "8px 14px", border: "none", borderRadius: 8,
          background: "linear-gradient(180deg, var(--panel-hi), var(--panel))",
          color: "var(--led-cyan)",
          fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 10,
          letterSpacing: "0.16em", textTransform: "uppercase",
          cursor: "pointer", boxShadow: "var(--nshadow-out-sm)",
          display: "flex", alignItems: "center", gap: 6,
        }}>
        ⌘K Search
      </button>
    );

    /* Build action list */
    const actions = [];
    (window.VISUALIZERS || []).forEach(v => actions.push({
      kind: "Viz", label: v.name, tag: v.tag, color: "#ffae3a",
      run: () => window.__setVizId?.(v.id),
    }));
    Object.entries(window.FXTypes || {}).forEach(([k, t]) => actions.push({
      kind: "FX", label: t.label, tag: "+ to chain", color: "#4be6ff",
      run: () => window.Prog?.addFX(k),
    }));
    Object.entries(window.BehaviorTypes || {}).forEach(([k, t]) => actions.push({
      kind: "Behave", label: t.label, tag: "+ modulator", color: t.color,
      run: () => window.Prog?.addBehavior(k),
    }));
    [["Stage","stage"],["Live Loops","composition"],["Slideshow","slideshow"],
     ["3D Scene","scene3d"],["Boards","text"],["Output Map","mapping"],
     ["Nodes","nodes"],["Generative","generative"]].forEach(([n, id]) => actions.push({
      kind: "Go", label: "Go to " + n, tag: id, color: "#ff5ad6",
      run: () => window.__setWorkspace?.(id),
    }));
    Object.entries(window.SoundLab?.clips || {}).forEach(([k, c]) => actions.push({
      kind: "Sound", label: "▶ " + c.label, tag: k, color: c.color,
      run: () => window.SoundLab.play(k),
    }));
    Object.entries(window.Stingers?.list || {}).forEach(([k, s]) => actions.push({
      kind: "FX-Burst", label: s.icon + " " + s.label, tag: "stinger", color: s.color,
      run: () => window.Stingers.fire(k),
    }));
    actions.push(
      { kind: "Action", label: "■ STOP all audio", color: "#ff3b3b",
        run: () => window.AudioEngine?.stop() },
      { kind: "Action", label: "▶ Demo synth", color: "#7cff4f",
        run: () => window.AudioEngine?.useDemo() },
      { kind: "Action", label: "● Toggle Strobo", color: "#ffae3a",
        run: () => window.Strobo && (window.Strobo.enabled = !window.Strobo.enabled) },
      { kind: "Action", label: "✕ Disable all FX", color: "#ff3b3b",
        run: () => { if (window.Prog) { window.Prog.fxChain.forEach(f => f.enabled = false); window.Prog.emit(); } } },
      { kind: "Action", label: "🗀 Save project", color: "#4be6ff",
        run: () => window.LuminaProject?.save() },
      { kind: "Action", label: "📂 Load project", color: "#4be6ff",
        run: () => window.LuminaProject?.load() },
    );

    const q = query.toLowerCase().trim();
    const filtered = !q ? actions.slice(0, 60) : actions.filter(a =>
      a.label.toLowerCase().includes(q) ||
      a.kind.toLowerCase().includes(q) ||
      (a.tag || "").toLowerCase().includes(q)
    ).slice(0, 80);

    const choose = (a) => {
      a.run();
      setOpen(false);
    };

    return (
      <div onClick={() => setOpen(false)} style={{
        position: "fixed", inset: 0, zIndex: 700,
        background: "rgba(0,0,0,0.6)", backdropFilter: "blur(4px)",
        display: "grid", placeItems: "start center", paddingTop: "12vh",
      }}>
        <div onClick={e => e.stopPropagation()} style={{
          width: "min(640px, 92vw)",
          background: "linear-gradient(180deg, var(--panel-hi), var(--panel-lo))",
          borderRadius: 12,
          boxShadow: "0 30px 80px rgba(0,0,0,0.8), 0 0 0 1px rgba(75,230,255,0.3), 0 0 24px rgba(75,230,255,0.2)",
          overflow: "hidden",
        }}>
          <div style={{
            padding: "14px 18px",
            borderBottom: "1px solid rgba(255,255,255,0.06)",
            display: "flex", alignItems: "center", gap: 12,
          }}>
            <span style={{ fontSize: 18, color: "var(--led-cyan)" }}>⌘K</span>
            <input ref={inputRef} value={query}
              onChange={e => { setQuery(e.target.value); setSel(0); }}
              onKeyDown={(e) => {
                if (e.key === "ArrowDown") { setSel(s => Math.min(filtered.length - 1, s + 1)); e.preventDefault(); }
                else if (e.key === "ArrowUp") { setSel(s => Math.max(0, s - 1)); e.preventDefault(); }
                else if (e.key === "Enter" && filtered[sel]) { choose(filtered[sel]); }
              }}
              placeholder="Type a visualizer, FX, behavior, action, or board..."
              style={{
                flex: 1, padding: "8px 0", background: "transparent", border: "none", outline: "none",
                color: "var(--ink)", fontFamily: "var(--font-display)", fontSize: 16, fontWeight: 600,
                letterSpacing: "0.02em",
              }} />
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 9, color: "var(--ink-faint)",
              padding: "3px 6px", border: "1px solid rgba(255,255,255,0.1)", borderRadius: 3 }}>ESC</span>
          </div>
          <div style={{ maxHeight: "60vh", overflowY: "auto", padding: 6 }}>
            {filtered.length === 0 && (
              <div style={{ padding: 24, textAlign: "center", color: "var(--ink-faint)", fontSize: 12 }}>
                No matches for "{query}"
              </div>
            )}
            {filtered.map((a, i) => (
              <div key={i}
                onClick={() => choose(a)}
                onMouseEnter={() => setSel(i)}
                style={{
                  display: "grid", gridTemplateColumns: "auto 60px 1fr auto", gap: 10,
                  alignItems: "center", padding: "8px 12px",
                  borderRadius: 6, cursor: "pointer",
                  background: i === sel ? `linear-gradient(90deg, ${a.color}33, transparent)` : "transparent",
                  borderLeft: i === sel ? `3px solid ${a.color}` : "3px solid transparent",
                }}>
                <span style={{ width: 6, height: 6, borderRadius: "50%",
                  background: a.color, boxShadow: `0 0 6px ${a.color}` }} />
                <span style={{
                  fontFamily: "var(--font-mono)", fontSize: 9,
                  color: "var(--ink-faint)", textTransform: "uppercase", letterSpacing: "0.12em",
                }}>{a.kind}</span>
                <span style={{
                  fontFamily: "var(--font-display)", fontSize: 12, fontWeight: 600,
                  color: i === sel ? "var(--ink)" : "var(--ink-dim)",
                }}>{a.label}</span>
                {a.tag && (
                  <span style={{
                    fontFamily: "var(--font-mono)", fontSize: 9, color: "var(--ink-faint)",
                  }}>{a.tag}</span>
                )}
              </div>
            ))}
          </div>
          <div style={{
            padding: "8px 14px", borderTop: "1px solid rgba(255,255,255,0.06)",
            display: "flex", justifyContent: "space-between",
            fontFamily: "var(--font-mono)", fontSize: 9, color: "var(--ink-faint)",
            background: "linear-gradient(180deg, var(--panel-lo), #0a0a0c)",
          }}>
            <span>↑↓ navigate · ↵ select · ESC close</span>
            <span>{filtered.length} of {actions.length}</span>
          </div>
        </div>
      </div>
    );
  }

  function mount() {
    if (!window.React || !window.ReactDOM) { setTimeout(mount, 100); return; }
    let host = document.getElementById("__quick_launcher");
    if (!host) { host = document.createElement("div"); host.id = "__quick_launcher"; document.body.appendChild(host); }
    ReactDOM.createRoot(host).render(<QuickLauncher />);
  }
  if (document.readyState === "complete" || document.readyState === "interactive") setTimeout(mount, 1100);
  else document.addEventListener("DOMContentLoaded", () => setTimeout(mount, 1100));
})();
