"use client";

import Link from "next/link";
import { FormEvent, useEffect, useId, useMemo, useState } from "react";
import { formatEuro } from "@/lib/utils/money";
import { useSiteText } from "@/components/providers/site-text-provider";

type Suggestion = {
  _id: string;
  title: string;
  handle: string;
  imageUrl?: string;
  priceCents?: number | null;
  regularPriceCents?: number | null;
};

type Props = {
  className?: string;
};

const SEARCH_MIN_QUERY_LENGTH = 4;
const SEARCH_DEBOUNCE_MS = 650;

export function SearchAutocomplete({ className }: Props) {
  const { t } = useSiteText();
  const searchInputId = useId();
  const [query, setQuery] = useState("");
  const [suggestions, setSuggestions] = useState<Suggestion[]>([]);
  const [isOpen, setIsOpen] = useState(false);
  const [isLoading, setIsLoading] = useState(false);

  const trimmedQuery = useMemo(() => query.trim(), [query]);

  useEffect(() => {
    if (trimmedQuery.length < SEARCH_MIN_QUERY_LENGTH) {
      setSuggestions([]);
      setIsOpen(false);
      setIsLoading(false);
      return;
    }

    const controller = new AbortController();
    const timeout = setTimeout(async () => {
      try {
        setIsLoading(true);
        const response = await fetch(`/api/search/suggestions?q=${encodeURIComponent(trimmedQuery)}`, {
          signal: controller.signal,
        });

        if (response.status === 429) {
          setSuggestions([]);
          setIsOpen(false);
          return;
        }

        const payload = (await response.json()) as { suggestions?: Suggestion[] };
        setSuggestions(payload.suggestions || []);
        setIsOpen(true);
      } catch {
        if (!controller.signal.aborted) {
          setSuggestions([]);
        }
      } finally {
        if (!controller.signal.aborted) {
          setIsLoading(false);
        }
      }
    }, SEARCH_DEBOUNCE_MS);

    return () => {
      clearTimeout(timeout);
      controller.abort();
    };
  }, [trimmedQuery]);

  const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
    if (!trimmedQuery) {
      event.preventDefault();
    }
  };

  return (
    <form
      action="/recherche"
      method="GET"
      role="search"
      onSubmit={handleSubmit}
      onFocus={() => {
        if (trimmedQuery.length >= SEARCH_MIN_QUERY_LENGTH) {
          setIsOpen(true);
        }
      }}
      onBlur={() => {
        setTimeout(() => setIsOpen(false), 120);
      }}
      className={className}
    >
      <label htmlFor={searchInputId} className="sr-only">
        {t("search.label")}
      </label>
      <input
        id={searchInputId}
        name="q"
        type="search"
        value={query}
        onChange={(event) => setQuery(event.target.value)}
        placeholder={t("search.placeholder")}
        autoComplete="off"
        className="h-10 w-full bg-transparent px-4 text-sm text-[var(--foreground)] outline-none placeholder:text-[var(--muted)]"
      />
      <button
        type="submit"
        className="inline-flex h-10 items-center justify-center rounded-full bg-[var(--accent-3)] px-4 text-xs font-semibold uppercase tracking-[0.12em] text-white transition hover:bg-[var(--accent-2)]"
      >
        {t("search.submit")}
      </button>

      {isOpen ? (
        <div className="absolute left-0 right-0 top-[calc(100%+0.5rem)] z-50 overflow-hidden rounded-[1.3rem] border border-[#ffe2e2] bg-white shadow-[0_18px_40px_rgba(49,18,18,0.14)]">
          {isLoading ? <p className="px-4 py-3 text-sm text-[var(--muted)]">{t("search.loading")}</p> : null}

          {!isLoading && suggestions.length === 0 && trimmedQuery.length >= SEARCH_MIN_QUERY_LENGTH ? (
            <p className="px-4 py-3 text-sm text-[var(--muted)]">{t("search.empty")}</p>
          ) : null}

          {!isLoading && suggestions.length > 0 ? (
            <ul>
              {suggestions.map((suggestion) => {
                const showRegularPrice =
                  typeof suggestion.regularPriceCents === "number" &&
                  typeof suggestion.priceCents === "number" &&
                  suggestion.regularPriceCents > suggestion.priceCents;

                return (
                  <li key={suggestion._id}>
                    <Link
                      href={`/produits/${suggestion.handle}`}
                      onMouseDown={(event) => {
                        // Keep focus on the search form long enough for the first click to navigate.
                        event.preventDefault();
                      }}
                      onClick={() => setIsOpen(false)}
                      className="flex items-center justify-between gap-4 border-b border-[#ffeaea] px-4 py-3 text-sm text-[var(--foreground)] transition hover:bg-[var(--surface-2)]"
                    >
                      <span className="line-clamp-1">{suggestion.title}</span>
                      <span className="flex shrink-0 items-baseline gap-2">
                        {showRegularPrice ? (
                          <span className="text-[11px] font-medium text-[var(--muted)] line-through decoration-[1.5px]">
                            {formatEuro(suggestion.regularPriceCents)}
                          </span>
                        ) : null}
                        <span className="text-xs font-semibold text-[var(--accent)]">{formatEuro(suggestion.priceCents)}</span>
                      </span>
                    </Link>
                  </li>
                );
              })}
              <li className="border-t border-[var(--line)]">
                <Link
                  href={`/recherche?q=${encodeURIComponent(trimmedQuery)}`}
                  onMouseDown={(event) => {
                    event.preventDefault();
                  }}
                  onClick={() => setIsOpen(false)}
                  className="block px-4 py-3 text-xs font-semibold uppercase tracking-[0.12em] text-[var(--accent-3)] transition hover:bg-[var(--surface-2)]"
                >
                  {t("search.viewAll")}
                </Link>
              </li>
            </ul>
          ) : null}
        </div>
      ) : null}
    </form>
  );
}
