import { useState, useRef, useEffect } from "react";
import {
  useCategories,
  useCreateCategory,
} from "../hooks/useCategories";

interface CategoryPickerProps {
  value: number;
  onChange: (categoryId: number) => void;
}

export function CategoryPicker({ value, onChange }: CategoryPickerProps) {
  const { data: categories = [] } = useCategories();
  const createCategory = useCreateCategory();
  const [inputValue, setInputValue] = useState("");
  const [isOpen, setIsOpen] = useState(false);
  const [highlightIndex, setHighlightIndex] = useState(-1);
  const containerRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const listRef = useRef<HTMLUListElement>(null);

  // Sync display value when value prop changes
  const selectedCategory = categories.find((c) => c.id === value);

  const filtered = categories.filter((c) =>
    c.name.toLowerCase().includes(inputValue.toLowerCase()),
  );

  const showCreateOption =
    inputValue.trim() !== "" &&
    !categories.some(
      (c) => c.name.toLowerCase() === inputValue.trim().toLowerCase(),
    );

  const totalOptions = filtered.length + (showCreateOption ? 1 : 0);

  useEffect(() => {
    function handleClickOutside(e: MouseEvent) {
      if (
        containerRef.current &&
        !containerRef.current.contains(e.target as Node)
      ) {
        setIsOpen(false);
        // Reset input to selected category name
        if (selectedCategory) {
          setInputValue("");
        }
      }
    }
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, [selectedCategory]);

  function handleSelect(categoryId: number) {
    onChange(categoryId);
    setInputValue("");
    setIsOpen(false);
    setHighlightIndex(-1);
  }

  async function handleCreate() {
    const name = inputValue.trim();
    if (!name) return;
    createCategory.mutate(
      { name, emoji: "\u{1F4E6}" },
      {
        onSuccess: (newCat) => {
          handleSelect(newCat.id);
        },
      },
    );
  }

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

    switch (e.key) {
      case "ArrowDown":
        e.preventDefault();
        setHighlightIndex((i) => Math.min(i + 1, totalOptions - 1));
        break;
      case "ArrowUp":
        e.preventDefault();
        setHighlightIndex((i) => Math.max(i - 1, 0));
        break;
      case "Enter":
        e.preventDefault();
        if (highlightIndex >= 0 && highlightIndex < filtered.length) {
          handleSelect(filtered[highlightIndex].id);
        } else if (
          showCreateOption &&
          highlightIndex === filtered.length
        ) {
          handleCreate();
        }
        break;
      case "Escape":
        setIsOpen(false);
        setHighlightIndex(-1);
        setInputValue("");
        break;
    }
  }

  // Scroll highlighted option into view
  useEffect(() => {
    if (highlightIndex >= 0 && listRef.current) {
      const option = listRef.current.children[highlightIndex] as HTMLElement;
      option?.scrollIntoView({ block: "nearest" });
    }
  }, [highlightIndex]);

  return (
    <div ref={containerRef} className="relative">
      <input
        ref={inputRef}
        type="text"
        role="combobox"
        aria-expanded={isOpen}
        aria-autocomplete="list"
        aria-controls="category-listbox"
        aria-activedescendant={
          highlightIndex >= 0 ? `category-option-${highlightIndex}` : undefined
        }
        value={
          isOpen
            ? inputValue
            : selectedCategory
              ? `${selectedCategory.emoji} ${selectedCategory.name}`
              : ""
        }
        placeholder="Search or create category..."
        onChange={(e) => {
          setInputValue(e.target.value);
          setIsOpen(true);
          setHighlightIndex(-1);
        }}
        onFocus={() => {
          setIsOpen(true);
          setInputValue("");
        }}
        onKeyDown={handleKeyDown}
        className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
      />
      {isOpen && (
        <ul
          ref={listRef}
          id="category-listbox"
          role="listbox"
          className="absolute z-20 mt-1 w-full max-h-48 overflow-auto bg-white border border-gray-200 rounded-lg shadow-lg"
        >
          {filtered.map((cat, i) => (
            <li
              key={cat.id}
              id={`category-option-${i}`}
              role="option"
              aria-selected={cat.id === value}
              className={`px-3 py-2 text-sm cursor-pointer ${
                i === highlightIndex
                  ? "bg-blue-50 text-blue-900"
                  : "hover:bg-gray-50"
              } ${cat.id === value ? "font-medium" : ""}`}
              onClick={() => handleSelect(cat.id)}
              onMouseEnter={() => setHighlightIndex(i)}
            >
              {cat.emoji} {cat.name}
            </li>
          ))}
          {showCreateOption && (
            <li
              id={`category-option-${filtered.length}`}
              role="option"
              aria-selected={false}
              className={`px-3 py-2 text-sm cursor-pointer border-t border-gray-100 ${
                highlightIndex === filtered.length
                  ? "bg-blue-50 text-blue-900"
                  : "hover:bg-gray-50 text-gray-600"
              }`}
              onClick={handleCreate}
              onMouseEnter={() => setHighlightIndex(filtered.length)}
            >
              + Create "{inputValue.trim()}"
            </li>
          )}
          {filtered.length === 0 && !showCreateOption && (
            <li className="px-3 py-2 text-sm text-gray-400">
              No categories found
            </li>
          )}
        </ul>
      )}
    </div>
  );
}
