// Cmd-K palette, fleet-wide search + quick actions.
// Hotkey: ⌘K / Ctrl+K. Esc to dismiss.
const { useState: useStateK, useEffect: useEffectK, useMemo: useMemoK, useRef: useRefK } = React;

function CmdKPalette({ open, onClose, onNav, onOpenApp, role }) {
  const [q, setQ] = useStateK("");
  const [cursor, setCursor] = useStateK(0);
  const inputRef = useRefK(null);

  // Reset state on each open.
  useEffectK(() => {
    if (open) {
      setQ("");
      setCursor(0);
      // focus input next tick so animation doesn't fight it
      setTimeout(() => inputRef.current?.focus(), 30);
    }
  }, [open]);

  // Build the searchable index. Memoize so we don't rebuild on every keystroke.
  const index = useMemoK(() => {
    const items = [];

    // Pages, role-aware
    const pages = role === "cto"
      ? [
          { id: "overview", label: "Overview", desc: "Worry queue, signals, recommendations" },
          { id: "fleet", label: "Fleet", desc: "All 24 apps across the org" },
          { id: "connections", label: "Connections", desc: "Apps ↔ schemas ↔ services" },
          { id: "governance", label: "Governance", desc: "Rules engine + evidence" },
          { id: "recommendations", label: "Recommendations", desc: "Codify knowledge into rules" },
          { id: "costs", label: "Cost attribution", desc: "Per-team P&L" },
          { id: "settings", label: "Settings" },
        ]
      : [
          { id: "overview", label: "My work", desc: "Today's deploys, tests, fixes" },
          { id: "fleet", label: "My apps" },
          { id: "connections", label: "Dependencies" },
          { id: "tests", label: "Tests" },
          { id: "costs", label: "My costs" },
        ];
    pages.forEach(p => items.push({
      kind: "page",
      key: "page:" + p.id,
      label: p.label,
      desc: p.desc,
      icon: "Home",
      action: () => onNav(p.id),
    }));

    // Apps
    DATA.APPS.forEach(a => {
      const o = DATA.OPERATORS[a.owner];
      items.push({
        kind: "app",
        key: "app:" + a.id,
        label: a.name,
        desc: `${o?.name || a.owner} · ${a.team || ""} · ${a.dau || 0} DAU`,
        searchExtra: (a.connections || []).map(c => c.name).join(" "),
        icon: "Fleet",
        action: () => onOpenApp(a),
      });
    });

    // Schemas
    DATA.SCHEMAS.forEach(s => items.push({
      kind: "schema",
      key: "schema:" + s.name,
      label: s.name,
      desc: `${s.kind} · used by ${s.apps.length} app${s.apps.length === 1 ? "" : "s"}${s.contract === "none" ? " · no contract" : s.contract === "partial" ? " · partial contract" : " · typed"}`,
      searchExtra: s.apps.join(" "),
      icon: "Database",
      action: () => onNav("connections"),
    }));

    // Services
    (DATA.SERVICES || []).forEach(s => items.push({
      kind: "service",
      key: "service:" + s.name,
      label: s.name,
      desc: `${s.kind} · ${s.apps.length} app${s.apps.length === 1 ? "" : "s"}${s.sharedKey ? " · shared key (unattributed)" : ""}`,
      searchExtra: s.apps.join(" ") + " " + (s.sharedKey || ""),
      icon: s.kind === "LLM" ? "Spark" : "Cloud",
      action: () => onNav("connections"),
    }));

    // Rules
    (DATA.RULES || []).forEach(r => {
      const cat = (DATA.RULE_CATEGORIES || []).find(c => c.id === r.category);
      items.push({
        kind: "rule",
        key: "rule:" + r.id,
        label: r.name,
        desc: `${cat?.label || r.category} · ${r.builtInTests} tests${r.violations > 0 ? ` · ${r.violations} violations` : ""}`,
        icon: "Shield",
        action: () => onNav("governance"),
      });
    });

    // Quick actions
    const actions = [
      { label: "Switch to CTO view",      icon: "Spark", action: () => onNav("__role:cto") },
      { label: "Switch to Operator view", icon: "Spark", action: () => onNav("__role:operator") },
      { label: "Export evidence pack",    icon: "Upload", action: () => onNav("governance"), desc: "Signed audit bundle" },
      { label: "Rotate shared keys",      icon: "Key",    action: () => onNav("settings") },
    ];
    actions.forEach(a => items.push({ kind: "action", key: "action:" + a.label, ...a }));

    return items;
  }, [role, onNav, onOpenApp]);

  // Filter + group
  const filtered = useMemoK(() => {
    const query = q.trim().toLowerCase();
    if (!query) return index;
    const tokens = query.split(/\s+/);
    return index.filter(it => {
      const hay = (it.label + " " + (it.desc || "") + " " + (it.searchExtra || "")).toLowerCase();
      return tokens.every(t => hay.includes(t));
    });
  }, [q, index]);

  const grouped = useMemoK(() => {
    const order = ["page", "app", "schema", "service", "rule", "action"];
    const labels = {
      page: "Pages",
      app: "Apps",
      schema: "Schemas",
      service: "Services",
      rule: "Rules",
      action: "Actions",
    };
    const buckets = {};
    filtered.forEach(it => {
      buckets[it.kind] = buckets[it.kind] || [];
      buckets[it.kind].push(it);
    });
    return order.filter(k => buckets[k]?.length).map(k => ({ key: k, label: labels[k], items: buckets[k] }));
  }, [filtered]);

  // Flat list for cursor navigation
  const flat = useMemoK(() => grouped.flatMap(g => g.items), [grouped]);

  useEffectK(() => { setCursor(0); }, [q]);

  // Keyboard
  useEffectK(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === "Escape") { e.preventDefault(); onClose(); return; }
      if (e.key === "ArrowDown") { e.preventDefault(); setCursor(c => Math.min(c + 1, flat.length - 1)); return; }
      if (e.key === "ArrowUp")   { e.preventDefault(); setCursor(c => Math.max(c - 1, 0)); return; }
      if (e.key === "Enter") {
        e.preventDefault();
        const it = flat[cursor];
        if (it) { it.action(); onClose(); }
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, flat, cursor, onClose]);

  if (!open) return null;

  return (
    <div className="cmdk-scrim" onMouseDown={onClose}>
      <div className="cmdk" onMouseDown={(e) => e.stopPropagation()}>
        <div className="cmdk-input-wrap">
          <Icons.Search s={16}/>
          <input
            ref={inputRef}
            className="cmdk-input"
            placeholder="Search apps, schemas, services, rules…"
            value={q}
            onChange={(e) => setQ(e.target.value)}
          />
          <span className="cmdk-item-kbd">esc</span>
        </div>
        <div className="cmdk-results">
          {flat.length === 0 ? (
            <div className="cmdk-empty">No matches for "{q}"</div>
          ) : grouped.map(g => (
            <div key={g.key}>
              <div className="cmdk-section">{g.label}</div>
              {g.items.map(it => {
                const idx = flat.indexOf(it);
                const Ic = Icons[it.icon] || Icons.Spark;
                return (
                  <div
                    key={it.key}
                    className={"cmdk-item" + (idx === cursor ? " on" : "")}
                    onMouseEnter={() => setCursor(idx)}
                    onClick={() => { it.action(); onClose(); }}
                  >
                    <span className="cmdk-item-icon"><Ic s={13}/></span>
                    <div className="cmdk-item-body">
                      <span className="cmdk-item-title">{it.label}</span>
                      {it.desc && <span className="cmdk-item-sub">{it.desc}</span>}
                    </div>
                    {idx === cursor && <span className="cmdk-item-kbd">↵</span>}
                  </div>
                );
              })}
            </div>
          ))}
        </div>
        <div className="cmdk-foot">
          <span>{flat.length} result{flat.length === 1 ? "" : "s"}</span>
          <span className="keys">
            <span><span className="cmdk-item-kbd">↑↓</span> navigate</span>
            <span><span className="cmdk-item-kbd">↵</span> select</span>
            <span><span className="cmdk-item-kbd">esc</span> close</span>
          </span>
        </div>
      </div>
    </div>
  );
}

window.CmdKPalette = CmdKPalette;
