"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useCallback, useEffect, useRef, useState } from "react";
import type { SearchHit } from "@/lib/admin/search";

const TYPE_LABEL: Record<string, string> = {
  carbet: "Carbet",
  user: "Utilisateur",
  booking: "Réservation",
  page: "Page",
  provider: "Prestataire",
};
const TYPE_ACCENT: Record<string, string> = {
  carbet: "bg-emerald-100 text-emerald-800",
  user: "bg-sky-100 text-sky-800",
  booking: "bg-amber-100 text-amber-800",
  page: "bg-violet-100 text-violet-800",
  provider: "bg-rose-100 text-rose-800",
};

/**
 * Palette ⌘K minimaliste, sans dépendance externe. Server search via
 * /api/admin/search?q=…, navigation au clavier (↑/↓/Enter/Esc).
 */
export function CommandPalette() {
  const router = useRouter();
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const [hits, setHits] = useState<SearchHit[]>([]);
  const [selected, setSelected] = useState(0);
  const [loading, setLoading] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const abortRef = useRef<AbortController | null>(null);

  // Ouvre la palette sur ⌘K / Ctrl+K. Esc ferme.
  useEffect(() => {
    function onKey(e: KeyboardEvent) {
      const cmd = e.metaKey || e.ctrlKey;
      if (cmd && e.key.toLowerCase() === "k") {
        e.preventDefault();
        setOpen((v) => !v);
      } else if (e.key === "Escape") {
        setOpen(false);
      }
    }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  useEffect(() => {
    if (open) {
      setQuery("");
      setHits([]);
      setSelected(0);
      setTimeout(() => inputRef.current?.focus(), 50);
    }
  }, [open]);

  const runSearch = useCallback(async (q: string) => {
    if (q.trim().length < 2) {
      setHits([]);
      return;
    }
    abortRef.current?.abort();
    const ac = new AbortController();
    abortRef.current = ac;
    setLoading(true);
    try {
      const r = await fetch(`/api/admin/search?q=${encodeURIComponent(q)}`, { signal: ac.signal });
      if (r.ok) {
        const j = await r.json();
        setHits(j.hits ?? []);
        setSelected(0);
      }
    } catch {
      // aborted ou erreur silencieuse
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    const id = setTimeout(() => runSearch(query), 150);
    return () => clearTimeout(id);
  }, [query, runSearch]);

  function onListKey(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setSelected((s) => Math.min(s + 1, hits.length - 1));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setSelected((s) => Math.max(s - 1, 0));
    } else if (e.key === "Enter") {
      e.preventDefault();
      const hit = hits[selected];
      if (hit) {
        setOpen(false);
        router.push(hit.href);
      }
    }
  }

  if (!open) return null;

  return (
    <div
      className="fixed inset-0 z-50 flex items-start justify-center bg-zinc-900/30 px-4 pt-[12vh] backdrop-blur-sm"
      onClick={() => setOpen(false)}
    >
      <div
        className="w-full max-w-xl overflow-hidden rounded-lg border border-zinc-200 bg-white shadow-2xl"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center gap-2 border-b border-zinc-200 px-3 py-2">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="text-zinc-400">
            <circle cx="11" cy="11" r="7" />
            <path d="M21 21 L17 17" />
          </svg>
          <input
            ref={inputRef}
            type="text"
            value={query}
            placeholder="Rechercher un carbet, un user, une résa…"
            onChange={(e) => setQuery(e.target.value)}
            onKeyDown={onListKey}
            className="flex-1 bg-transparent text-sm text-zinc-900 placeholder-zinc-400 focus:outline-none"
          />
          <kbd className="rounded border border-zinc-300 bg-zinc-100 px-1.5 py-0.5 text-[10px] text-zinc-500">
            ESC
          </kbd>
        </div>

        <div className="max-h-96 overflow-y-auto py-1">
          {loading ? (
            <div className="px-4 py-3 text-sm text-zinc-500">…</div>
          ) : query.length >= 2 && hits.length === 0 ? (
            <div className="px-4 py-3 text-sm text-zinc-500">Aucun résultat.</div>
          ) : hits.length === 0 ? (
            <div className="px-4 py-3 text-sm text-zinc-500">
              Tape au moins 2 caractères. Navigation : ↑ ↓ / Entrée.
            </div>
          ) : (
            <ul>
              {hits.map((h, i) => (
                <li key={`${h.type}-${h.id}`}>
                  <Link
                    href={h.href}
                    onClick={() => setOpen(false)}
                    onMouseEnter={() => setSelected(i)}
                    className={`flex items-center justify-between gap-3 px-3 py-2 text-sm ${
                      i === selected ? "bg-zinc-100" : "hover:bg-zinc-50"
                    }`}
                  >
                    <span className="flex items-center gap-2 truncate">
                      <span
                        className={`rounded px-1.5 py-0.5 text-[10px] font-semibold ${TYPE_ACCENT[h.type]}`}
                      >
                        {TYPE_LABEL[h.type]}
                      </span>
                      <span className="truncate text-zinc-900">{h.title}</span>
                    </span>
                    {h.subtitle ? (
                      <span className="truncate text-xs text-zinc-500">{h.subtitle}</span>
                    ) : null}
                  </Link>
                </li>
              ))}
            </ul>
          )}
        </div>
      </div>
    </div>
  );
}
