"use client";

import { useEffect, useId, useMemo, useRef, useState } from "react";
import Link from "next/link";
import { Search, FileText, BookOpen, FolderOpen, Loader2 } from "lucide-react";

import {
  useGlobalSearch,
  type CaseHit,
  type DocumentHit,
} from "@/lib/api/global-search";
import type { SearchHit as PrecedentHit } from "@/lib/api/precedent-library";

const DEBOUNCE_MS = 250;

/**
 * Header global search — debounced input + per-source result panel.
 *
 * Three independent fan-out queries (cases / precedent / documents) each
 * render their own section with an own loading/empty state, so the fast
 * SQL source paints immediately while the slower vector sources stream in.
 */
export function GlobalSearch() {
  const [raw, setRaw] = useState("");
  const [debounced, setDebounced] = useState("");
  const [open, setOpen] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const wrapperRef = useRef<HTMLDivElement>(null);
  const listboxId = useId();

  // Debounce.
  useEffect(() => {
    const t = setTimeout(() => setDebounced(raw), DEBOUNCE_MS);
    return () => clearTimeout(t);
  }, [raw]);

  // Cmd/Ctrl+K — focus + select.
  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      const isModK = (e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k";
      if (isModK) {
        e.preventDefault();
        inputRef.current?.focus();
        inputRef.current?.select();
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  // Click-outside.
  useEffect(() => {
    if (!open) return;
    const onClick = (e: MouseEvent) => {
      if (!wrapperRef.current?.contains(e.target as Node)) setOpen(false);
    };
    window.addEventListener("mousedown", onClick);
    return () => window.removeEventListener("mousedown", onClick);
  }, [open]);

  // Route changes don't need a separate listener: clicking any link
  // (nav, search result, in-page) triggers mousedown outside wrapperRef,
  // and the click-outside effect closes the panel.

  const { cases, precedent, documents, isQueryReady, anyLoading } =
    useGlobalSearch(debounced);

  const showPanel = open && isQueryReady;

  const hasAnyResults = useMemo(() => {
    return (
      (cases.data?.items.length ?? 0) > 0 ||
      (precedent.data?.items.length ?? 0) > 0 ||
      (documents.data?.length ?? 0) > 0
    );
  }, [cases.data, precedent.data, documents.data]);

  return (
    <div ref={wrapperRef} className="relative w-full max-w-[460px]">
      <div className="relative">
        <Search
          className="absolute end-3 top-1/2 -translate-y-1/2 size-4 text-parchment/50 pointer-events-none"
          aria-hidden="true"
        />
        <input
          ref={inputRef}
          type="search"
          value={raw}
          onChange={(e) => {
            setRaw(e.target.value);
            setOpen(true);
          }}
          onFocus={() => setOpen(true)}
          onKeyDown={(e) => {
            if (e.key === "Escape") {
              setOpen(false);
              inputRef.current?.blur();
            }
          }}
          placeholder="חפש תיק, פסיקה, או מסמך…"
          aria-label="חיפוש גלובלי"
          autoComplete="off"
          spellCheck={false}
          className="
            w-full ps-3 pe-10 py-2 rounded-md
            bg-navy-soft/60 border border-parchment/15
            text-sm text-parchment placeholder:text-parchment/40
            focus:outline-none focus:ring-2 focus:ring-gold/60 focus:border-transparent
            transition-colors
          "
        />
        <kbd
          className="
            absolute end-9 top-1/2 -translate-y-1/2
            text-[10px] font-mono text-parchment/40
            border border-parchment/20 rounded px-1 py-0.5
            pointer-events-none select-none
            hidden md:inline-block
          "
          aria-hidden="true"
        >
          ⌘K
        </kbd>
      </div>

      {showPanel && (
        <div
          id={listboxId}
          role="listbox"
          aria-label="תוצאות חיפוש"
          className="
            absolute top-full inset-x-0 mt-2 z-50
            rounded-lg bg-popover text-popover-foreground
            shadow-xl ring-1 ring-foreground/10
            max-h-[70vh] overflow-y-auto
          "
          dir="rtl"
        >
          {anyLoading && !hasAnyResults && (
            <div className="px-4 py-6 text-sm text-muted-foreground flex items-center gap-2">
              <Loader2 className="size-4 animate-spin" aria-hidden="true" />
              מחפש…
            </div>
          )}

          <ResultGroup
            title="תיקים"
            icon={<FolderOpen className="size-4" aria-hidden="true" />}
            isLoading={cases.isLoading}
            isError={cases.isError}
            count={cases.data?.count}
          >
            {cases.data?.items.map((hit) => (
              <CaseRow key={hit.case_number} hit={hit} onSelect={() => setOpen(false)} />
            ))}
          </ResultGroup>

          <ResultGroup
            title="ספריית פסיקה"
            icon={<BookOpen className="size-4" aria-hidden="true" />}
            isLoading={precedent.isLoading}
            isError={precedent.isError}
            count={precedent.data?.count}
            seeMoreHref={`/precedents?q=${encodeURIComponent(debounced)}`}
          >
            {precedent.data?.items.map((hit, i) => (
              <PrecedentRow key={`${hit.case_law_id}-${i}`} hit={hit} onSelect={() => setOpen(false)} />
            ))}
          </ResultGroup>

          <ResultGroup
            title="מסמכי תיקים והחלטות"
            icon={<FileText className="size-4" aria-hidden="true" />}
            isLoading={documents.isLoading}
            isError={documents.isError}
            count={documents.data?.length}
          >
            {documents.data?.map((hit, i) => (
              <DocumentRow key={`${hit.case_number}-${i}`} hit={hit} onSelect={() => setOpen(false)} />
            ))}
          </ResultGroup>

          {!anyLoading && !hasAnyResults && (
            <div className="px-4 py-6 text-sm text-muted-foreground text-center">
              לא נמצא כלום עבור <span className="font-mono">{debounced}</span>.
              <br />
              נסה מילים נרדפות או חפש לפי מספר תיק.
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ─── Result groups + rows ────────────────────────────────────────────

function ResultGroup({
  title,
  icon,
  isLoading,
  isError,
  count,
  seeMoreHref,
  children,
}: {
  title: string;
  icon: React.ReactNode;
  isLoading: boolean;
  isError: boolean;
  count: number | undefined;
  seeMoreHref?: string;
  children: React.ReactNode;
}) {
  const hasItems = (count ?? 0) > 0;

  return (
    <div className="border-b border-foreground/5 last:border-b-0">
      <div className="flex items-center gap-2 px-3 pt-3 pb-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider">
        {icon}
        <span>{title}</span>
        {count !== undefined && (
          <span className="text-foreground/50 normal-case font-normal">({count})</span>
        )}
        {isLoading && <Loader2 className="size-3 animate-spin ms-auto" aria-hidden="true" />}
      </div>

      {isError && (
        <div className="px-3 pb-2 text-xs text-destructive">שגיאה בטעינת תוצאות</div>
      )}

      {!isLoading && !isError && !hasItems && (
        <div className="px-3 pb-2 text-xs text-muted-foreground/70">אין תוצאות בקטגוריה זו</div>
      )}

      <div className="flex flex-col">{children}</div>

      {seeMoreHref && hasItems && (
        <Link
          href={seeMoreHref}
          className="block px-3 py-1.5 text-xs text-gold-deep hover:bg-accent/40 transition-colors"
        >
          הצג עוד →
        </Link>
      )}
    </div>
  );
}

function CaseRow({ hit, onSelect }: { hit: CaseHit; onSelect: () => void }) {
  return (
    <Link
      href={`/cases/${encodeURIComponent(hit.case_number)}`}
      onClick={onSelect}
      role="option"
      className="block px-3 py-2 hover:bg-accent/40 transition-colors"
    >
      <div className="flex items-baseline justify-between gap-3">
        <span className="font-medium text-sm">ערר {hit.case_number}</span>
        {hit.status && (
          <span className="text-[10px] uppercase tracking-wider text-muted-foreground">
            {hit.status}
          </span>
        )}
      </div>
      <div className="text-xs text-muted-foreground truncate">
        {hit.title}
        {hit.property_address && <span> · {hit.property_address}</span>}
      </div>
    </Link>
  );
}

function PrecedentRow({ hit, onSelect }: { hit: PrecedentHit; onSelect: () => void }) {
  const href = `/precedents/${hit.case_law_id}`;
  const pct = Math.round(hit.score * 100);

  if (hit.type === "halacha") {
    return (
      <Link
        href={href}
        onClick={onSelect}
        role="option"
        className="block px-3 py-2 hover:bg-accent/40 transition-colors"
      >
        <div className="flex items-baseline justify-between gap-3">
          <span className="font-medium text-sm line-clamp-1">הלכה — {hit.rule_statement}</span>
          <span className="text-[10px] text-gold-deep tabular-nums">{pct}%</span>
        </div>
        <div className="text-xs text-muted-foreground truncate">
          {hit.case_name} · {hit.case_number}
        </div>
      </Link>
    );
  }

  return (
    <Link
      href={href}
      onClick={onSelect}
      role="option"
      className="block px-3 py-2 hover:bg-accent/40 transition-colors"
    >
      <div className="flex items-baseline justify-between gap-3">
        <span className="font-medium text-sm">פסקה</span>
        <span className="text-[10px] text-gold-deep tabular-nums">{pct}%</span>
      </div>
      <div className="text-xs text-muted-foreground line-clamp-2">
        “{hit.content.slice(0, 160)}…”
      </div>
      <div className="text-[11px] text-muted-foreground/70">
        {hit.case_name} · {hit.case_number}
      </div>
    </Link>
  );
}

function DocumentRow({ hit, onSelect }: { hit: DocumentHit; onSelect: () => void }) {
  const pct = Math.round(hit.score * 100);
  return (
    <Link
      href={`/cases/${encodeURIComponent(hit.case_number)}`}
      onClick={onSelect}
      role="option"
      className="block px-3 py-2 hover:bg-accent/40 transition-colors"
    >
      <div className="flex items-baseline justify-between gap-3">
        <span className="font-medium text-sm truncate">{hit.document}</span>
        <span className="text-[10px] text-gold-deep tabular-nums">{pct}%</span>
      </div>
      <div className="text-xs text-muted-foreground line-clamp-2">
        “{hit.content.slice(0, 160)}…”
      </div>
      <div className="text-[11px] text-muted-foreground/70">
        ערר {hit.case_number}
        {hit.page != null && <span> · עמ׳ {hit.page}</span>}
      </div>
    </Link>
  );
}
