import { useState, useEffect, useRef, useCallback } from 'react';
import { searchUsers, UserSearchResult } from '../api';
import './UserAutocomplete.css';

interface UserAutocompleteProps {
  value: string;
  onChange: (username: string) => void;
  placeholder?: string;
  disabled?: boolean;
  autoFocus?: boolean;
}

export function UserAutocomplete({
  value,
  onChange,
  placeholder = 'Search users...',
  disabled = false,
  autoFocus = false,
}: UserAutocompleteProps) {
  const [query, setQuery] = useState(value);
  const [results, setResults] = useState<UserSearchResult[]>([]);
  const [loading, setLoading] = useState(false);
  const [isOpen, setIsOpen] = useState(false);
  const [selectedIndex, setSelectedIndex] = useState(-1);
  const containerRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const debounceRef = useRef<ReturnType<typeof setTimeout>>();

  // Search for users with debounce
  const doSearch = useCallback(async (searchQuery: string) => {
    if (searchQuery.length < 1) {
      setResults([]);
      setIsOpen(false);
      return;
    }

    setLoading(true);
    try {
      const users = await searchUsers(searchQuery);
      setResults(users);
      setIsOpen(users.length > 0);
      setSelectedIndex(-1);
    } catch {
      setResults([]);
      setIsOpen(false);
    } finally {
      setLoading(false);
    }
  }, []);

  // Handle input change with debounce
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newValue = e.target.value;
    setQuery(newValue);
    onChange(newValue); // Update parent immediately for form validation

    // Debounce the search
    if (debounceRef.current) {
      clearTimeout(debounceRef.current);
    }
    debounceRef.current = setTimeout(() => {
      doSearch(newValue);
    }, 200);
  };

  // Handle selecting a user
  const handleSelect = (user: UserSearchResult) => {
    setQuery(user.username);
    onChange(user.username);
    setIsOpen(false);
    setResults([]);
    inputRef.current?.focus();
  };

  // Handle keyboard navigation
  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (!isOpen) return;

    switch (e.key) {
      case 'ArrowDown':
        e.preventDefault();
        setSelectedIndex(prev => (prev < results.length - 1 ? prev + 1 : prev));
        break;
      case 'ArrowUp':
        e.preventDefault();
        setSelectedIndex(prev => (prev > 0 ? prev - 1 : -1));
        break;
      case 'Enter':
        e.preventDefault();
        if (selectedIndex >= 0 && results[selectedIndex]) {
          handleSelect(results[selectedIndex]);
        }
        break;
      case 'Escape':
        setIsOpen(false);
        break;
    }
  };

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

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

  // Sync external value changes
  useEffect(() => {
    setQuery(value);
  }, [value]);

  // Cleanup debounce on unmount
  useEffect(() => {
    return () => {
      if (debounceRef.current) {
        clearTimeout(debounceRef.current);
      }
    };
  }, []);

  return (
    <div className="user-autocomplete" ref={containerRef}>
      <div className="user-autocomplete__input-wrapper">
        <input
          ref={inputRef}
          type="text"
          value={query}
          onChange={handleInputChange}
          onKeyDown={handleKeyDown}
          onFocus={() => query.length >= 1 && results.length > 0 && setIsOpen(true)}
          placeholder={placeholder}
          disabled={disabled}
          autoFocus={autoFocus}
          autoComplete="off"
          className="user-autocomplete__input"
        />
        {loading && (
          <div className="user-autocomplete__spinner" />
        )}
      </div>

      {isOpen && results.length > 0 && (
        <ul className="user-autocomplete__dropdown">
          {results.map((user, index) => (
            <li
              key={user.id}
              className={`user-autocomplete__option ${index === selectedIndex ? 'selected' : ''}`}
              onClick={() => handleSelect(user)}
              onMouseEnter={() => setSelectedIndex(index)}
            >
              <div className="user-autocomplete__avatar">
                {user.username.charAt(0).toUpperCase()}
              </div>
              <div className="user-autocomplete__user-info">
                <span className="user-autocomplete__username">{user.username}</span>
                {user.is_admin && (
                  <span className="user-autocomplete__admin-badge">Admin</span>
                )}
              </div>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}
