"use client";

//  File:    occupation-search.tsx
//  Path:    apps/web/components/occupation-search.tsx
//  Project: AI Risk Index — airiskindex.io
//  Author:  Simon-Pierre Boucher
//  Contact: contact@spboucher.ai
//  Copyright © 2026 Simon-Pierre Boucher. All rights reserved.
//
//  Description: Debounced live occupation search box (client component).


import Link from "next/link";
import { useEffect, useRef, useState } from "react";

interface Item {
  code: string;
  title: string;
}

/** Debounced live search over /api/v1/occupations. */
export function OccupationSearch(): JSX.Element {
  const [query, setQuery] = useState("");
  const [items, setItems] = useState<Item[]>([]);
  const [open, setOpen] = useState(false);
  const boxRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (query.trim().length < 2) {
      setItems([]);
      return;
    }
    const controller = new AbortController();
    const timer = setTimeout(async () => {
      try {
        const response = await fetch(
          `/api/v1/occupations?q=${encodeURIComponent(query.trim())}&per_page=8`,
          { signal: controller.signal },
        );
        if (response.ok) {
          const data = (await response.json()) as { items: Item[] };
          setItems(data.items);
          setOpen(true);
        }
      } catch {
        /* aborted or offline — keep prior results */
      }
    }, 200);
    return () => {
      controller.abort();
      clearTimeout(timer);
    };
  }, [query]);

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

  return (
    <div ref={boxRef} className="relative max-w-xl">
      <input
        type="search"
        value={query}
        onChange={(event) => setQuery(event.target.value)}
        onFocus={() => items.length > 0 && setOpen(true)}
        placeholder="Search 1,000+ occupations — e.g. paralegal, radiologist, roofer…"
        aria-label="Search occupations"
        className="w-full card px-4 py-3 text-base outline-none placeholder:text-[var(--muted)] focus:border-[var(--seq)]"
      />
      {open && items.length > 0 && (
        <ul className="absolute z-20 mt-2 w-full overflow-hidden card shadow-lg">
          {items.map((item) => (
            <li key={item.code} className="border-b border-[var(--grid)] last:border-b-0">
              <Link
                href={`/occupations/${item.code}`}
                className="flex items-baseline justify-between px-4 py-2.5 hover:bg-[var(--wash)]"
                onClick={() => setOpen(false)}
              >
                <span className="truncate">{item.title}</span>
                <span className="ml-3 shrink-0 text-xs text-[var(--muted)]">{item.code}</span>
              </Link>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}
