import { Search, X } from "lucide-react";
import {
	type KeyboardEvent,
	useCallback,
	useEffect,
	useRef,
	useState,
} from "react";
import type { SearchResult } from "../hooks/use-bestiary.js";
import { Input } from "./ui/input.js";

interface BestiarySearchProps {
	onSelectCreature: (result: SearchResult) => void;
	onClose: () => void;
	searchFn: (query: string) => SearchResult[];
}

export function BestiarySearch({
	onSelectCreature,
	onClose,
	searchFn,
}: BestiarySearchProps) {
	const [query, setQuery] = useState("");
	const [highlightIndex, setHighlightIndex] = useState(-1);
	const inputRef = useRef<HTMLInputElement>(null);
	const containerRef = useRef<HTMLDivElement>(null);
	const results = query.length >= 2 ? searchFn(query) : [];

	useEffect(() => {
		inputRef.current?.focus();
	}, []);

	useEffect(() => {
		setHighlightIndex(-1);
	}, [query]);

	useEffect(() => {
		function handleClickOutside(e: MouseEvent) {
			if (
				containerRef.current &&
				!containerRef.current.contains(e.target as Node)
			) {
				onClose();
			}
		}
		document.addEventListener("mousedown", handleClickOutside);
		return () => document.removeEventListener("mousedown", handleClickOutside);
	}, [onClose]);

	const handleKeyDown = useCallback(
		(e: KeyboardEvent) => {
			if (e.key === "Escape") {
				onClose();
				return;
			}
			if (e.key === "ArrowDown") {
				e.preventDefault();
				setHighlightIndex((i) => (i < results.length - 1 ? i + 1 : 0));
				return;
			}
			if (e.key === "ArrowUp") {
				e.preventDefault();
				setHighlightIndex((i) => (i > 0 ? i - 1 : results.length - 1));
				return;
			}
			if (e.key === "Enter" && highlightIndex >= 0) {
				e.preventDefault();
				onSelectCreature(results[highlightIndex]);
			}
		},
		[results, highlightIndex, onClose, onSelectCreature],
	);

	return (
		<div ref={containerRef} className="relative w-full max-w-sm">
			<div className="flex items-center gap-2">
				<Search className="h-4 w-4 text-muted-foreground" />
				<Input
					ref={inputRef}
					type="text"
					value={query}
					onChange={(e) => setQuery(e.target.value)}
					onKeyDown={handleKeyDown}
					placeholder="Search bestiary..."
					className="flex-1"
				/>
				<button
					type="button"
					onClick={onClose}
					className="text-muted-foreground hover:text-hover-neutral"
				>
					<X className="h-4 w-4" />
				</button>
			</div>

			{query.length >= 2 && (
				<div className="absolute bottom-full z-50 mb-1 w-full rounded-md border border-border bg-card shadow-lg">
					{results.length === 0 ? (
						<div className="px-3 py-2 text-sm text-muted-foreground">
							No creatures found
						</div>
					) : (
						<ul className="max-h-60 overflow-y-auto py-1">
							{results.map((result, i) => (
								<li key={`${result.source}:${result.name}`}>
									<button
										type="button"
										className={`flex w-full items-center justify-between px-3 py-1.5 text-left text-sm ${
											i === highlightIndex
												? "bg-accent/20 text-foreground"
												: "text-foreground hover:bg-hover-neutral-bg"
										}`}
										onClick={() => onSelectCreature(result)}
										onMouseEnter={() => setHighlightIndex(i)}
									>
										<span>{result.name}</span>
										<span className="text-xs text-muted-foreground">
											{result.sourceDisplayName}
										</span>
									</button>
								</li>
							))}
						</ul>
					)}
				</div>
			)}
		</div>
	);
}
