import React, { useState, useEffect, useRef } from 'react';
import { forumAPI } from '../services/api';

interface TagInputProps {
  selectedTags: string[];
  onChange: (tags: string[]) => void;
  placeholder?: string;
}

const TagInput: React.FC<TagInputProps> = ({
  selectedTags,
  onChange,
  placeholder = 'Add tags...',
}) => {
  const [inputValue, setInputValue] = useState('');
  const [suggestions, setSuggestions] = useState<string[]>([]);
  const [showSuggestions, setShowSuggestions] = useState(false);
  const [activeSuggestion, setActiveSuggestion] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);
  const suggestionsRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const fetchSuggestions = async () => {
      if (inputValue.length >= 2) {
        try {
          const response = await forumAPI.getTags({ search: inputValue });
          const tags = response.data.map((tag: any) => tag.tagName);
          setSuggestions(tags.filter((tag: string) => !selectedTags.includes(tag)));
          setShowSuggestions(true);
        } catch (error) {
          console.error('Failed to fetch tag suggestions:', error);
        }
      } else {
        setSuggestions([]);
        setShowSuggestions(false);
      }
    };

    const debounceTimer = setTimeout(fetchSuggestions, 300);
    return () => clearTimeout(debounceTimer);
  }, [inputValue, selectedTags]);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (
        suggestionsRef.current &&
        !suggestionsRef.current.contains(event.target as Node) &&
        inputRef.current &&
        !inputRef.current.contains(event.target as Node)
      ) {
        setShowSuggestions(false);
      }
    };

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

  const addTag = (tag: string) => {
    const normalizedTag = tag.toLowerCase().trim();
    if (normalizedTag && !selectedTags.includes(normalizedTag)) {
      onChange([...selectedTags, normalizedTag]);
      setInputValue('');
      setSuggestions([]);
      setShowSuggestions(false);
      setActiveSuggestion(0);
    }
  };

  const removeTag = (tagToRemove: string) => {
    onChange(selectedTags.filter((tag) => tag !== tagToRemove));
  };

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      if (showSuggestions && suggestions.length > 0 && activeSuggestion < suggestions.length) {
        addTag(suggestions[activeSuggestion]);
      } else if (inputValue.trim()) {
        addTag(inputValue);
      }
    } else if (e.key === 'ArrowDown') {
      e.preventDefault();
      setActiveSuggestion((prev) => Math.min(prev + 1, suggestions.length - 1));
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      setActiveSuggestion((prev) => Math.max(prev - 1, 0));
    } else if (e.key === 'Escape') {
      setShowSuggestions(false);
    } else if (e.key === 'Backspace' && !inputValue && selectedTags.length > 0) {
      removeTag(selectedTags[selectedTags.length - 1]);
    }
  };

  return (
    <div className="tag-input-container">
      <div className="form-control d-flex flex-wrap gap-1 p-2" style={{ minHeight: '45px' }}>
        {selectedTags.map((tag) => (
          <span key={tag} className="badge bg-primary d-flex align-items-center gap-1">
            #{tag}
            <button
              type="button"
              className="btn-close btn-close-white"
              style={{ fontSize: '0.6rem' }}
              onClick={() => removeTag(tag)}
              aria-label="Remove tag"
            ></button>
          </span>
        ))}
        <input
          ref={inputRef}
          type="text"
          className="border-0 flex-grow-1"
          style={{ outline: 'none', minWidth: '150px' }}
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
          onKeyDown={handleKeyDown}
          onFocus={() => {
            if (suggestions.length > 0) setShowSuggestions(true);
          }}
          placeholder={selectedTags.length === 0 ? placeholder : ''}
        />
      </div>

      {showSuggestions && suggestions.length > 0 && (
        <div
          ref={suggestionsRef}
          className="list-group position-absolute w-100 shadow-sm"
          style={{ zIndex: 1000, maxHeight: '200px', overflowY: 'auto' }}
        >
          {suggestions.map((suggestion, index) => (
            <button
              key={suggestion}
              type="button"
              className={`list-group-item list-group-item-action ${
                index === activeSuggestion ? 'active' : ''
              }`}
              onClick={() => addTag(suggestion)}
              onMouseEnter={() => setActiveSuggestion(index)}
            >
              #{suggestion}
            </button>
          ))}
        </div>
      )}

      <small className="form-text text-muted">
        Press Enter to add a tag. Use letters, numbers, and hyphens only.
      </small>
    </div>
  );
};

export default TagInput;
