/**
 * CommandPalette — global Cmd+K (or Ctrl+K) overlay with hybrid_search.
 *
 * Renders directly in <RootLayout>. Type a query, debounced 250ms, hit /api/search/hybrid,
 * arrow-key navigation, Enter opens the chunk anchor on /d/<doc>#cNNNN.
 */
"use client";
import { useCallback, useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";

interface Hit {
  chunk_id: string;
  doc_id: string;
  page: number;
  type: string;
  bbox: { x: number; y: number; w: number; h: number } | null;
  classification: string | null;
  snippet: string;
  score: number;
  href: string;
}

export function CommandPalette() {
  const router = useRouter();
  const [open, setOpen] = useState(false);
  const [q, setQ] = useState("");
  const [loading, setLoading] = useState(false);
  const [hits, setHits] = useState<Hit[]>([]);
  const [sel, setSel] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);

  // Global hotkey
  useEffect(() => {
    function onKey(e: KeyboardEvent) {
      const cmd = e.metaKey || e.ctrlKey;
      if (cmd && e.key.toLowerCase() === "k") {
        e.preventDefault();
        setOpen((o) => !o);
      } else if (e.key === "Escape") {
        setOpen(false);
      }
    }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  // Focus input when opened
  useEffect(() => {
    if (open) setTimeout(() => inputRef.current?.focus(), 30);
    else {
      setQ("");
      setHits([]);
      setSel(0);
    }
  }, [open]);

  // Debounced search
  useEffect(() => {
    if (!open || q.trim().length < 2) {
      setHits([]);
      return;
    }
    const ctl = new AbortController();
    const t = setTimeout(async () => {
      setLoading(true);
      try {
        const res = await fetch(
          `/api/search/hybrid?q=${encodeURIComponent(q)}&lang=pt&top_k=10`,
          { signal: ctl.signal },
        );
        if (!res.ok) {
          setHits([]);
          return;
        }
        const data = (await res.json()) as { hits?: Hit[] };
        setHits(data.hits ?? []);
        setSel(0);
      } catch {
        // aborted or error — keep last hits
      } finally {
        setLoading(false);
      }
    }, 250);
    return () => {
      ctl.abort();
      clearTimeout(t);
    };
  }, [q, open]);

  const go = useCallback(
    (h: Hit) => {
      router.push(h.href);
      setOpen(false);
    },
    [router],
  );

  function onKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setSel((s) => Math.min(hits.length - 1, s + 1));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setSel((s) => Math.max(0, s - 1));
    } else if (e.key === "Enter") {
      e.preventDefault();
      if (hits[sel]) go(hits[sel]);
    }
  }

  if (!open) return null;

  return (
    <div
      className="fixed inset-0 z-50 bg-black/60 backdrop-blur-sm flex items-start justify-center pt-24"
      onClick={() => setOpen(false)}
    >
      <div
        className="w-[min(640px,90vw)] bg-[#040810] border border-[#00ff9c] rounded-lg shadow-2xl overflow-hidden"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center gap-2 px-4 py-3 border-b border-[rgba(0,255,156,0.20)]">
          <span className="text-[#7fdbff] font-mono text-xs">⌘K</span>
          <input
            ref={inputRef}
            value={q}
            onChange={(e) => setQ(e.target.value)}
            onKeyDown={onKeyDown}
            placeholder="busca semântica no corpus inteiro…"
            className="flex-1 bg-transparent text-[#c8d4e6] outline-none font-mono text-sm placeholder:text-[#5a6678]"
          />
          {loading && <span className="text-[#5a6678] font-mono text-xs animate-pulse">…</span>}
        </div>
        <ul className="max-h-96 overflow-y-auto">
          {hits.length === 0 && q.trim().length >= 2 && !loading && (
            <li className="px-4 py-6 text-center text-[#5a6678] text-xs font-mono">sem resultados</li>
          )}
          {hits.map((h, i) => (
            <li
              key={`${h.doc_id}-${h.chunk_id}`}
              onMouseEnter={() => setSel(i)}
              onClick={() => go(h)}
              className={`px-3 py-2 cursor-pointer border-l-2 ${
                sel === i
                  ? "border-[#00ff9c] bg-[rgba(0,255,156,0.06)]"
                  : "border-transparent hover:bg-[rgba(127,219,255,0.04)]"
              }`}
            >
              <div className="flex items-center gap-2 text-[10px] font-mono mb-0.5">
                <span className="text-[#00ff9c]">{h.chunk_id}</span>
                <span className="text-[#5a6678]">p{h.page}</span>
                <span className="text-[#5a6678]">{h.type}</span>
                {h.classification && <span className="text-[#ff6b6b]">{h.classification}</span>}
                <span className="text-[#8896aa] ml-auto">{h.score.toFixed(2)}</span>
              </div>
              <div className="text-[#c8d4e6] text-xs line-clamp-2">{h.snippet}</div>
              <div className="text-[10px] font-mono text-[#5a6678] truncate mt-0.5">{h.doc_id}</div>
            </li>
          ))}
        </ul>
        <div className="px-3 py-2 border-t border-[rgba(0,255,156,0.20)] text-[10px] font-mono text-[#5a6678] flex justify-between">
          <span>↑↓ navegar · ↵ abrir · esc fechar</span>
          <span>{hits.length > 0 ? `${hits.length} hits` : "hybrid BM25+dense+rerank"}</span>
        </div>
      </div>
    </div>
  );
}
