import { useState, useEffect, useRef, useMemo, useCallback } from "react";
import { NoteStatus } from "@/types/noteStatus";

interface UseKeyboardNavigationProps {
	availableStatuses: NoteStatus[];
	currentStatuses: NoteStatus[];
	onSelectStatus: (status: NoteStatus) => void;
	onRemoveStatus: (status: NoteStatus) => void;
}

export const useKeyboardNavigation = ({
	availableStatuses,
	currentStatuses,
	onSelectStatus,
	onRemoveStatus,
}: UseKeyboardNavigationProps) => {
	const [focusedIndex, setFocusedIndex] = useState(-1);
	const [searchFilter, setSearchFilter] = useState("");
	const containerRef = useRef<HTMLDivElement>(null);
	const searchRef = useRef<HTMLInputElement>(null);

	const filteredStatuses = useMemo(
		() =>
			searchFilter
				? availableStatuses.filter((status) => {
						const searchTerm = searchFilter.toLowerCase();
						return (
							status.name.toLowerCase().includes(searchTerm) ||
							(status.templateId &&
								status.templateId
									.toLowerCase()
									.includes(searchTerm))
						);
					})
				: availableStatuses,
		[searchFilter, availableStatuses],
	);

	const handleKeyDown = useCallback(
		(e: React.KeyboardEvent) => {
			switch (e.key) {
				case "ArrowDown":
					e.preventDefault();
					if (filteredStatuses.length > 0) {
						setFocusedIndex((prev) =>
							prev < filteredStatuses.length - 1 ? prev + 1 : 0,
						);
					}
					break;
				case "ArrowUp":
					e.preventDefault();
					if (filteredStatuses.length > 0) {
						setFocusedIndex((prev) =>
							prev > 0 ? prev - 1 : filteredStatuses.length - 1,
						);
					}
					break;
				case "Tab":
					if (!e.shiftKey) {
						e.preventDefault();
						if (filteredStatuses.length > 0) {
							setFocusedIndex((prev) =>
								prev < filteredStatuses.length - 1
									? prev + 1
									: 0,
							);
						}
					} else {
						e.preventDefault();
						if (filteredStatuses.length > 0) {
							setFocusedIndex((prev) =>
								prev > 0
									? prev - 1
									: filteredStatuses.length - 1,
							);
						}
					}
					break;
				case "Enter":
					if (
						focusedIndex >= 0 &&
						focusedIndex < filteredStatuses.length
					) {
						e.preventDefault();
						const status = filteredStatuses[focusedIndex];
						const isSelected = currentStatuses.some(
							(s) =>
								s.name === status.name &&
								s.templateId === status.templateId,
						);
						if (isSelected) {
							onRemoveStatus(status);
						} else {
							onSelectStatus(status);
						}
					}
					break;
				case "Backspace":
					e.preventDefault();
					setSearchFilter((prev) => prev.slice(0, -1));
					if (searchRef.current) {
						searchRef.current.focus();
					}
					break;
				case "Escape":
					e.preventDefault();
					setSearchFilter("");
					break;
				default:
					if (
						e.key.length === 1 &&
						!e.ctrlKey &&
						!e.metaKey &&
						!e.altKey
					) {
						e.preventDefault();
						setSearchFilter((prev) => prev + e.key);
						if (searchRef.current) {
							searchRef.current.focus();
						}
					}
					break;
			}
		},
		[
			filteredStatuses,
			focusedIndex,
			currentStatuses,
			onRemoveStatus,
			onSelectStatus,
			searchRef,
		],
	);

	useEffect(() => {
		setFocusedIndex(filteredStatuses.length > 0 ? 0 : -1);
	}, [searchFilter, filteredStatuses.length]);

	useEffect(() => {
		if (containerRef.current) {
			containerRef.current.focus();
		}
	}, []);

	return {
		focusedIndex,
		searchFilter,
		filteredStatuses,
		containerRef,
		searchRef,
		handleKeyDown,
		setSearchFilter,
	};
};
