"use client";

import { useState, useRef, useEffect } from "react";
import { ChevronDown, Search } from "lucide-react";
import clsx from "clsx";
import styles from "@/styles/AgentSelector.module.css";

interface AgentSelectorProps {
	agents: string[];
	selectedAgent: string;
	onSelect: (agent: string) => void;
	placeholder?: string;
}

export function AgentSelector({
	agents,
	selectedAgent,
	onSelect,
	placeholder = "Select an agent..."
}: AgentSelectorProps) {
	const [isOpen, setIsOpen] = useState(false);
	const [searchTerm, setSearchTerm] = useState("");
	const [highlightedIndex, setHighlightedIndex] = useState(0);
	const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, width: 0 });
	const dropdownRef = useRef<HTMLDivElement>(null);
	const triggerRef = useRef<HTMLButtonElement>(null);
	const searchRef = useRef<HTMLInputElement>(null);

	const filteredAgents = agents.filter(agent =>
		agent.toLowerCase().includes(searchTerm.toLowerCase())
	);

	useEffect(() => {
		function handleClickOutside(event: MouseEvent) {
			if (
				dropdownRef.current &&
				!dropdownRef.current.contains(event.target as Node)
			) {
				setIsOpen(false);
				setSearchTerm("");
			}
		}

		if (isOpen) {
			document.addEventListener("mousedown", handleClickOutside);
		}

		return () => {
			document.removeEventListener("mousedown", handleClickOutside);
		};
	}, [isOpen]);

	useEffect(() => {
		if (isOpen && searchRef.current) {
			searchRef.current.focus();
		}
	}, [isOpen]);

	useEffect(() => {
		setHighlightedIndex(0);
	}, [searchTerm]);

	const handleKeyDown = (e: React.KeyboardEvent) => {
		if (!isOpen) {
			if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
				e.preventDefault();
				updateDropdownPosition();
				setIsOpen(true);
			}
			return;
		}

		switch (e.key) {
			case "ArrowDown":
				e.preventDefault();
				setHighlightedIndex(prev =>
					prev < filteredAgents.length - 1 ? prev + 1 : 0
				);
				break;
			case "ArrowUp":
				e.preventDefault();
				setHighlightedIndex(prev =>
					prev > 0 ? prev - 1 : filteredAgents.length - 1
				);
				break;
			case "Enter":
				e.preventDefault();
				if (filteredAgents[highlightedIndex]) {
					onSelect(filteredAgents[highlightedIndex]);
					setIsOpen(false);
					setSearchTerm("");
				}
				break;
			case "Escape":
				e.preventDefault();
				setIsOpen(false);
				setSearchTerm("");
				break;
		}
	};

	const handleSelect = (agent: string) => {
		onSelect(agent);
		setIsOpen(false);
		setSearchTerm("");
	};

	const updateDropdownPosition = () => {
		if (triggerRef.current) {
			const rect = triggerRef.current.getBoundingClientRect();
			setDropdownPosition({
				top: rect.bottom + 2,
				left: rect.left,
				width: rect.width
			});
		}
	};

	const handleOpen = () => {
		updateDropdownPosition();
		setIsOpen(!isOpen);
	};

	return (
		<div className={styles.agentSelector} ref={dropdownRef}>
			<button
				ref={triggerRef}
				className={clsx(styles.trigger, isOpen && styles.triggerOpen)}
				type="button"
				onClick={handleOpen}
				onKeyDown={handleKeyDown}
				aria-expanded={isOpen}
				aria-haspopup="listbox"
			>
				<span className={styles.triggerText}>
					{selectedAgent || placeholder}
				</span>
				<ChevronDown
					size={16}
					className={clsx(styles.chevron, isOpen && styles.chevronOpen)}
				/>
			</button>

			{isOpen && (
				<div
					className={styles.dropdown}
					style={{
						top: dropdownPosition.top,
						left: dropdownPosition.left,
						width: Math.max(dropdownPosition.width, 200)
					}}
				>
					<div className={styles.searchContainer}>
						<Search size={16} className={styles.searchIcon} />
						<input
							ref={searchRef}
							type="text"
							className={styles.searchInput}
							placeholder="Search agents..."
							value={searchTerm}
							onChange={(e) => setSearchTerm(e.target.value)}
							onKeyDown={handleKeyDown}
						/>
					</div>

					<ul className={styles.agentList} role="listbox">
						{filteredAgents.length === 0 ? (
							<li className={styles.noResults}>No agents found</li>
						) : (
							filteredAgents.map((agent, index) => (
								<li
									key={agent}
									className={clsx(
										styles.agentOption,
										agent === selectedAgent && styles.selected,
										index === highlightedIndex && styles.highlighted
									)}
									onClick={() => handleSelect(agent)}
									role="option"
									aria-selected={agent === selectedAgent}
								>
									{agent}
								</li>
							))
						)}
					</ul>
				</div>
			)}
		</div>
	);
}