import { useState, useRef, useEffect, useMemo } from 'react';
import { useLanguages } from '../hooks/useLanguages';

interface LanguageSelectorProps {
  selectedLanguages: string[];
  onAdd: (langCode: string) => void;
  onRemove: (langCode: string) => void;
  disabled?: boolean;
}

export function LanguageSelector({
  selectedLanguages,
  onAdd,
  onRemove,
  disabled = false,
}: LanguageSelectorProps) {
  const { data: languagesData, isLoading, error } = useLanguages();
  const [searchQuery, setSearchQuery] = useState('');
  const [isOpen, setIsOpen] = useState(false);
  const [highlightedIndex, setHighlightedIndex] = useState(0);
  const containerRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  // Get available languages (not already selected), sorted alphabetically
  const availableLanguages = useMemo(() => {
    if (!languagesData?.languages) return [];

    return Object.entries(languagesData.languages)
      .filter(([code]) => !selectedLanguages.includes(code))
      .sort((a, b) => a[1].localeCompare(b[1]));
  }, [languagesData, selectedLanguages]);

  // Filter languages by search query
  const filteredLanguages = useMemo(() => {
    if (!searchQuery.trim()) return availableLanguages;

    const query = searchQuery.toLowerCase();
    return availableLanguages.filter(
      ([code, name]) =>
        name.toLowerCase().includes(query) ||
        code.toLowerCase().includes(query)
    );
  }, [availableLanguages, searchQuery]);

  // Reset highlighted index when filtered results change
  useEffect(() => {
    setHighlightedIndex(0);
  }, [filteredLanguages.length]);

  // Close dropdown when clicking outside
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    }

    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  const handleSelect = (langCode: string) => {
    onAdd(langCode);
    setSearchQuery('');
    setIsOpen(false);
    inputRef.current?.focus();
  };

  const 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();
        setHighlightedIndex((prev) =>
          prev < filteredLanguages.length - 1 ? prev + 1 : prev
        );
        break;
      case 'ArrowUp':
        e.preventDefault();
        setHighlightedIndex((prev) => (prev > 0 ? prev - 1 : 0));
        break;
      case 'Enter':
        e.preventDefault();
        if (filteredLanguages[highlightedIndex]) {
          handleSelect(filteredLanguages[highlightedIndex][0]);
        }
        break;
      case 'Escape':
        setIsOpen(false);
        break;
    }
  };

  const getLanguageName = (code: string): string => {
    return languagesData?.languages[code] || code.toUpperCase();
  };

  if (error) {
    return (
      <div className="text-red-600 text-sm">
        Failed to load languages. Please try again.
      </div>
    );
  }

  return (
    <div>
      <label className="block text-sm font-medium text-gray-700 mb-2">
        Target Languages for Translation
      </label>

      {/* Selected Languages Tags */}
      {selectedLanguages.length > 0 && (
        <div className="flex flex-wrap gap-2 mb-3">
          {selectedLanguages.map((lang) => (
            <span
              key={lang}
              className="inline-flex items-center gap-1 bg-blue-100 text-blue-800 px-2.5 py-1 rounded-md text-sm"
            >
              {getLanguageName(lang)}
              <button
                type="button"
                onClick={() => onRemove(lang)}
                disabled={disabled}
                className="text-blue-600 hover:text-blue-800 disabled:opacity-50 disabled:cursor-not-allowed"
                aria-label={`Remove ${getLanguageName(lang)}`}
              >
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            </span>
          ))}
        </div>
      )}

      {/* Searchable Dropdown */}
      <div ref={containerRef} className="relative">
        <div className="flex gap-2">
          <div className="relative flex-1">
            <input
              ref={inputRef}
              type="text"
              value={searchQuery}
              onChange={(e) => {
                setSearchQuery(e.target.value);
                setIsOpen(true);
              }}
              onFocus={() => setIsOpen(true)}
              onKeyDown={handleKeyDown}
              disabled={disabled || isLoading || availableLanguages.length === 0}
              placeholder={
                isLoading
                  ? 'Loading languages...'
                  : availableLanguages.length === 0
                    ? 'All languages selected'
                    : 'Search languages...'
              }
              className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 disabled:bg-gray-100 disabled:cursor-not-allowed"
              aria-label="Search languages"
              aria-expanded={isOpen}
              aria-autocomplete="list"
            />
            {/* Dropdown arrow */}
            <button
              type="button"
              onClick={() => setIsOpen(!isOpen)}
              disabled={disabled || isLoading || availableLanguages.length === 0}
              className="absolute inset-y-0 right-0 flex items-center pr-2 disabled:cursor-not-allowed"
              tabIndex={-1}
            >
              <svg
                className={`w-5 h-5 text-gray-400 transition-transform ${isOpen ? 'rotate-180' : ''}`}
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
              </svg>
            </button>
          </div>
        </div>

        {/* Dropdown Panel */}
        {isOpen && filteredLanguages.length > 0 && (
          <ul
            className="absolute z-10 mt-1 w-full bg-white border border-gray-300 rounded-md shadow-lg max-h-60 overflow-auto"
            role="listbox"
          >
            {filteredLanguages.map(([code, name], index) => (
              <li
                key={code}
                role="option"
                aria-selected={index === highlightedIndex}
                className={`px-3 py-2 cursor-pointer ${
                  index === highlightedIndex
                    ? 'bg-blue-100 text-blue-900'
                    : 'hover:bg-gray-100'
                }`}
                onClick={() => handleSelect(code)}
                onMouseEnter={() => setHighlightedIndex(index)}
              >
                <span className="font-medium">{name}</span>
                <span className="text-gray-500 ml-2 text-sm">({code})</span>
              </li>
            ))}
          </ul>
        )}

        {/* No results message */}
        {isOpen && searchQuery && filteredLanguages.length === 0 && (
          <div className="absolute z-10 mt-1 w-full bg-white border border-gray-300 rounded-md shadow-lg px-3 py-2 text-gray-500 text-sm">
            No languages found matching "{searchQuery}"
          </div>
        )}
      </div>

      {/* Helper text */}
      <p className="mt-1 text-xs text-gray-500">
        {availableLanguages.length > 0
          ? `${availableLanguages.length} language${availableLanguages.length !== 1 ? 's' : ''} available`
          : selectedLanguages.length > 0
            ? 'All available languages have been selected'
            : ''}
      </p>
    </div>
  );
}
