"use client";

import { useEffect, useId, useRef, useState } from "react";

import { CloseIcon, SearchIcon, Spinner } from "@/components/ui";

/** Example queries that demonstrate the semantic behaviour of the search. */
const EXAMPLE_QUERIES = [
  "headphones for travelling",
  "something for working out",
  "comfortable shoes for running",
  "gift for someone who loves music",
  "cheap wireless headphones",
];

export interface ProductSearchProps {
  value: string;
  onChange: (value: string) => void;
  onClear: () => void;
  isLoading: boolean;
  suggestions: string[];
}

/**
 * The search box: input, search icon, clear button, loading indicator and
 * suggestions. Implemented as a labelled `role="search"` form rather than a
 * combobox — suggestions are a convenience, not a required interaction path.
 */
export function ProductSearch({
  value,
  onChange,
  onClear,
  isLoading,
  suggestions,
}: ProductSearchProps) {
  const inputId = useId();
  const [focused, setFocused] = useState(false);
  const container = useRef<HTMLDivElement>(null);
  const showSuggestions = focused && suggestions.length > 0 && value.trim().length > 0;

  useEffect(() => {
    function onPointerDown(event: MouseEvent) {
      if (!container.current?.contains(event.target as Node)) setFocused(false);
    }
    document.addEventListener("mousedown", onPointerDown);
    return () => document.removeEventListener("mousedown", onPointerDown);
  }, []);

  return (
    <div ref={container} className="relative">
      <form
        role="search"
        onSubmit={(event) => {
          event.preventDefault();
          setFocused(false);
        }}
      >
        <label htmlFor={inputId} className="sr-only">
          Search products
        </label>
        <div className="relative">
          <SearchIcon className="pointer-events-none absolute top-1/2 left-4 size-5 -translate-y-1/2 text-slate-400" />

          <input
            id={inputId}
            type="search"
            value={value}
            autoComplete="off"
            onChange={(event) => onChange(event.target.value)}
            onFocus={() => setFocused(true)}
            placeholder="Search by meaning — try “headphones for travelling”"
            aria-describedby={`${inputId}-hint`}
            className="w-full rounded-2xl border border-slate-300 bg-white py-3.5 pr-28 pl-12 text-base text-slate-900 shadow-sm transition placeholder:text-slate-400 focus:border-indigo-500 focus:ring-4 focus:ring-indigo-500/15 focus:outline-none"
          />

          <div className="absolute top-1/2 right-3 flex -translate-y-1/2 items-center gap-1">
            {isLoading ? (
              <span className="flex items-center gap-1.5 pr-1 text-xs text-slate-500">
                <Spinner />
                <span className="sr-only">Searching</span>
              </span>
            ) : null}
            {value ? (
              <button
                type="button"
                onClick={() => {
                  onClear();
                  onChange("");
                }}
                className="rounded-full p-1.5 text-slate-500 transition-colors hover:bg-slate-100 hover:text-slate-700 focus-visible:ring-2 focus-visible:ring-indigo-600 focus-visible:outline-none"
              >
                <CloseIcon />
                <span className="sr-only">Clear search</span>
              </button>
            ) : null}
          </div>
        </div>
      </form>

      <p id={`${inputId}-hint`} className="sr-only">
        Results update as you type and are ranked by vector similarity, not just keyword matches.
      </p>

      {showSuggestions ? (
        <ul className="absolute inset-x-0 top-full z-20 mt-2 overflow-hidden rounded-2xl border border-slate-200 bg-white py-1.5 shadow-lg">
          {suggestions.map((suggestion) => (
            <li key={suggestion}>
              <button
                type="button"
                onClick={() => {
                  onChange(suggestion);
                  setFocused(false);
                }}
                className="flex w-full items-center gap-2.5 px-4 py-2 text-left text-sm text-slate-700 transition-colors hover:bg-indigo-50 hover:text-indigo-800 focus-visible:bg-indigo-50 focus-visible:outline-none"
              >
                <SearchIcon className="size-4 shrink-0 text-slate-400" />
                {suggestion}
              </button>
            </li>
          ))}
        </ul>
      ) : null}

      {!value ? (
        <div className="mt-3 flex flex-wrap items-center gap-2">
          <span className="text-xs text-slate-500">Try:</span>
          {EXAMPLE_QUERIES.map((example) => (
            <button
              key={example}
              type="button"
              onClick={() => onChange(example)}
              className="rounded-full border border-slate-300 bg-white px-3 py-1 text-xs text-slate-600 transition-colors hover:border-indigo-300 hover:bg-indigo-50 hover:text-indigo-700 focus-visible:ring-2 focus-visible:ring-indigo-600 focus-visible:outline-none"
            >
              {example}
            </button>
          ))}
        </div>
      ) : null}
    </div>
  );
}
