import { useState, useEffect } from 'react';
import { X, Search, Star, Swords, Users, Sparkles, ChevronLeft, ChevronRight, ExternalLink, Eye, EyeOff } from 'lucide-react';
import { Button, Input, Spinner } from '@/shared/components/ui';
import { api } from '@/shared/lib/api';
import type { Feat, FeatSearchResult, CharacterSkill, Proficiency } from '@/shared/types';

interface AddFeatModalProps {
  onClose: () => void;
  onAdd: (feat: {
    featId?: string;
    name: string;
    nameGerman?: string;
    level: number;
    source: 'CLASS' | 'ANCESTRY' | 'GENERAL' | 'SKILL' | 'BONUS' | 'ARCHETYPE';
  }) => Promise<void>;
  existingFeatNames: string[];
  characterLevel: number;
  characterClass?: string;
  characterAncestry?: string;
  characterSkills?: CharacterSkill[];
}

// Proficiency levels in order (for comparison)
const PROFICIENCY_ORDER: Proficiency[] = ['UNTRAINED', 'TRAINED', 'EXPERT', 'MASTER', 'LEGENDARY'];

// Check if character meets skill prerequisites
function checkSkillPrerequisites(
  prerequisites: string | undefined,
  skills: CharacterSkill[]
): { met: boolean; unmetReason?: string } {
  if (!prerequisites) return { met: true };

  const prereqLower = prerequisites.toLowerCase();

  // Patterns to check: "trained in X", "expert in X", "master in X", "legendary in X"
  const patterns = [
    { regex: /legendary in (\w+(?:\s+\w+)?)/gi, required: 'LEGENDARY' as Proficiency },
    { regex: /master in (\w+(?:\s+\w+)?)/gi, required: 'MASTER' as Proficiency },
    { regex: /expert in (\w+(?:\s+\w+)?)/gi, required: 'EXPERT' as Proficiency },
    { regex: /trained in (\w+(?:\s+\w+)?)/gi, required: 'TRAINED' as Proficiency },
  ];

  for (const { regex, required } of patterns) {
    let match;
    while ((match = regex.exec(prereqLower)) !== null) {
      const skillName = match[1].trim();

      // Skip non-skill prerequisites like "trained in armor" or "trained in light armor"
      if (skillName.includes('armor') || skillName.includes('weapon') || skillName.includes('spell')) {
        continue;
      }

      // Find the character's skill
      const characterSkill = skills.find(
        s => s.skillName.toLowerCase() === skillName ||
             s.skillName.toLowerCase().includes(skillName)
      );

      const characterProficiency = characterSkill?.proficiency || 'UNTRAINED';
      const requiredIndex = PROFICIENCY_ORDER.indexOf(required);
      const characterIndex = PROFICIENCY_ORDER.indexOf(characterProficiency);

      if (characterIndex < requiredIndex) {
        const requiredLabel = required.charAt(0) + required.slice(1).toLowerCase();
        return {
          met: false,
          unmetReason: `${requiredLabel} in ${skillName.charAt(0).toUpperCase() + skillName.slice(1)}`,
        };
      }
    }
  }

  return { met: true };
}

type FeatTypeFilter = 'all' | 'General' | 'Skill' | 'Class' | 'Ancestry' | 'Archetype';

const FEAT_TYPE_ICONS: Record<FeatTypeFilter, React.ReactNode> = {
  all: <Star className="h-4 w-4" />,
  General: <Star className="h-4 w-4" />,
  Skill: <Sparkles className="h-4 w-4" />,
  Class: <Swords className="h-4 w-4" />,
  Ancestry: <Users className="h-4 w-4" />,
  Archetype: <Star className="h-4 w-4" />,
};

const FEAT_TYPE_LABELS: Record<FeatTypeFilter, string> = {
  all: 'Alle',
  General: 'Allgemein',
  Skill: 'Fertigkeit',
  Class: 'Klasse',
  Ancestry: 'Abstammung',
  Archetype: 'Archetyp',
};

