import React, { useState, useEffect, useRef, useCallback } from 'react';
import TextField, { BaseTextFieldProps } from '../TextField/TextField';
import { autocompleteAddress, AddressSuggestion } from '../../../api/realEstateApi';
import styles from './AddressAutocomplete.module.css';

interface AddressAutocompleteProps extends BaseTextFieldProps {
  onSelect?: (suggestion: AddressSuggestion) => void;
  debounceMs?: number;
  minQueryLength?: number;
  maxSuggestions?: number;
}

const AddressAutocomplete: React.FC<AddressAutocompleteProps> = ({
  value = '',
  onChange,
  onSelect,
  placeholder,
  disabled = false,
  required = false,
  readonly = false,
  size = 'md',
  error,
  helperText,
  label,
  className = '',
  type = 'text',
  name,
  id,
  onKeyDown,
  debounceMs = 300,
  minQueryLength = 2,
  maxSuggestions = 10,
  ...props
}) => {
  const [suggestions, setSuggestions] = useState<AddressSuggestion[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [selectedIndex, setSelectedIndex] = useState(-1);
  const [showSuggestions, setShowSuggestions] = useState(false);
  const [query, setQuery] = useState(value);
  const [autocompleteError, setAutocompleteError] = useState<string | null>(null);
  
  const containerRef = useRef<HTMLDivElement>(null);
  const suggestionsRef = useRef<HTMLUListElement>(null);
  const debounceTimerRef = useRef<NodeJS.Timeout | null>(null);

  // Sync query with value prop
  useEffect(() => {
    setQuery(value);
  }, [value]);

  // Debounced search function
  const performSearch = useCallback(async (searchQuery: string) => {
    if (searchQuery.length < minQueryLength) {
      if (import.meta.env.DEV) {
        console.log('🔍 [AddressAutocomplete] Query too short:', {
          query: searchQuery,
          length: searchQuery.length,
          minLength: minQueryLength
        });
      }
      setSuggestions([]);
      setShowSuggestions(false);
      setIsLoading(false);
      return;
    }

    if (import.meta.env.DEV) {
      console.log('🔍 [AddressAutocomplete] Starting search:', {
        query: searchQuery,
        length: searchQuery.length,
        maxSuggestions: maxSuggestions
      });
    }

    setIsLoading(true);
    setAutocompleteError(null); // Clear previous errors
    try {
      const results = await autocompleteAddress(searchQuery, maxSuggestions);
      
      if (import.meta.env.DEV) {
        console.log('✅ [AddressAutocomplete] Search completed:', {
          query: searchQuery,
          resultCount: results.length,
          results: results.slice(0, 3) // Log first 3
        });
      }

      setSuggestions(results);
      setShowSuggestions(results.length > 0 || true); // Show dropdown even if empty to show "no results" or error
      setSelectedIndex(-1);
      setAutocompleteError(null); // Clear any previous errors on success
    } catch (err: any) {
      console.error('❌ [AddressAutocomplete] Error in performSearch:', err);
      const errorMessage = err?.response?.data?.detail || err?.message || 'Fehler beim Laden der Adressvorschläge';
      setAutocompleteError(errorMessage);
      setSuggestions([]);
      setShowSuggestions(true); // Show dropdown to display error
      setSelectedIndex(-1);
    } finally {
      setIsLoading(false);
    }
  }, [minQueryLength, maxSuggestions]);

  // Handle input change with debouncing
  const handleInputChange = useCallback((newValue: string) => {
    if (import.meta.env.DEV) {
      console.log('⌨️ [AddressAutocomplete] Input changed:', {
        newValue: newValue,
        length: newValue.length,
        willSearch: newValue.length >= minQueryLength
      });
    }

    setQuery(newValue);
    setAutocompleteError(null); // Clear error on new input
    
    // Update parent component immediately
    if (onChange) {
      onChange(newValue);
    }

    // Clear existing timer
    if (debounceTimerRef.current) {
      clearTimeout(debounceTimerRef.current);
    }

    // Set new timer for debounced search
    debounceTimerRef.current = setTimeout(() => {
      if (import.meta.env.DEV) {
        console.log('⏱️ [AddressAutocomplete] Debounce timer fired, calling performSearch');
      }
      performSearch(newValue);
    }, debounceMs);
  }, [onChange, debounceMs, performSearch, minQueryLength]);

  // Handle suggestion selection
  const handleSelectSuggestion = useCallback((suggestion: AddressSuggestion) => {
    setQuery(suggestion.value);
    setShowSuggestions(false);
    setSelectedIndex(-1);
    
    if (onChange) {
      onChange(suggestion.value);
    }
    
    if (onSelect) {
      onSelect(suggestion);
    }
  }, [onChange, onSelect]);

  // Handle keyboard navigation
  const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    if (!showSuggestions || suggestions.length === 0) {
      if (onKeyDown) {
        onKeyDown(e);
      }
      return;
    }

    switch (e.key) {
      case 'ArrowDown':
        e.preventDefault();
        setSelectedIndex(prev => 
          prev < suggestions.length - 1 ? prev + 1 : prev
        );
        break;
      case 'ArrowUp':
        e.preventDefault();
        setSelectedIndex(prev => prev > 0 ? prev - 1 : -1);
        break;
      case 'Enter':
        if (selectedIndex >= 0 && selectedIndex < suggestions.length) {
          e.preventDefault();
          handleSelectSuggestion(suggestions[selectedIndex]);
        } else if (onKeyDown) {
          onKeyDown(e);
        }
        break;
      case 'Escape':
        e.preventDefault();
        setShowSuggestions(false);
        setSelectedIndex(-1);
        break;
      default:
        if (onKeyDown) {
          onKeyDown(e);
        }
    }
  }, [showSuggestions, suggestions, selectedIndex, handleSelectSuggestion, onKeyDown]);

  // Click outside handler
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setShowSuggestions(false);
        setSelectedIndex(-1);
      }
    };

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

  // Scroll selected item into view
  useEffect(() => {
    if (selectedIndex >= 0 && suggestionsRef.current) {
      const selectedElement = suggestionsRef.current.children[selectedIndex] as HTMLElement;
      if (selectedElement) {
        selectedElement.scrollIntoView({
          block: 'nearest',
          behavior: 'smooth'
        });
      }
    }
  }, [selectedIndex]);

  // Highlight matching text in suggestion
  const highlightText = (text: string, query: string): React.ReactNode => {
    if (!query || query.length < minQueryLength) {
      return text;
    }

    const parts = text.split(new RegExp(`(${query})`, 'gi'));
    return (
      <>
        {parts.map((part, index) => 
          part.toLowerCase() === query.toLowerCase() ? (
            <mark key={index} className={styles.highlight}>{part}</mark>
          ) : (
            <span key={index}>{part}</span>
          )
        )}
      </>
    );
  };

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

  return (
    <div ref={containerRef} className={`${styles.autocompleteContainer} ${className}`}>
      <TextField
        value={query}
        onChange={handleInputChange}
        placeholder={placeholder}
        disabled={disabled}
        required={required}
        readonly={readonly}
        size={size}
        error={undefined}
        helperText={helperText}
        label={label}
        type={type}
        name={name}
        id={id}
        onKeyDown={handleKeyDown}
        {...props}
      />
      
      {showSuggestions && (
        <div className={styles.suggestionsWrapper}>
          <ul ref={suggestionsRef} className={styles.suggestionsList}>
            {isLoading && (
              <li className={styles.suggestionItem}>
                <span className={styles.loadingText}>Suche Adressen...</span>
              </li>
            )}
            {!isLoading && autocompleteError && (
              <li className={styles.suggestionItem}>
                <span className={styles.errorText}>{autocompleteError}</span>
              </li>
            )}
            {!isLoading && !autocompleteError && suggestions.length === 0 && query.length >= minQueryLength && (
              <li className={styles.suggestionItem}>
                <span className={styles.noResultsText}>Keine Adressen gefunden</span>
              </li>
            )}
            {!isLoading && suggestions.map((suggestion, index) => (
              <li
                key={`${suggestion.value}-${index}`}
                className={`${styles.suggestionItem} ${
                  index === selectedIndex ? styles.suggestionItemSelected : ''
                }`}
                onClick={() => handleSelectSuggestion(suggestion)}
                onMouseEnter={() => setSelectedIndex(index)}
              >
                <span className={styles.suggestionText}>
                  {highlightText(suggestion.label, query)}
                </span>
              </li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
};

export default AddressAutocomplete;
