"use client";

import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { Dialog, DialogPanel } from "@headlessui/react";
import { IconSearch } from "@tabler/icons-react";
import Fuse from "fuse.js";

import type { DocsSearchRecord } from "@/lib/docs/search-index";

export function DocsSearch({
  records,
  lang,
  className,
}: {
  records: DocsSearchRecord[];
  lang: string;
  className?: string;
}) {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const router = useRouter();

  const fuse = useMemo(
    () =>
      new Fuse(records, {
        keys: ["title", "pageTitle", "content"],
        threshold: 0.4,
        ignoreLocation: true,
      }),
    [records],
  );

  const results = useMemo(
    () => (query ? fuse.search(query).slice(0, 8).map((r) => r.item) : []),
    [query, fuse],
  );

  // ⌘K / Ctrl+K opens the dialog.
  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        setOpen(true);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  const go = (href: string) => {
    setOpen(false);
    setQuery("");
    router.push(`/${lang}${href}`);
  };

  return (
    <>
      <button
        type="button"
        onClick={() => setOpen(true)}
        className={`border-hairline bg-surface-2/60 text-ink-4 hover:border-hairline-2 flex items-center gap-2 rounded-xl border px-3 py-2 text-sm transition ${className ?? ""}`}
      >
        <IconSearch className="size-4" />
        <span className="flex-1 text-left">Find something…</span>
        <kbd className="border-hairline text-ink-4 hidden rounded border px-1.5 py-0.5 text-[11px] font-medium sm:inline">
          ⌘K
        </kbd>
      </button>

      <Dialog open={open} onClose={setOpen} className="relative z-50">
        <div
          className="fixed inset-0 bg-black/40 backdrop-blur-sm"
          aria-hidden="true"
        />
        <div className="fixed inset-0 flex items-start justify-center p-4 pt-[15vh]">
          <DialogPanel
            transition
            className="bg-background ring-hairline w-full max-w-lg overflow-hidden rounded-2xl shadow-2xl ring-1 transition data-[closed]:scale-95 data-[closed]:opacity-0"
          >
            <div className="border-hairline flex items-center gap-2 border-b px-4">
              <IconSearch className="text-ink-4 size-5" />
              <input
                autoFocus
                type="search"
                name="q"
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                placeholder="Find something…"
                aria-label="Find something…"
                autoComplete="off"
                inputMode="search"
                enterKeyHint="search"
                className="text-ink-1 placeholder:text-ink-4 w-full bg-transparent py-3.5 text-sm outline-none"
              />
            </div>
            {query && (
              <ul className="max-h-80 overflow-y-auto p-2">
                {results.length === 0 ? (
                  <li className="text-ink-4 px-3 py-6 text-center text-sm">
                    No results for “{query}”
                  </li>
                ) : (
                  results.map((r, i) => (
                    <li key={`${r.href}-${i}`}>
                      <button
                        type="button"
                        onClick={() => go(r.href)}
                        className="hover:bg-foreground/5 block w-full rounded-lg px-3 py-2 text-left"
                      >
                        <div className="text-ink-1 text-sm font-medium">
                          {r.title}
                        </div>
                        {r.title !== r.pageTitle && (
                          <div className="text-ink-4 text-xs">{r.pageTitle}</div>
                        )}
                      </button>
                    </li>
                  ))
                )}
              </ul>
            )}
          </DialogPanel>
        </div>
      </Dialog>
    </>
  );
}
