'use client';

import { useState, useRef, useEffect } from 'react';
import { createPortal } from 'react-dom';
import { Tag } from '@/lib/types';
import { useTagsAutocomplete } from '@/hooks/useTags';
import { tagsClient } from '@/clients/tags-client';
import { Badge } from './Badge';

interface TagInputProps {
  tags: string[];
  onChange: (tags: string[]) => void;
  primaryTagId?: string;
  onPrimaryTagChange?: (tagId: string | undefined) => void;
  placeholder?: string;
  maxTags?: number;
  className?: string;
  compactSuggestions?: boolean; // Pour adapter selon l'espace
}

export function TagInput({
  tags,
  onChange,
  primaryTagId,
  onPrimaryTagChange,
  placeholder = 'Ajouter des tags...',
  maxTags = 10,
  className = '',
  compactSuggestions = false,
}: TagInputProps) {
  const [inputValue, setInputValue] = useState('');
  const [showSuggestions, setShowSuggestions] = useState(false);
  const [selectedIndex, setSelectedIndex] = useState(-1);
  const [hasLoadedPopularTags, setHasLoadedPopularTags] = useState(false);
  const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 });
  const [positionCalculated, setPositionCalculated] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const suggestionsRef = useRef<HTMLDivElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  const {
    suggestions,
    loading,
    searchTags,
    clearSuggestions,
    loadPopularTags,
  } = useTagsAutocomplete();
  const [allTags, setAllTags] = useState<Tag[]>([]);

  // Calculer la position du dropdown (copié du composant Dropdown)
  const calculatePosition = () => {
    if (!containerRef.current) return;

    const rect = containerRef.current.getBoundingClientRect();

    // Placement bottom-start (comme dans Dropdown)
    const top = rect.bottom + 4;
    const left = rect.left;

    setDropdownPosition({ top, left });
    setPositionCalculated(true);
  };

  // Charger tous les tags au début pour pouvoir identifier le tag prioritaire
  useEffect(() => {
    const loadTags = async () => {
      try {
        const response = await tagsClient.getPopularTags(100);
        setAllTags(response.data);
      } catch (error) {
        console.error('Erreur lors du chargement des tags:', error);
        setAllTags([]);
      }
    };
    loadTags();
  }, []);

  // Mettre à jour la position quand le dropdown s'ouvre (comme dans Dropdown)
  useEffect(() => {
    if (showSuggestions) {
      setPositionCalculated(false);
      calculatePosition();
    } else {
      setPositionCalculated(false);
    }
  }, [showSuggestions]);

  // Rechercher des suggestions quand l'input change
  useEffect(() => {
    if (inputValue.trim()) {
      searchTags(inputValue);
      setShowSuggestions(true);
      setSelectedIndex(-1);
      setHasLoadedPopularTags(false); // Reset flag when typing
    } else {
      clearSuggestions();
      // Only hide suggestions if we haven't just loaded popular tags
      if (!hasLoadedPopularTags) {
        setShowSuggestions(false);
      }
    }
  }, [inputValue, searchTags, clearSuggestions, hasLoadedPopularTags]);

  // Gérer le clic extérieur pour fermer les suggestions
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (
        showSuggestions &&
        containerRef.current &&
        !containerRef.current.contains(event.target as Node) &&
        suggestionsRef.current &&
        !suggestionsRef.current.contains(event.target as Node)
      ) {
        setShowSuggestions(false);
        setSelectedIndex(-1);
      }
    };

    if (showSuggestions) {
      document.addEventListener('mousedown', handleClickOutside);
    }

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

  const addTag = (tagName: string) => {
    const trimmedTag = tagName.trim();
    if (trimmedTag && !tags.includes(trimmedTag) && tags.length < maxTags) {
      onChange([...tags, trimmedTag]);
    }
    setInputValue('');
    setShowSuggestions(false);
    setSelectedIndex(-1);
  };

  const removeTag = (tagToRemove: string) => {
    onChange(tags.filter((tag) => tag !== tagToRemove));
    // Si on supprime le tag prioritaire, le désélectionner
    if (primaryTagId && onPrimaryTagChange && allTags) {
      const tagToRemoveObj = allTags.find((tag) => tag.name === tagToRemove);
      if (tagToRemoveObj && tagToRemoveObj.id === primaryTagId) {
        onPrimaryTagChange(undefined);
      }
    }
  };

  const handleTagClick = (tagName: string) => {
    if (!onPrimaryTagChange || !allTags) return;

    const tagObj = allTags.find((tag) => tag.name === tagName);
    if (!tagObj) return;

    if (primaryTagId === tagObj.id) {
      // Désélectionner si c'est déjà sélectionné
      onPrimaryTagChange(undefined);
    } else {
      // Sélectionner comme prioritaire
      onPrimaryTagChange(tagObj.id);
    }
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      if (selectedIndex >= 0 && suggestions[selectedIndex]) {
        addTag(suggestions[selectedIndex].name);
      } else if (inputValue.trim()) {
        addTag(inputValue);
      }
    } else if (e.key === 'Escape') {
      setShowSuggestions(false);
      setSelectedIndex(-1);
    } else if (e.key === 'ArrowDown') {
      e.preventDefault();
      setSelectedIndex((prev) =>
        prev < suggestions.length - 1 ? prev + 1 : prev
      );
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      setSelectedIndex((prev) => (prev > 0 ? prev - 1 : -1));
    } else if (e.key === 'Backspace' && !inputValue && tags.length > 0) {
      // Supprimer le dernier tag si l'input est vide
      removeTag(tags[tags.length - 1]);
    }
  };

  const handleSuggestionClick = (tag: Tag) => {
    addTag(tag.name);
  };

  const handleFocus = () => {
    if (inputValue.trim()) {
      // Si il y a du texte, afficher les suggestions existantes
      setShowSuggestions(true);
    } else {
      // Si l'input est vide, charger les tags populaires
      setHasLoadedPopularTags(true);
      loadPopularTags(20);
      setShowSuggestions(true);
    }
    setSelectedIndex(-1);
  };

  return (
    <div ref={containerRef} className={`relative ${className}`}>
      {/* Container des tags et input */}
      <div className="min-h-[42px] p-2 border border-[var(--border)] rounded-lg bg-[var(--input)] focus-within:border-[var(--primary)] focus-within:ring-1 focus-within:ring-[var(--primary)]/20 transition-colors">
        <div className="flex flex-wrap gap-1 items-center">
          {/* Tags existants */}
          {tags.map((tag, index) => {
            const tagObj = allTags?.find((t) => t.name === tag);
            const isPrimary = tagObj && primaryTagId === tagObj.id;

            return (
              <Badge
                key={index}
                variant="default"
                className={`flex items-center gap-1 px-2 py-1 text-xs transition-all ${
                  isPrimary
                    ? 'ring-2 ring-[var(--primary)] bg-[var(--primary)]/10'
                    : onPrimaryTagChange
                      ? 'cursor-pointer hover:ring-1 hover:ring-[var(--primary)]/50'
                      : ''
                }`}
                onClick={
                  onPrimaryTagChange ? () => handleTagClick(tag) : undefined
                }
                title={
                  onPrimaryTagChange
                    ? isPrimary
                      ? 'Tag prioritaire (cliquer pour désélectionner)'
                      : 'Cliquer pour sélectionner comme prioritaire'
                    : undefined
                }
              >
                <span>{tag}</span>
                {isPrimary && (
                  <span className="text-[var(--primary)] font-bold">★</span>
                )}
                <button
                  type="button"
                  onClick={(e) => {
                    e.stopPropagation();
                    removeTag(tag);
                  }}
                  className="text-[var(--muted-foreground)] hover:text-[var(--foreground)] ml-1"
                  aria-label={`Supprimer le tag ${tag}`}
                >
                  ×
                </button>
              </Badge>
            );
          })}

          {/* Input pour nouveau tag */}
          {tags.length < maxTags && (
            <input
              ref={inputRef}
              type="text"
              value={inputValue}
              onChange={(e) => setInputValue(e.target.value)}
              onKeyDown={handleKeyDown}
              onFocus={handleFocus}
              placeholder={tags.length === 0 ? placeholder : ''}
              className="flex-1 min-w-[120px] bg-transparent border-none outline-none text-[var(--foreground)] placeholder-[var(--muted-foreground)] text-sm"
            />
          )}
        </div>
      </div>

      {/* Suggestions dropdown */}
      {showSuggestions &&
        (suggestions.length > 0 || loading) &&
        positionCalculated &&
        typeof window !== 'undefined' &&
        createPortal(
          <div
            ref={suggestionsRef}
            className="fixed z-[99999] max-h-64 overflow-y-auto rounded-xl border border-[var(--border)]/60 bg-[var(--card)]/80 backdrop-blur-xl shadow-2xl shadow-[var(--card-shadow-medium)]"
            style={{
              top: `${dropdownPosition.top}px`,
              left: `${dropdownPosition.left}px`,
            }}
          >
            {loading ? (
              <div className="p-3 text-center text-[var(--muted-foreground)] text-sm">
                Recherche...
              </div>
            ) : (
              <div
                className={`gap-2 p-3 ${compactSuggestions ? 'grid grid-cols-1' : 'grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4'}`}
              >
                {suggestions.map((tag, index) => (
                  <button
                    key={tag.id}
                    type="button"
                    onClick={() => handleSuggestionClick(tag)}
                    className={`flex items-center gap-2 px-2 py-1.5 text-xs rounded-md transition-colors border ${
                      index === selectedIndex
                        ? 'bg-[var(--primary)]/15 text-[var(--primary)] ring-1 ring-[var(--primary)]/40 border-[var(--primary)]/40 backdrop-blur-sm'
                        : 'text-[var(--foreground)] border-transparent hover:bg-[var(--card)]/40 hover:border-[var(--border)]/40 backdrop-blur-sm'
                    } ${tags.includes(tag.name) ? 'opacity-50 cursor-not-allowed' : ''}`}
                    disabled={tags.includes(tag.name)}
                    title={
                      tags.includes(tag.name)
                        ? 'Déjà ajouté'
                        : `Ajouter ${tag.name}`
                    }
                  >
                    <div
                      className="w-2 h-2 rounded-full flex-shrink-0"
                      style={{ backgroundColor: tag.color }}
                    />
                    <span className="truncate text-[var(--foreground)]">
                      {tag.name}
                    </span>
                    {tags.includes(tag.name) && (
                      <span className="text-[var(--muted-foreground)] ml-auto">
                        ✓
                      </span>
                    )}
                  </button>
                ))}
              </div>
            )}
          </div>,
          document.body
        )}

      {/* Indicateur de limite */}
      {tags.length >= maxTags && (
        <div className="text-xs text-[var(--muted-foreground)] mt-1">
          Limite de {maxTags} tags atteinte
        </div>
      )}
    </div>
  );
}