const FEAT_SOURCE_MAP: Record<string, 'CLASS' | 'ANCESTRY' | 'GENERAL' | 'SKILL' | 'BONUS' | 'ARCHETYPE'> = {
  General: 'GENERAL',
  Skill: 'SKILL',
  Class: 'CLASS',
  Ancestry: 'ANCESTRY',
  Archetype: 'ARCHETYPE',
  Heritage: 'ANCESTRY',
};

export function AddFeatModal({
  onClose,
  onAdd,
  existingFeatNames,
  characterLevel,
  characterClass,
  characterAncestry,
  characterSkills = [],
}: AddFeatModalProps) {
  const [searchQuery, setSearchQuery] = useState('');
  const [featType, setFeatType] = useState<FeatTypeFilter>('all');
  const [searchResult, setSearchResult] = useState<FeatSearchResult | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [selectedFeat, setSelectedFeat] = useState<Feat | null>(null);
  const [selectedSource, setSelectedSource] = useState<'CLASS' | 'ANCESTRY' | 'GENERAL' | 'SKILL' | 'BONUS' | 'ARCHETYPE'>('GENERAL');
  const [isAdding, setIsAdding] = useState(false);
  const [page, setPage] = useState(1);
  const [manualMode, setManualMode] = useState(false);
  const [manualFeatName, setManualFeatName] = useState('');
  const [showUnavailable, setShowUnavailable] = useState(false);

  // Search feats
  useEffect(() => {
    const searchFeats = async () => {
      setIsLoading(true);
      try {
        const result = await api.searchFeats({
          query: searchQuery || undefined,
          featType: featType !== 'all' ? featType : undefined,
          className: featType === 'Class' ? characterClass : undefined,
          ancestryName: featType === 'Ancestry' ? characterAncestry : undefined,
          maxLevel: characterLevel,
          page,
          limit: 30,
        });
        setSearchResult(result);
      } catch (error) {
        console.error('Failed to search feats:', error);
        // If the API fails (e.g., no feats in DB), show empty result
        setSearchResult({ items: [], total: 0, page: 1, limit: 30, totalPages: 0 });
      } finally {
        setIsLoading(false);
      }
    };

    const debounce = setTimeout(searchFeats, 300);
    return () => clearTimeout(debounce);
  }, [searchQuery, featType, characterLevel, characterClass, characterAncestry, page]);

  // Reset page when search/filter changes
  useEffect(() => {
    setPage(1);
  }, [searchQuery, featType]);

  // Update source when feat type changes
  useEffect(() => {
    if (featType !== 'all') {
      setSelectedSource(FEAT_SOURCE_MAP[featType] || 'GENERAL');
    }
  }, [featType]);

  const handleSelectFeat = (feat: Feat) => {
    setSelectedFeat(feat);
    setSelectedSource(FEAT_SOURCE_MAP[feat.featType || 'General'] || 'GENERAL');
  };

  const handleAdd = async () => {
    if (manualMode) {
      if (!manualFeatName.trim()) return;
      setIsAdding(true);
      try {
        await onAdd({
          name: manualFeatName.trim(),
          level: characterLevel,
          source: selectedSource,
        });
        onClose();
      } catch (error) {
        console.error('Failed to add feat:', error);
      } finally {
        setIsAdding(false);
      }
    } else {
      if (!selectedFeat) return;
      setIsAdding(true);
      try {
        await onAdd({
          featId: selectedFeat.id,
          name: selectedFeat.name,
          nameGerman: selectedFeat.nameGerman,
          level: characterLevel,
          source: selectedSource,
        });
        onClose();
      } catch (error) {
        console.error('Failed to add feat:', error);
      } finally {
        setIsAdding(false);
      }
    }
  };

  const isAlreadyOwned = (featName: string) =>
    existingFeatNames.some((n) => n.toLowerCase() === featName.toLowerCase());

  const getFeatTypeColor = (type?: string) => {
    switch (type) {
      case 'Class':
        return 'text-red-400';
      case 'Ancestry':
        return 'text-blue-400';
      case 'Skill':
        return 'text-green-400';
      case 'General':
        return 'text-yellow-400';
      case 'Archetype':
        return 'text-purple-400';
      default:
        return 'text-text-secondary';
    }
  };

  const getActionsDisplay = (actions?: string) => {
    if (!actions) return null;
    switch (actions) {
      case '1':
        return <span className="text-xs px-1.5 py-0.5 rounded bg-primary-500/20 text-primary-400">1 Aktion</span>;
      case '2':
        return <span className="text-xs px-1.5 py-0.5 rounded bg-primary-500/20 text-primary-400">2 Aktionen</span>;
      case '3':
        return <span className="text-xs px-1.5 py-0.5 rounded bg-primary-500/20 text-primary-400">3 Aktionen</span>;
      case 'free':
        return <span className="text-xs px-1.5 py-0.5 rounded bg-green-500/20 text-green-400">Freie Aktion</span>;
      case 'reaction':
        return <span className="text-xs px-1.5 py-0.5 rounded bg-yellow-500/20 text-yellow-400">Reaktion</span>;
      default:
        return null;
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-end sm:items-center justify-center">
      {/* Backdrop */}
      <div className="absolute inset-0 bg-black/60" onClick={onClose} />

      {/* Modal */}
      <div className="relative w-full sm:max-w-2xl max-h-[90vh] bg-bg-secondary rounded-t-2xl sm:rounded-2xl flex flex-col overflow-hidden">
        {/* Header */}
        <div className="flex items-center justify-between p-4 border-b border-border">
          <h2 className="text-lg font-semibold text-text-primary">
            {selectedFeat || manualMode ? 'Talent hinzufügen' : 'Talent suchen'}
          </h2>
          <Button variant="ghost" size="icon" onClick={onClose}>
            <X className="h-5 w-5" />
          </Button>
        </div>

        {selectedFeat ? (
          // Selected feat detail view
          <div className="flex-1 overflow-y-auto p-4 space-y-4">
            <button
              onClick={() => setSelectedFeat(null)}
              className="text-sm text-primary-500 hover:text-primary-400"
            >
              &larr; Zurück zur Suche
            </button>

            <div className="p-4 rounded-xl bg-bg-tertiary">
              <div className="flex items-start justify-between gap-2">
                <div>
                  <h3 className="font-semibold text-text-primary text-lg">
                    {selectedFeat.nameGerman || selectedFeat.name}
                  </h3>
                  {selectedFeat.nameGerman && (
                    <p className="text-sm text-text-muted">{selectedFeat.name}</p>
                  )}
                </div>
                {getActionsDisplay(selectedFeat.actions)}
              </div>

              <div className="mt-2 flex flex-wrap gap-2">
                <span className={`text-sm ${getFeatTypeColor(selectedFeat.featType)}`}>
                  {selectedFeat.featType || 'Allgemein'}
                </span>
                {selectedFeat.level && (
                  <span className="text-sm text-text-secondary">
                    Level {selectedFeat.level}+
                  </span>
                )}
                {selectedFeat.rarity && selectedFeat.rarity !== 'Common' && (
                  <span className={`text-xs px-1.5 py-0.5 rounded ${
                    selectedFeat.rarity === 'Uncommon' ? 'bg-orange-500/20 text-orange-400' :
                    selectedFeat.rarity === 'Rare' ? 'bg-blue-500/20 text-blue-400' :
                    'bg-purple-500/20 text-purple-400'
                  }`}>
                    {selectedFeat.rarity}
                  </span>
                )}
              </div>

              {/* Prerequisites */}
              {selectedFeat.prerequisites && (
                <div className="mt-3 text-sm">
                  <span className="text-text-secondary">Voraussetzungen: </span>
                  <span className="text-text-primary">{selectedFeat.prerequisites}</span>
                </div>
              )}

              {/* Traits */}
              {selectedFeat.traits.length > 0 && (
                <div className="mt-3 flex flex-wrap gap-1">
                  {selectedFeat.traits.map((trait) => (
                    <span
                      key={trait}
                      className="px-2 py-0.5 text-xs rounded bg-primary-500/20 text-primary-400"
                    >
                      {trait}
                    </span>
                  ))}
                </div>
              )}

              {/* Summary */}
              {selectedFeat.summary && (
                <p className="mt-3 text-sm text-text-secondary leading-relaxed">
                  {selectedFeat.summaryGerman || selectedFeat.summary}
                </p>
              )}

              {/* Description */}
              {selectedFeat.description && (
                <div className="mt-3 pt-3 border-t border-border">
                  <p className="text-sm text-text-primary leading-relaxed">
                    {selectedFeat.description}
                  </p>
                </div>
              )}

              {/* Archives of Nethys Link */}
              {selectedFeat.url && (
                <a
                  href={`https://2e.aonprd.com${selectedFeat.url}`}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="mt-3 flex items-center gap-2 text-sm text-primary-400 hover:text-primary-300"
                >
                  <ExternalLink className="h-4 w-4" />
                  Auf Archives of Nethys anzeigen
                </a>
              )}
            </div>

            <Button
              className="w-full h-12"
              onClick={handleAdd}
              disabled={isAdding}
            >
              {isAdding ? 'Wird hinzugefügt...' : `${selectedFeat.nameGerman || selectedFeat.name} hinzufügen`}
            </Button>
          </div>
        ) : manualMode ? (
          // Manual entry mode
          <div className="flex-1 overflow-y-auto p-4 space-y-4">
            <button
              onClick={() => setManualMode(false)}
              className="text-sm text-primary-500 hover:text-primary-400"
            >
              &larr; Zurück zur Suche
            </button>

            <div className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-text-primary mb-1.5">
                  Talent Name
                </label>
                <Input
                  value={manualFeatName}
                  onChange={(e) => setManualFeatName(e.target.value)}
                  placeholder="Name des Talents eingeben..."
                  autoFocus
                />
              </div>

              <div className="space-y-2">
                <label className="text-sm font-medium text-text-primary">Typ</label>
                <div className="flex flex-wrap gap-2">
                  {(['CLASS', 'ANCESTRY', 'GENERAL', 'SKILL', 'ARCHETYPE', 'BONUS'] as const).map((src) => (
                    <button
                      key={src}
                      onClick={() => setSelectedSource(src)}
                      className={`px-3 py-1.5 rounded-lg text-sm font-medium transition-colors ${
                        selectedSource === src
                          ? 'bg-primary-500 text-white'
                          : 'bg-bg-tertiary text-text-secondary hover:bg-bg-elevated'
                      }`}
                    >
                      {src === 'CLASS' ? 'Klasse' :
                       src === 'ANCESTRY' ? 'Abstammung' :
                       src === 'GENERAL' ? 'Allgemein' :
                       src === 'SKILL' ? 'Fertigkeit' :
                       src === 'ARCHETYPE' ? 'Archetyp' : 'Bonus'}
                    </button>
                  ))}
                </div>
              </div>
            </div>

            <Button
              className="w-full h-12"
              onClick={handleAdd}
              disabled={isAdding || !manualFeatName.trim()}
            >
              {isAdding ? 'Wird hinzugefügt...' : 'Talent hinzufügen'}
            </Button>
          </div>
        ) : (
          // Search view
          <>
            {/* Search */}
            <div className="p-4 border-b border-border space-y-3">
              <div className="relative">
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" />
                <Input
                  placeholder="Nach Talent suchen..."
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  className="pl-10"
                  autoFocus
                />
              </div>

              {/* Type Filter */}
              <div className="flex gap-1 overflow-x-auto pb-1">
                {(Object.keys(FEAT_TYPE_LABELS) as FeatTypeFilter[]).map((type) => (
                  <button
                    key={type}
                    onClick={() => setFeatType(type)}
                    className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-medium whitespace-nowrap transition-colors ${
                      featType === type
                        ? 'bg-primary-500 text-white'
                        : 'bg-bg-tertiary text-text-secondary hover:bg-bg-elevated hover:text-text-primary'
                    }`}
                  >
                    {FEAT_TYPE_ICONS[type]}
                    {FEAT_TYPE_LABELS[type]}
                  </button>
                ))}
              </div>
            </div>

            {/* Toggle for unavailable feats */}
            <div className="px-4 pb-2">
              <button
                onClick={() => setShowUnavailable(!showUnavailable)}
                className="flex items-center gap-2 text-sm text-text-secondary hover:text-text-primary"
              >
                {showUnavailable ? (
                  <Eye className="h-4 w-4" />
                ) : (
                  <EyeOff className="h-4 w-4" />
                )}
                {showUnavailable ? 'Nicht erlernbare ausblenden' : 'Nicht erlernbare anzeigen'}
              </button>
            </div>

            {/* Results */}
            <div className="flex-1 overflow-y-auto p-4 pt-0">
              {isLoading ? (
                <div className="flex items-center justify-center py-8">
                  <Spinner />
                </div>
              ) : !searchResult?.items.length ? (
                <div className="text-center py-8 space-y-4">
                  <p className="text-text-secondary">
                    {searchResult?.total === 0
                      ? 'Keine Talente in der Datenbank gefunden.'
                      : 'Keine passenden Talente gefunden.'}
                  </p>
                  <Button variant="outline" onClick={() => setManualMode(true)}>
                    Talent manuell hinzufügen
                  </Button>
                </div>
              ) : (
                <div className="space-y-2">
                  {searchResult.items.map((feat) => {
                    const owned = isAlreadyOwned(feat.name);
                    const prereqCheck = checkSkillPrerequisites(feat.prerequisites, characterSkills);
                    const isUnavailable = !prereqCheck.met;

                    // Hide unavailable feats if toggle is off
                    if (isUnavailable && !showUnavailable) {
                      return null;
                    }

                    const isDisabled = owned || isUnavailable;

                    return (
                      <button
                        key={feat.id}
                        onClick={() => !isDisabled && handleSelectFeat(feat)}
                        disabled={isDisabled}
                        className={`w-full text-left p-3 rounded-lg transition-colors ${
                          isDisabled
                            ? 'bg-bg-tertiary/50 opacity-50 cursor-not-allowed'
                            : 'bg-bg-tertiary hover:bg-bg-elevated'
                        }`}
                      >
                        <div className="flex items-start justify-between gap-2">
                          <div className="min-w-0 flex-1">
                            <div className="flex items-center gap-2">
                              <p className={`font-medium truncate ${isDisabled ? 'text-text-muted' : 'text-text-primary'}`}>
                                {feat.nameGerman || feat.name}
                              </p>
                              {getActionsDisplay(feat.actions)}
                            </div>
                            <p className={`text-xs ${isDisabled ? 'text-text-muted' : getFeatTypeColor(feat.featType)}`}>
                              {feat.featType || 'Allgemein'}
                              {feat.level && ` • Level ${feat.level}+`}
                              {feat.className && ` • ${feat.className}`}
                              {feat.ancestryName && ` • ${feat.ancestryName}`}
                            </p>
                          </div>
                          {owned && (
                            <span className="text-xs text-text-muted flex-shrink-0">Bereits vorhanden</span>
                          )}
                          {isUnavailable && !owned && (
                            <span className="text-xs text-orange-400 flex-shrink-0">
                              {prereqCheck.unmetReason}
                            </span>
                          )}
                        </div>
                      </button>
                    );
                  })}
                </div>
              )}

              {/* Manual add button at bottom */}
              {searchResult && searchResult.items.length > 0 && (
                <div className="mt-4 pt-4 border-t border-border text-center">
                  <Button variant="outline" onClick={() => setManualMode(true)}>
                    Talent manuell hinzufügen
                  </Button>
                </div>
              )}
            </div>

            {/* Pagination */}
            {searchResult && searchResult.totalPages > 1 && (
              <div className="flex items-center justify-between p-4 border-t border-border">
                <span className="text-sm text-text-secondary">
                  {searchResult.total} Ergebnisse
                </span>
                <div className="flex items-center gap-2">
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setPage((p) => Math.max(1, p - 1))}
                    disabled={page <= 1}
                  >
                    <ChevronLeft className="h-4 w-4" />
                  </Button>
                  <span className="text-sm text-text-primary">
                    {page} / {searchResult.totalPages}
                  </span>
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setPage((p) => Math.min(searchResult.totalPages, p + 1))}
                    disabled={page >= searchResult.totalPages}
                  >
                    <ChevronRight className="h-4 w-4" />
                  </Button>
                </div>
              </div>
            )}
          </>
        )}
      </div>
    </div>
  );
}
