// ==== Command palette (Cmd+K) =======================================
// Quick search across sections, projects, papers, talks, awards, skills,
// plus actions: open chat, open terminal, racer, contact.

function makeCommandIndex() {
  const items = [];
  // Sections
  const SECTIONS = [
    ["hero",        "Go to: Intro",            "section", "01"],
    ["about",       "Go to: About",            "section", "02"],
    ["graph",       "Go to: The Atlas",        "section", "03"],
    ["projects",    "Go to: Selected Work",    "section", "04"],
    ["mantis",      "Go to: MANTIS case study", "section", "05"],
    ["trifecta",    "Go to: Lethal Trifecta",  "section", "06"],
    ["mcp",         "Go to: MCP Gateway",      "section", "07"],
    ["soc",         "Go to: Live SOC",         "section", "08"],
    ["owasp",       "Go to: Threat Model",     "section", "09"],
    ["timeline",    "Go to: Timeline",         "section", "10"],
    ["research",    "Go to: Research",         "section", "11"],
    ["recognition", "Go to: Talks & Awards",   "section", "12"],
    ["skills",      "Go to: Stack",            "section", "13"],
    ["writing",     "Go to: Writing",          "section", "14"],
    ["now",         "Go to: Now",              "section", "15"],
    ["contact",     "Go to: Contact",          "section", "16"],
  ];
  SECTIONS.forEach(([id, label, kind, n]) => items.push({ id: `s:${id}`, label, kind, hint: n, action: () => scrollToId(id) }));

  // Projects
  AYUSH.PROJECTS.forEach(p => items.push({
    id: `p:${p.id}`, label: p.name + " · " + p.sub, kind: "project", hint: p.year,
    action: () => { if (p.id === "mantis") scrollToId("mantis"); else if (p.link) window.open(p.link, "_blank"); else scrollToId("projects"); }
  }));

  // Papers
  AYUSH.PAPERS.forEach((p, i) => items.push({
    id: `pa:${i}`, label: p.title, kind: "paper", hint: p.yr,
    action: () => { if (p.link) window.open(p.link, "_blank"); else scrollToId("research"); }
  }));

  // Talks
  AYUSH.TALKS.forEach((t, i) => items.push({
    id: `tk:${i}`, label: t.title + " · " + t.venue, kind: "talk", hint: t.yr,
    action: () => scrollToId("recognition")
  }));

  // Awards
  AYUSH.AWARDS.forEach((a, i) => items.push({
    id: `aw:${i}`, label: a.name + " · " + a.org, kind: "award", hint: a.yr,
    action: () => scrollToId("recognition")
  }));

  // Skill groups
  AYUSH.SKILLS.forEach((s, i) => items.push({
    id: `sg:${i}`, label: "Stack · " + s.group, kind: "skill", hint: `${s.items.length}`,
    action: () => scrollToId("skills")
  }));

  // Actions
  items.push({ id: "a:term", label: "Open terminal", kind: "action", hint: "~",
    action: () => window.dispatchEvent(new CustomEvent("ayush:open-terminal")) });
  items.push({ id: "a:chat", label: "Ask the agent", kind: "action", hint: "AI",
    action: () => window.dispatchEvent(new CustomEvent("ayush:open-chat")) });
  items.push({ id: "a:racer", label: "Launch DeepRacer", kind: "action", hint: "🏁",
    action: () => window.dispatchEvent(new CustomEvent("ayush:open-racer")) });
  items.push({ id: "a:email", label: "Email Ayush", kind: "action", hint: "→",
    action: () => { window.location.href = "mailto:" + AYUSH.PROFILE.email; } });
  items.push({ id: "a:github", label: "Open GitHub", kind: "action", hint: "↗",
    action: () => window.open(AYUSH.PROFILE.links.github, "_blank") });
  items.push({ id: "a:linkedin", label: "Open LinkedIn", kind: "action", hint: "↗",
    action: () => window.open(AYUSH.PROFILE.links.linkedin, "_blank") });

  return items;
}

function CommandPalette({ onClose }) {
  const items = useMemo(makeCommandIndex, []);
  const [q, setQ] = useState("");
  const [idx, setIdx] = useState(0);
  const inputRef = useRef(null);

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

  const filtered = useMemo(() => {
    const s = q.trim().toLowerCase();
    if (!s) return items.slice(0, 24);
    return items
      .map(it => ({ it, score: scoreMatch(it.label.toLowerCase() + " " + it.kind, s) }))
      .filter(x => x.score > -Infinity)
      .sort((a, b) => b.score - a.score)
      .slice(0, 30)
      .map(x => x.it);
  }, [q, items]);

  useEffect(() => { setIdx(0); }, [q]);

  function runItem(it) {
    onClose && onClose();
    setTimeout(() => it.action && it.action(), 60);
  }

  function onKey(e) {
    if (e.key === "Escape") { onClose && onClose(); }
    else if (e.key === "ArrowDown") { setIdx(i => Math.min(filtered.length - 1, i + 1)); e.preventDefault(); }
    else if (e.key === "ArrowUp")   { setIdx(i => Math.max(0, i - 1)); e.preventDefault(); }
    else if (e.key === "Enter")     { const it = filtered[idx]; if (it) runItem(it); e.preventDefault(); }
  }

  return (
    <div className="cmdk-backdrop" onClick={onClose}>
      <div className="cmdk" role="dialog" aria-label="command palette" onClick={e => e.stopPropagation()}>
        <div className="cmdk-input">
          <span className="prefix">›</span>
          <input ref={inputRef} value={q} onChange={e => setQ(e.target.value)} onKeyDown={onKey}
                 placeholder="search anything — projects, papers, sections, awards…" />
          <span className="kbd">esc</span>
        </div>
        <div className="cmdk-results">
          {filtered.length === 0 && <div className="cmdk-empty">no matches</div>}
          {filtered.map((it, i) => (
            <div key={it.id}
              className={"cmdk-row" + (i === idx ? " active" : "")}
              onMouseEnter={() => setIdx(i)}
              onClick={() => runItem(it)}>
              <span className={`cmdk-kind k-${it.kind}`}>{it.kind}</span>
              <span className="cmdk-label">{it.label}</span>
              <span className="cmdk-hint">{it.hint}</span>
            </div>
          ))}
        </div>
        <div className="cmdk-foot">
          <span><span className="kbd">↑↓</span> navigate</span>
          <span><span className="kbd">enter</span> select</span>
          <span><span className="kbd">esc</span> close</span>
        </div>
      </div>
    </div>
  );
}

// Fuzzy-ish score: prefix > substring > char-in-order; -Infinity = no match
function scoreMatch(haystack, needle) {
  if (!needle) return 0;
  if (haystack.startsWith(needle)) return 1000;
  const idx = haystack.indexOf(needle);
  if (idx >= 0) return 500 - idx;
  // chars-in-order
  let hi = 0, ni = 0, found = 0, lastHi = -1, runs = 0;
  while (hi < haystack.length && ni < needle.length) {
    if (haystack[hi] === needle[ni]) {
      if (lastHi !== hi - 1) runs += 1;
      lastHi = hi;
      ni++; found++;
    }
    hi++;
  }
  if (ni < needle.length) return -Infinity;
  return found * 10 - runs * 4;
}

Object.assign(window, { CommandPalette });
