"use client";

import { Search } from "lucide-react";
import Link from "next/link";
import { useEffect, useRef, useState } from "react";
import { getPosterUrl, type TmdbSearchResult } from "@/lib/tmdb";
import { cn } from "@/lib/utils";

export function SearchBar({
  autoFocus = false,
  onSelect,
  compact = false,
}: {
  autoFocus?: boolean;
  onSelect?: (movie: TmdbSearchResult) => void;
  compact?: boolean;
}) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [query, setQuery] = useState("");
  const [results, setResults] = useState<TmdbSearchResult[]>([]);
  const [loading, setLoading] = useState(false);
  const [open, setOpen] = useState(false);

  useEffect(() => {
    if (!query.trim()) {
      return;
    }

    const controller = new AbortController();
    const timeout = setTimeout(async () => {
      setLoading(true);
      try {
        const response = await fetch(
          `/api/search?q=${encodeURIComponent(query)}`,
          { signal: controller.signal },
        );
        const data = (await response.json()) as { results: TmdbSearchResult[] };
        setResults(data.results ?? []);
        setOpen(true);
      } catch (error) {
        if ((error as Error).name !== "AbortError") {
          setResults([]);
        }
      } finally {
        setLoading(false);
      }
    }, 300);

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

  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (!containerRef.current?.contains(event.target as Node)) {
        setOpen(false);
      }
    }

    if (open) {
      document.addEventListener("click", handleClickOutside);
    }

    return () => document.removeEventListener("click", handleClickOutside);
  }, [open]);

  return (
    <div
      ref={containerRef}
      className={cn("relative w-full", open && "z-50", !compact && "max-w-2xl")}
    >
      <div className="relative">
        <Search
          className={cn(
            "pointer-events-none absolute top-1/2 -translate-y-1/2 text-stone-400",
            compact ? "left-3 h-4 w-4" : "left-4 h-5 w-5",
          )}
        />
        <input
          autoFocus={autoFocus}
          type="search"
          name="movie-search"
          autoComplete="off"
          autoCorrect="off"
          autoCapitalize="off"
          spellCheck={false}
          data-1p-ignore
          data-lpignore="true"
          data-bwignore
          data-form-type="other"
          value={query}
          onChange={(event) => {
            const value = event.target.value;
            setQuery(value);
            if (!value.trim()) {
              setResults([]);
              setOpen(false);
            }
          }}
          onFocus={() => query.trim() && setOpen(true)}
          placeholder="Search for a movie..."
          className={cn(
            "w-full border border-stone-300 bg-white text-stone-950 outline-none transition focus:border-amber-500 focus:bg-amber-50 focus:ring-2 focus:ring-amber-200",
            compact
              ? "rounded-xl py-2 pl-9 pr-3 text-sm"
              : "rounded-2xl py-4 pl-12 pr-4 text-base",
          )}
        />
      </div>

      {open && (
        <ul
          role="listbox"
          className="absolute z-50 mt-2 w-full overflow-hidden rounded-2xl border border-stone-200 bg-white shadow-xl"
        >
          {loading && (
            <li className="px-4 py-3 text-sm text-stone-600">Searching...</li>
          )}
          {!loading && results.length === 0 && (
            <li className="px-4 py-3 text-sm text-stone-600">No results found</li>
          )}
          {!loading &&
            results.map((result) => {
              const poster = getPosterUrl(result.poster_path, "w185");
              const year = result.release_date?.slice(0, 4);

              const inner = (
                <>
                  <div className="relative h-14 w-10 shrink-0 overflow-hidden rounded-md bg-stone-200">
                    {poster ? (
                      <img
                        src={poster}
                        alt=""
                        className="absolute inset-0 h-full w-full object-cover"
                      />
                    ) : (
                      <div className="flex h-full items-center justify-center text-[10px] text-stone-500">
                        N/A
                      </div>
                    )}
                  </div>
                  <div className="min-w-0">
                    <p className="truncate font-medium text-stone-950">
                      {result.title}
                      {year ? (
                        <span className="ml-2 font-normal text-stone-500">
                          ({year})
                        </span>
                      ) : null}
                    </p>
                    <p className="line-clamp-1 text-sm text-stone-600">
                      {result.overview || "No overview available"}
                    </p>
                  </div>
                </>
              );

              return (
                <li key={result.id} role="option" aria-selected={false}>
                  {onSelect ? (
                    <button
                      type="button"
                      onClick={() => {
                        onSelect(result);
                        setOpen(false);
                        setQuery("");
                      }}
                      className="flex w-full items-center gap-3 border-b border-stone-100 px-4 py-3 text-left transition hover:bg-stone-50 last:border-b-0"
                    >
                      {inner}
                    </button>
                  ) : (
                    <Link
                      href={`/movie/${result.id}`}
                      prefetch
                      onClick={() => setOpen(false)}
                      className="flex items-center gap-3 border-b border-stone-100 px-4 py-3 transition hover:bg-stone-50 last:border-b-0"
                    >
                      {inner}
                    </Link>
                  )}
                </li>
              );
            })}
        </ul>
      )}
    </div>
  );
}