"use client";

import { useEffect, useId, useRef, useState } from "react";
import { usePathname, useRouter } from "next/navigation";
import { Search } from "lucide-react";
import { catalogApi } from "@/lib/api/catalog";
import type { ApiProductSuggestion } from "@/lib/api/types";
import { cn } from "@/lib/utils";

const MIN_CHARS = 2;
const DEBOUNCE_MS = 200;

/**
 * Header product search (B05). Enter goes to `/products?search=…`; from the
 * second letter a list of matching products opens, understanding trade words
 * ("sar" → TMT, "patti" → Flat) the same way the results page does.
 *
 * The old inputs had no form and no submit: typing and pressing Enter did
 * nothing at all.
 */
export default function HeaderSearch({
  placeholder = "Search for products, prices...",
  className,
  inputClassName,
  onNavigate,
}: {
  placeholder?: string;
  className?: string;
  inputClassName?: string;
  /** Called after a search or pick, e.g. to close the mobile menu. */
  onNavigate?: () => void;
}) {
  const router = useRouter();
  const pathname = usePathname();
  const listId = useId();
  const wrapRef = useRef<HTMLFormElement>(null);

  const [q, setQ] = useState("");
  const [items, setItems] = useState<ApiProductSuggestion[]>([]);
  const [interpreted, setInterpreted] = useState<string | null>(null);
  const [open, setOpen] = useState(false);
  const [active, setActive] = useState(-1);

  // Keep the box in step with the results page (read from the URL directly:
  // useSearchParams in the root layout would opt every page out of static rendering).
  useEffect(() => {
    if (pathname === "/products") {
      setQ(new URLSearchParams(window.location.search).get("search") ?? "");
    }
    setOpen(false);
  }, [pathname]);

  useEffect(() => {
    const term = q.trim();
    if (term.length < MIN_CHARS) {
      setItems([]);
      setInterpreted(null);
      return;
    }
    const ctrl = new AbortController();
    const t = window.setTimeout(() => {
      catalogApi
        .suggest(term, { signal: ctrl.signal })
        .then((r) => {
          setItems(r.data);
          setInterpreted(r.meta?.interpreted ?? null);
          setActive(-1);
        })
        .catch(() => {
          /* aborted or offline: keep the last list */
        });
    }, DEBOUNCE_MS);
    return () => {
      window.clearTimeout(t);
      ctrl.abort();
    };
  }, [q]);

  useEffect(() => {
    if (!open) return;
    const onDown = (e: MouseEvent) => {
      if (!wrapRef.current?.contains(e.target as Node)) setOpen(false);
    };
    document.addEventListener("mousedown", onDown);
    return () => document.removeEventListener("mousedown", onDown);
  }, [open]);

  function go(href: string) {
    setOpen(false);
    onNavigate?.();
    router.push(href);
  }

  function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    const pick = active >= 0 ? items[active] : undefined;
    if (pick) return go(`/products/${encodeURIComponent(pick.slug)}`);
    const term = q.trim();
    go(term ? `/products?search=${encodeURIComponent(term)}` : "/products");
  }

  function onKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === "ArrowDown" && items.length) {
      e.preventDefault();
      setOpen(true);
      setActive((i) => (i + 1) % items.length);
    } else if (e.key === "ArrowUp" && items.length) {
      e.preventDefault();
      setActive((i) => (i <= 0 ? items.length - 1 : i - 1));
    } else if (e.key === "Escape") {
      setOpen(false);
      setActive(-1);
    }
  }

  const showList = open && q.trim().length >= MIN_CHARS;

  return (
    <form ref={wrapRef} role="search" onSubmit={onSubmit} className={cn("relative w-full", className)}>
      <Search size={16} className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" aria-hidden />
      <input
        type="search"
        name="search"
        value={q}
        onChange={(e) => {
          setQ(e.target.value);
          setOpen(true);
        }}
        onFocus={() => setOpen(true)}
        onKeyDown={onKeyDown}
        placeholder={placeholder}
        aria-label="Search products"
        role="combobox"
        aria-autocomplete="list"
        aria-expanded={showList}
        aria-controls={listId}
        aria-activedescendant={active >= 0 ? `${listId}-${active}` : undefined}
        autoComplete="off"
        enterKeyHint="search"
        className={cn(
          "w-full rounded-lg border border-gray-200 bg-white py-2 pl-9 pr-4 text-sm text-gray-800 transition-all placeholder:text-gray-400 focus:border-[#CC1414] focus:outline-none focus:ring-2 focus:ring-[#CC1414]/20 [&::-webkit-search-cancel-button]:hidden",
          inputClassName
        )}
      />

      {showList && (
        <div className="absolute left-0 right-0 top-full z-50 mt-1 overflow-hidden rounded-xl border border-gray-100 bg-white shadow-xl">
          {interpreted && (
            <p className="border-b border-gray-50 px-3 py-2 text-xs text-gray-500">
              Showing <span className="font-semibold text-gray-700">{interpreted}</span>
            </p>
          )}
          <ul id={listId} role="listbox" aria-label="Product suggestions" className="max-h-80 overflow-y-auto py-1">
            {items.map((p, i) => (
              <li
                key={p.id}
                id={`${listId}-${i}`}
                role="option"
                aria-selected={i === active}
                onMouseEnter={() => setActive(i)}
                onMouseDown={(e) => e.preventDefault()}
                onClick={() => go(`/products/${encodeURIComponent(p.slug)}`)}
                className={cn(
                  "flex cursor-pointer items-center justify-between gap-3 px-3 py-2 text-sm",
                  i === active ? "bg-red-50 text-[#CC1414]" : "text-gray-800"
                )}
              >
                <span className="truncate font-medium">{p.name}</span>
                {p.category && <span className="shrink-0 text-xs capitalize text-gray-400">{p.category.toLowerCase()}</span>}
              </li>
            ))}
            {items.length === 0 && <li className="px-3 py-2 text-sm text-gray-500">No matching products</li>}
          </ul>
          {/* type="button": Enter in the input "clicks" the form's first submit
              button, which would drop the highlighted pick before onSubmit. */}
          <button
            type="button"
            onMouseDown={(e) => e.preventDefault()}
            onClick={() => go(`/products?search=${encodeURIComponent(q.trim())}`)}
            className="block w-full border-t border-gray-50 px-3 py-2 text-left text-sm font-medium text-[#CC1414] hover:bg-red-50"
          >
            Search for “{q.trim()}”
          </button>
        </div>
      )}
    </form>
  );
}
