import { useState, useEffect } from 'react';
import {
  FlaskConical,
  Plus,
  Minus,
  RefreshCw,
  Beaker,
  BookOpen,
  Sparkles,
  Zap,
  Loader2,
  Search,
  X,
  Check,
  Trash2,
  Hammer,
  ChevronDown,
  ChevronUp,
} from 'lucide-react';
import {
  Button,
  Card,
  CardHeader,
  CardTitle,
  CardContent,
} from '@/shared/components/ui';
import { ActionIcon } from '@/shared/components/ui/action-icon';
import { api } from '@/shared/lib/api';
import type {
  Character,
  CharacterAlchemyState,
  CharacterFormula,
  CharacterPreparedItem,
  Equipment,
  AvailableFormula,
} from '@/shared/types';

// Research field translations and colors
const RESEARCH_FIELD_DATA: Record<string, { german: string; color: string; description: string }> = {
  BOMBER: {
    german: 'Bomber',
    color: 'text-red-400 bg-red-500/20',
    description: 'Spezialisiert auf Bomben und explosive Alchemie',
  },
  CHIRURGEON: {
    german: 'Chirurg',
    color: 'text-green-400 bg-green-500/20',
    description: 'Spezialisiert auf Heilelixiere und Medizin',
  },
  MUTAGENIST: {
    german: 'Mutageniker',
    color: 'text-blue-400 bg-blue-500/20',
    description: 'Spezialisiert auf Mutagene und Körperverbesserung',
  },
  TOXICOLOGIST: {
    german: 'Toxikologe',
    color: 'text-yellow-400 bg-yellow-500/20',
    description: 'Spezialisiert auf Gifte und Toxine',
  },
};

// Alchemy item subcategory colors
const SUBCATEGORY_COLORS: Record<string, string> = {
  'Bomb': 'text-red-400 bg-red-500/20',
  'Elixir': 'text-green-400 bg-green-500/20',
  'Mutagen': 'text-blue-400 bg-blue-500/20',
  'Poison': 'text-yellow-400 bg-yellow-500/20',
  'Tool': 'text-gray-400 bg-gray-500/20',
  'Drug': 'text-purple-400 bg-purple-500/20',
};

/**
 * Extract the base name from an alchemical item name (remove potency suffix)
 * Removes any parenthetical suffix at the end of the name
 * E.g., "Alchemist's Fire (Greater)" -> "Alchemist's Fire"
 *       "Alchemistenfeuer (Stark)" -> "Alchemistenfeuer"
 */
function extractBaseName(name: string): string {
  // Remove any parenthetical suffix at the end: "Item Name (Anything)" -> "Item Name"
  return name.replace(/\s*\([^)]+\)$/, '').trim();
}

// PF2e Action Keywords to ActionIcon props mapping
const ACTION_KEYWORDS: Record<string, number | 'reaction' | 'free'> = {
  'one-action': 1,
  'two-actions': 2,
  'three-actions': 3,
  'reaction': 'reaction',
  'free-action': 'free',
};

/**
 * Parse activation text and render with proper action icons
 * Handles malformed text like "one-action]" (missing opening bracket)
 */
function ActivationText({ text }: { text: string }) {
  // Split text by action keywords and render with icons
  const parts: React.ReactNode[] = [];
  let keyIndex = 0;

  // Create a regex that matches all action keywords (with optional brackets)
  const keywordPattern = Object.keys(ACTION_KEYWORDS)
    .map(k => `\\[?${k}\\]?`)
    .join('|');
  const regex = new RegExp(`(${keywordPattern})`, 'gi');

  let match;
  let lastIndex = 0;

  // Reset regex
  regex.lastIndex = 0;

  while ((match = regex.exec(text)) !== null) {
    // Add text before the match
    if (match.index > lastIndex) {
      parts.push(text.slice(lastIndex, match.index));
    }

    // Find which keyword matched (normalize by removing brackets)
    const matchedText = match[0].replace(/[\[\]]/g, '').toLowerCase();
    const actionValue = ACTION_KEYWORDS[matchedText];

    if (actionValue !== undefined) {
      parts.push(
        <ActionIcon key={`action-${keyIndex++}`} actions={actionValue} size="sm" className="mx-0.5 align-middle" />
      );
    } else {
      parts.push(match[0]);
    }

    lastIndex = regex.lastIndex;
  }

  // Add remaining text
  if (lastIndex < text.length) {
    parts.push(text.slice(lastIndex));
  }

  return <span className="inline-flex items-center flex-wrap gap-0.5">{parts}</span>;
}

interface AlchemyTabProps {
  character: Character;
  campaignId: string;
  onStateUpdate: (state: CharacterAlchemyState) => void;
  onFormulasUpdate: (formulas: CharacterFormula[]) => void;
  onPreparedItemsUpdate: (items: CharacterPreparedItem[]) => void;
}

export function AlchemyTab({
  character,
  campaignId,
  onStateUpdate,
  onFormulasUpdate,
  onPreparedItemsUpdate,
}: AlchemyTabProps) {
  const [showAddFormula, setShowAddFormula] = useState(false);
  const [showPrepareItems, setShowPrepareItems] = useState(false);
  const [showQuickAlchemy, setShowQuickAlchemy] = useState(false);
  const [showCraftAlchemy, setShowCraftAlchemy] = useState(false);
  const [selectedFormula, setSelectedFormula] = useState<CharacterFormula | null>(null);
  const [showInfused, setShowInfused] = useState(true);
  const [showPermanent, setShowPermanent] = useState(true);

  const alchemyState = character.alchemyState;
  const formulas = character.formulas || [];
  const preparedItems = character.preparedItems || [];

  // Separate infused and permanent items
  const infusedItems = preparedItems.filter((i) => i.isInfused);
  const permanentItems = preparedItems.filter((i) => !i.isInfused);

  // Check if character is an alchemist
  const isAlchemist = !!alchemyState;

  if (!isAlchemist) {
    return (
      <div className="space-y-6">
        <Card>
          <CardContent className="py-8 text-center">
            <FlaskConical className="h-12 w-12 mx-auto text-text-muted mb-4" />
            <h3 className="text-lg font-medium text-text-primary mb-2">Keine Alchemie verfügbar</h3>
            <p className="text-text-secondary">
              Dieser Charakter ist kein Alchemist und hat keine Alchemie-Fähigkeiten.
            </p>
          </CardContent>
        </Card>
      </div>
    );
  }

  const handleUpdateVials = async (newCurrent: number) => {
    try {
      const result = await api.updateVials(campaignId, character.id, newCurrent);
      onStateUpdate(result);
    } catch (err) {
      console.error('Failed to update vials:', err);
    }
  };

  const handleRefillVials = async () => {
    try {
      const result = await api.refillVials(campaignId, character.id);
      onStateUpdate(result);
    } catch (err) {
      console.error('Failed to refill vials:', err);
    }
  };

  const handleDeletePreparedItem = async (itemId: string) => {
    try {
      await api.deletePreparedItem(campaignId, character.id, itemId);
      onPreparedItemsUpdate(preparedItems.filter((i) => i.id !== itemId));
    } catch (err) {
      console.error('Failed to delete item:', err);
    }
  };

  const researchField = alchemyState.researchField;
  const fieldData = researchField ? RESEARCH_FIELD_DATA[researchField] : null;

  return (
    <div className="space-y-4">
      {/* Research Field Card */}
      {fieldData && (
        <Card>
          <CardContent className="py-4">
            <div className="flex items-center gap-3">
              <div className={`h-10 w-10 rounded-lg flex items-center justify-center ${fieldData.color}`}>
                <Beaker className="h-5 w-5" />
              </div>
              <div className="flex-1">
                <p className="font-medium text-text-primary">{fieldData.german}</p>
                <p className="text-xs text-text-secondary">{fieldData.description}</p>
              </div>
            </div>
          </CardContent>
        </Card>
      )}

      {/* Versatile Vials Card */}
      <Card>
        <CardHeader className="pb-2">
          <CardTitle className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              <FlaskConical className="h-5 w-5 text-purple-400" />
              Vielseitige Phiolen
            </div>
            <Button
              size="sm"
              variant="outline"
              className="text-purple-400 border-purple-500/30 hover:bg-purple-500/10"
              onClick={handleRefillVials}
              disabled={alchemyState.versatileVialsCurrent >= alchemyState.versatileVialsMax}
            >
              <RefreshCw className="h-4 w-4 mr-1" />
              Auffüllen
            </Button>
          </CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex items-center justify-center gap-4">
            <Button
              size="icon"
              variant="outline"
              className="h-10 w-10"
              onClick={() => handleUpdateVials(alchemyState.versatileVialsCurrent - 1)}
              disabled={alchemyState.versatileVialsCurrent <= 0}
            >
              <Minus className="h-5 w-5" />
            </Button>
            <div className="text-center min-w-[100px]">
              <p className="text-3xl font-bold text-purple-400">
                {alchemyState.versatileVialsCurrent}
              </p>
              <p className="text-xs text-text-secondary">von {alchemyState.versatileVialsMax}</p>
            </div>
            <Button
              size="icon"
              variant="outline"
              className="h-10 w-10"
              onClick={() => handleUpdateVials(alchemyState.versatileVialsCurrent + 1)}
              disabled={alchemyState.versatileVialsCurrent >= alchemyState.versatileVialsMax}
            >
              <Plus className="h-5 w-5" />
            </Button>
          </div>
          {/* Progress bar */}
          <div className="mt-3 h-2 bg-bg-tertiary rounded-full overflow-hidden">
            <div
              className="h-full bg-purple-500 transition-all"
              style={{
                width: `${(alchemyState.versatileVialsCurrent / alchemyState.versatileVialsMax) * 100}%`,
              }}
            />
          </div>
        </CardContent>
      </Card>

      {/* Advanced Alchemy Batch Card */}
      <Card>
        <CardHeader className="pb-2">
          <CardTitle className="flex items-center gap-2">
            <Sparkles className="h-5 w-5 text-yellow-400" />
            Fortgeschrittene Alchemie
          </CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex items-center justify-between">
            <div>
              <p className="text-sm text-text-secondary">Tägliche Chargen</p>
              <p className="text-lg font-bold text-yellow-400">
                {alchemyState.advancedAlchemyBatch} / {alchemyState.advancedAlchemyMax} verwendet
              </p>
            </div>
            <Button
              variant="outline"
              className="border-yellow-500/30 text-yellow-400 hover:bg-yellow-500/10"
              onClick={() => setShowPrepareItems(true)}
              disabled={alchemyState.advancedAlchemyBatch >= alchemyState.advancedAlchemyMax}
            >
              <Plus className="h-4 w-4 mr-1" />
              Vorbereiten
            </Button>
          </div>
          {/* Progress bar */}
          <div className="mt-3 h-2 bg-bg-tertiary rounded-full overflow-hidden">
            <div
              className="h-full bg-yellow-500 transition-all"
              style={{
                width: `${(alchemyState.advancedAlchemyBatch / alchemyState.advancedAlchemyMax) * 100}%`,
              }}
            />
          </div>
        </CardContent>
      </Card>

      {/* Quick Alchemy and Craft Buttons */}
      <div className="grid grid-cols-2 gap-2">
        <Button
          className="bg-purple-600 hover:bg-purple-700"
          onClick={() => setShowQuickAlchemy(true)}
          disabled={alchemyState.versatileVialsCurrent <= 0}
        >
          <Zap className="h-4 w-4 mr-2" />
          Schnelle Alchemie
        </Button>
        <Button
          variant="outline"
          className="border-amber-500/30 text-amber-400 hover:bg-amber-500/10"
          onClick={() => setShowCraftAlchemy(true)}
        >
          <Hammer className="h-4 w-4 mr-2" />
          Normale Alchemie
        </Button>
      </div>

      {/* Infused Items Section */}
      <Card>
        <CardHeader className="pb-2">
          <CardTitle
            className="flex items-center justify-between cursor-pointer"
            onClick={() => setShowInfused(!showInfused)}
          >
            <div className="flex items-center gap-2">
              <Beaker className="h-5 w-5 text-cyan-400" />
              Infundierte Gegenstände ({infusedItems.length})
            </div>
            {showInfused ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
          </CardTitle>
        </CardHeader>
        {showInfused && (
          <CardContent>
            {infusedItems.length > 0 && (
              <p className="text-xs text-yellow-500/80 mb-3 flex items-center gap-1">
                <Sparkles className="h-3 w-3" />
                Infundierte Items verfallen beim nächsten Rasten
              </p>
            )}
            {infusedItems.length === 0 ? (
              <p className="text-center text-text-muted py-4">
                Keine infundierten Gegenstände
              </p>
            ) : (
              <div className="space-y-2">
                {infusedItems.map((item) => (
                  <PreparedItemRow
                    key={item.id}
                    item={item}
                    onDelete={() => handleDeletePreparedItem(item.id)}
                  />
                ))}
              </div>
            )}
          </CardContent>
        )}
      </Card>

      {/* Permanent Items Section */}
      <Card>
        <CardHeader className="pb-2">
          <CardTitle
            className="flex items-center justify-between cursor-pointer"
            onClick={() => setShowPermanent(!showPermanent)}
          >
            <div className="flex items-center gap-2">
              <Hammer className="h-5 w-5 text-amber-400" />
              Hergestellte Gegenstände ({permanentItems.length})
            </div>
            {showPermanent ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
          </CardTitle>
        </CardHeader>
        {showPermanent && (
          <CardContent>
            {permanentItems.length > 0 && (
              <p className="text-xs text-green-500/80 mb-3 flex items-center gap-1">
                <Check className="h-3 w-3" />
                Hergestellte Items bleiben beim Rasten erhalten
              </p>
            )}
            {permanentItems.length === 0 ? (
              <p className="text-center text-text-muted py-4">
                Keine hergestellten Gegenstände
              </p>
            ) : (
              <div className="space-y-2">
                {permanentItems.map((item) => (
                  <PreparedItemRow
                    key={item.id}
                    item={item}
                    onDelete={() => handleDeletePreparedItem(item.id)}
                  />
                ))}
              </div>
            )}
          </CardContent>
        )}
      </Card>

      {/* Formula Book */}
      <Card>
        <CardHeader className="pb-2">
          <CardTitle className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              <BookOpen className="h-5 w-5 text-amber-400" />
              Formelbuch ({formulas.length})
            </div>
            <Button
              size="sm"
              variant="outline"
              className="border-amber-500/30 text-amber-400 hover:bg-amber-500/10"
              onClick={() => setShowAddFormula(true)}
            >
              <Plus className="h-4 w-4 mr-1" />
              Formel
            </Button>
          </CardTitle>
        </CardHeader>
        <CardContent>
          {formulas.length === 0 ? (
            <p className="text-center text-text-muted py-4">
              Keine Formeln im Formelbuch
            </p>
          ) : (
            <div className="grid gap-2 sm:grid-cols-2">
              {formulas.map((formula) => (
                <button
                  key={formula.id}
                  className="p-3 rounded-lg bg-bg-secondary hover:bg-bg-tertiary transition-colors text-left"
                  onClick={() => setSelectedFormula(formula)}
                >
                  <p className="font-medium text-text-primary truncate">
                    {extractBaseName(formula.equipment?.nameGerman || formula.nameGerman || formula.name)}
                  </p>
                  <div className="flex items-center gap-2 mt-1">
                    {formula.equipment?.itemSubcategory && (
                      <span className={`text-xs px-1.5 py-0.5 rounded ${SUBCATEGORY_COLORS[formula.equipment.itemSubcategory] || 'text-text-muted bg-bg-tertiary'}`}>
                        {formula.equipment.itemSubcategory}
                      </span>
                    )}
                  </div>
                </button>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Modals */}
      {showAddFormula && (
        <AddFormulaModal
          campaignId={campaignId}
          characterId={character.id}
          characterLevel={character.level}
          existingFormulaIds={formulas.map((f) => f.equipmentId)}
          onClose={() => setShowAddFormula(false)}
          onAdd={(formula) => {
            onFormulasUpdate([...formulas, formula]);
            setShowAddFormula(false);
          }}
        />
      )}

      {showPrepareItems && (
        <PrepareItemsModal
          campaignId={campaignId}
          characterId={character.id}
          availableSlots={alchemyState.advancedAlchemyMax - alchemyState.advancedAlchemyBatch}
          onClose={() => setShowPrepareItems(false)}
          onPrepare={(items) => {
            onPreparedItemsUpdate([...preparedItems, ...items]);
            // Update batch count in state
            const totalPrepared = items.reduce((sum, i) => sum + i.quantity, 0);
            onStateUpdate({
              ...alchemyState,
              advancedAlchemyBatch: alchemyState.advancedAlchemyBatch + totalPrepared,
            });
            setShowPrepareItems(false);
          }}
        />
      )}

      {showQuickAlchemy && (
        <QuickAlchemyModal
          campaignId={campaignId}
          characterId={character.id}
          onClose={() => setShowQuickAlchemy(false)}
          onCreated={(item) => {
            onPreparedItemsUpdate([item, ...preparedItems]);
            onStateUpdate({
              ...alchemyState,
              versatileVialsCurrent: alchemyState.versatileVialsCurrent - 1,
            });
            setShowQuickAlchemy(false);
          }}
        />
      )}

      {showCraftAlchemy && (
        <CraftAlchemyModal
          campaignId={campaignId}
          characterId={character.id}
          formulas={formulas}
          onClose={() => setShowCraftAlchemy(false)}
          onCrafted={(item) => {
            onPreparedItemsUpdate([item, ...preparedItems]);
            setShowCraftAlchemy(false);
          }}
        />
      )}

      {selectedFormula && (
        <FormulaDetailModal
          formula={selectedFormula}
          onClose={() => setSelectedFormula(null)}
          onRemove={() => {
            onFormulasUpdate(formulas.filter((f) => f.id !== selectedFormula.id));
            setSelectedFormula(null);
          }}
          campaignId={campaignId}
          characterId={character.id}
        />
      )}
    </div>
  );
}

/**
 * Parse English effect text and extract damage/healing/bonus values
 */
function parseEffectDamage(effect: string): { dice: string; abbr: string; color: string }[] {
  const results: { dice: string; abbr: string; color: string }[] = [];
  const splashResults: { dice: string; abbr: string; color: string }[] = [];

  // 1. Healing: "restores 3d6+6 Hit Points"
  const healMatch = effect.match(/restores?\s+(\d+d\d+(?:\s*\+\s*\d+)?)\s+Hit\s+Points/i);
  if (healMatch) {
    results.push({
      dice: healMatch[1].replace(/\s+/g, ''),
      abbr: 'Heal',
      color: 'bg-green-500/20 text-green-400'
    });
  }

  // 2. Item bonus: "bonus is +1" or "+1 item bonus" or "gain a +1 item bonus"
  const bonusMatch1 = effect.match(/bonus\s+is\s+\+(\d+)/i);
  const bonusMatch2 = effect.match(/\+(\d+)\s+(?:item\s+)?bonus/i);
  const bonusValue = bonusMatch1?.[1] || bonusMatch2?.[1];
  if (bonusValue) {
    results.push({
      dice: `+${bonusValue}`,
      abbr: 'Bonus',
      color: 'bg-blue-500/20 text-blue-400'
    });
  }

  // If we found healing/bonus, return those
  if (results.length > 0) {
    return results;
  }

  // Type config for damage
  const typeConfig: Record<string, { abbr: string; color: string }> = {
    'bludgeoning': { abbr: 'B', color: 'bg-red-500/20 text-red-400' },
    'slashing': { abbr: 'S', color: 'bg-red-500/20 text-red-400' },
    'piercing': { abbr: 'P', color: 'bg-red-500/20 text-red-400' },
    'fire': { abbr: 'F', color: 'bg-orange-500/20 text-orange-400' },
    'cold': { abbr: 'C', color: 'bg-cyan-500/20 text-cyan-400' },
    'electricity': { abbr: 'E', color: 'bg-yellow-500/20 text-yellow-400' },
    'acid': { abbr: 'A', color: 'bg-green-500/20 text-green-400' },
    'poison': { abbr: 'Po', color: 'bg-purple-500/20 text-purple-400' },
    'sonic': { abbr: 'So', color: 'bg-pink-500/20 text-pink-400' },
    'mental': { abbr: 'M', color: 'bg-violet-500/20 text-violet-400' },
    'force': { abbr: 'Fo', color: 'bg-blue-500/20 text-blue-400' },
    'bleed': { abbr: 'Blut', color: 'bg-red-700/20 text-red-500' },
  };

  // 3. Splash damage: "1 slashing splash damage" or "1 splash damage"
  const splashPattern = /(\d+d?\d*)\s+(\w+\s+)?splash\s+damage/gi;
  let match;
  while ((match = splashPattern.exec(effect)) !== null) {
    const dice = match[1];
    const splashType = match[2]?.trim().toLowerCase();
    const typeInfo = splashType ? typeConfig[splashType] : null;
    splashResults.push({
      dice,
      abbr: typeInfo ? `${typeInfo.abbr} Splash` : 'Splash',
      color: typeInfo?.color || 'bg-orange-500/20 text-orange-400',
    });
  }

  // 4. Regular damage: "1d8 slashing damage", "1 persistent bleed damage"
  const damagePattern = /(\d+d\d+|\d+)\s+(persistent\s+)?(\w+)\s+damage/gi;
  while ((match = damagePattern.exec(effect)) !== null) {
    const dice = match[1];
    const type = match[3].toLowerCase();

    // Skip if this is splash damage (handled separately)
    if (type === 'splash') continue;

    // Check if next word is "splash" - then skip (handled by splash pattern)
    const afterMatch = effect.slice(match.index + match[0].length);
    if (/^\s*splash/i.test(afterMatch)) continue;

    const config = typeConfig[type] || { abbr: type.charAt(0).toUpperCase(), color: 'bg-red-500/20 text-red-400' };
    results.push({
      dice,
      abbr: config.abbr,
      color: config.color,
    });
  }

  // Splash damage always at the end
  return [...results, ...splashResults];
}

// Prepared Item Row Component - shows effect directly
interface PreparedItemRowProps {
  item: CharacterPreparedItem;
  onDelete: () => void;
}

function PreparedItemRow({ item, onDelete }: PreparedItemRowProps) {
  // Always parse the English effect for consistent results
  const effectEN = item.equipment?.effect;
  const summaryEN = item.equipment?.summary;
  const textToParse = effectEN || summaryEN || '';
  const parsedDamages = parseEffectDamage(textToParse);

  // For display fallback, prefer German (prioritize German over English)
  const displayText = item.equipment?.effectGerman || item.equipment?.summaryGerman ||
                      item.equipment?.effect || item.equipment?.summary;

  return (
    <div
      className={`p-3 rounded-lg bg-bg-secondary border ${item.isInfused ? 'border-cyan-500/20' : 'border-amber-500/20'}`}
    >
      {/* Header row */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2 flex-wrap flex-1 min-w-0">
          <span className="font-medium text-text-primary">
            {item.equipment?.nameGerman || item.nameGerman || item.name}
          </span>
          {item.equipment?.level !== undefined && item.equipment?.level !== null && (
            <span className="text-xs px-1.5 py-0.5 rounded bg-bg-tertiary text-text-secondary">
              Stufe {item.equipment.level}
            </span>
          )}
          {/* Show creation method for infused items */}
          {item.isInfused && (
            item.isQuickAlchemy ? (
              <span className="text-xs px-1.5 py-0.5 rounded bg-purple-500/20 text-purple-400 flex items-center gap-1">
                <Zap className="h-3 w-3" />
                Schnell
              </span>
            ) : (
              <span className="text-xs px-1.5 py-0.5 rounded bg-yellow-500/20 text-yellow-400 flex items-center gap-1">
                <Sparkles className="h-3 w-3" />
                Vorbereitet
              </span>
            )
          )}
        </div>
        <div className="flex items-center gap-1 ml-2">
          <span className={`font-bold min-w-[30px] text-center ${item.isInfused ? 'text-cyan-400' : 'text-amber-400'}`}>
            x{item.quantity}
          </span>
          <Button
            size="icon"
            variant="ghost"
            className="h-8 w-8 text-red-400 hover:text-red-300 hover:bg-red-500/10"
            onClick={onDelete}
            title="Löschen"
          >
            <Trash2 className="h-4 w-4" />
          </Button>
        </div>
      </div>

      {/* Effect display */}
      {parsedDamages.length > 0 ? (
        <div className="mt-2 flex flex-wrap gap-2">
          {parsedDamages.map((dmg, i) => (
            <span
              key={i}
              className={`inline-flex items-center gap-1 text-sm px-2 py-1 rounded ${dmg.color}`}
            >
              <span className="font-bold">{dmg.dice}</span>
              <span>{dmg.abbr}</span>
            </span>
          ))}
        </div>
      ) : displayText ? (
        <p className="mt-2 text-sm text-text-secondary line-clamp-2">{displayText}</p>
      ) : null}
    </div>
  );
}

// Formula Detail Modal
interface FormulaDetailModalProps {
  formula: CharacterFormula;
  onClose: () => void;
  onRemove: () => void;
  campaignId: string;
  characterId: string;
}

function FormulaDetailModal({
  formula,
  onClose,
  onRemove,
  campaignId,
  characterId,
}: FormulaDetailModalProps) {
  const [isRemoving, setIsRemoving] = useState(false);
  const [isLoadingVariants, setIsLoadingVariants] = useState(true);
  const [variants, setVariants] = useState<AvailableFormula[]>([]);
  const [selectedVariantId, setSelectedVariantId] = useState<string | null>(null);
  const [activeTab, setActiveTab] = useState<'info' | 'effects'>('info');

  const equipment = formula.equipment;
  const baseName = extractBaseName(formula.name);

  // Load all variants of this formula
  useEffect(() => {
    loadVariants();
  }, []);

  const loadVariants = async () => {
    setIsLoadingVariants(true);
    try {
      const data = await api.getAvailableFormulas(campaignId, characterId);
      console.log('[FormulaDetail] API returned', data.length, 'available formulas');
      console.log('[FormulaDetail] Looking for baseName:', baseName);
      // Filter to only variants of this formula
      const formulaVariants = data.filter((f: AvailableFormula) =>
        extractBaseName(f.name) === baseName
      );
      console.log('[FormulaDetail] Found', formulaVariants.length, 'variants:', formulaVariants.map((f: AvailableFormula) => `${f.name} (Lvl ${f.level})`));
      // Sort by level
      formulaVariants.sort((a: AvailableFormula, b: AvailableFormula) => (a.level ?? 0) - (b.level ?? 0));
      setVariants(formulaVariants);
      // Default to the current formula's equipment
      if (equipment) {
        setSelectedVariantId(equipment.id);
      } else if (formulaVariants.length > 0) {
        setSelectedVariantId(formulaVariants[0].id);
      }
    } catch (err) {
      console.error('Failed to load variants:', err);
    } finally {
      setIsLoadingVariants(false);
    }
  };

  const selectedVariant = variants.find(v => v.id === selectedVariantId) || null;
  const displayEquipment = selectedVariant || equipment;

  const subcategoryColor = displayEquipment?.itemSubcategory
    ? SUBCATEGORY_COLORS[displayEquipment.itemSubcategory] || 'text-text-muted bg-bg-tertiary'
    : '';

  const handleRemove = async () => {
    setIsRemoving(true);
    try {
      await api.removeFormula(campaignId, characterId, formula.id);
      onRemove();
    } catch (err) {
      console.error('Failed to remove formula:', err);
    } finally {
      setIsRemoving(false);
    }
  };

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4" onClick={onClose}>
      <Card className="w-full max-w-lg max-h-[80vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
        <div className="p-4 border-b border-border">
          <div className="flex items-center justify-between">
            <div>
              <h2 className="text-lg font-bold text-text-primary">
                {extractBaseName(displayEquipment?.nameGerman || formula.nameGerman || formula.name)}
              </h2>
              {(displayEquipment?.nameGerman || formula.nameGerman) && (
                <p className="text-sm text-text-secondary italic">{baseName}</p>
              )}
            </div>
            <Button variant="ghost" size="icon" onClick={onClose}>
              <X className="h-5 w-5" />
            </Button>
          </div>
        </div>
        {/* Tab Navigation */}
        {!isLoadingVariants && variants.length > 1 && (
          <div className="border-b border-border px-4">
            <div className="flex gap-4">
              <button
                className={`py-3 px-1 text-sm font-medium border-b-2 transition-colors ${
                  activeTab === 'info'
                    ? 'border-primary-500 text-primary-400'
                    : 'border-transparent text-text-secondary hover:text-text-primary'
                }`}
                onClick={() => setActiveTab('info')}
              >
                Details
              </button>
              <button
                className={`py-3 px-1 text-sm font-medium border-b-2 transition-colors ${
                  activeTab === 'effects'
                    ? 'border-primary-500 text-primary-400'
                    : 'border-transparent text-text-secondary hover:text-text-primary'
                }`}
                onClick={() => setActiveTab('effects')}
              >
                Alle Effekte ({variants.length})
              </button>
            </div>
          </div>
        )}

        <div className="flex-1 overflow-y-auto p-4">
          {/* Effects Tab - Show all variant effects */}
          {activeTab === 'effects' && !isLoadingVariants && variants.length > 1 ? (
            <div className="space-y-4">
              <p className="text-sm text-text-secondary mb-4">
                Vergleiche die Effekte aller verfügbaren Stufenvarianten:
              </p>
              {variants.map((variant) => {
                const isOriginal = variant.id === equipment?.id;
                const potencyLabel = variant.nameGerman?.match(/\(([^)]+)\)$/)?.[1] ||
                                   variant.name.match(/\(([^)]+)\)$/)?.[1] ||
                                   `Stufe ${variant.level ?? 0}`;
                return (
                  <div
                    key={variant.id}
                    className={`p-4 rounded-lg border ${
                      isOriginal
                        ? 'bg-amber-500/10 border-amber-500/30'
                        : 'bg-bg-secondary border-border'
                    }`}
                  >
                    <div className="flex items-center justify-between mb-2">
                      <div className="flex items-center gap-2">
                        <span className="font-medium text-text-primary">
                          {potencyLabel}
                        </span>
                        <span className="text-xs px-1.5 py-0.5 rounded bg-bg-tertiary text-text-secondary">
                          Stufe {variant.level ?? 0}
                        </span>
                        {isOriginal && (
                          <span className="text-xs px-1.5 py-0.5 rounded bg-amber-500/20 text-amber-400">
                            Gelernt
                          </span>
                        )}
                      </div>
                      {variant.price !== undefined && variant.price !== null && (
                        <span className="text-xs text-text-secondary">
                          {variant.price} Gp
                        </span>
                      )}
                    </div>
                    {(variant.effectGerman || variant.effect) ? (
                      <p className="text-sm text-text-primary">
                        {variant.effectGerman || variant.effect}
                      </p>
                    ) : (
                      <p className="text-sm text-text-muted italic">
                        Kein spezifischer Effekt
                      </p>
                    )}
                  </div>
                );
              })}
            </div>
          ) : (
            <>
              {/* Info Tab - Original detail view */}
              {/* Formula source badge */}
              <div className="flex flex-wrap gap-2 mb-4">
                <span className="text-sm px-2 py-1 rounded bg-amber-500/20 text-amber-400">
                  Formelbuch
                </span>
                {formula.formulaSource && (
                  <span className="text-sm px-2 py-1 rounded bg-bg-tertiary text-text-secondary">
                    {formula.formulaSource}
                  </span>
                )}
              </div>

              {/* Variant Selector */}
              {!isLoadingVariants && variants.length > 1 && (
                <div className="mb-4">
                  <h4 className="text-sm font-medium text-text-secondary mb-2">Stufenvarianten</h4>
                  <div className="flex flex-wrap gap-2">
                    {variants.map((variant) => {
                      const isSelected = variant.id === selectedVariantId;
                      const isOriginal = variant.id === equipment?.id;
                      return (
                        <button
                          key={variant.id}
                          className={`px-3 py-2 rounded-lg text-sm font-medium transition-colors ${
                            isSelected
                              ? 'bg-primary-500 text-white'
                              : 'bg-bg-tertiary text-text-secondary hover:bg-bg-secondary hover:text-text-primary'
                          }`}
                          onClick={() => setSelectedVariantId(variant.id)}
                        >
                          <span>Lvl {variant.level ?? 0}</span>
                          {isOriginal && !isSelected && (
                            <span className="ml-1 text-amber-400">*</span>
                          )}
                        </button>
                      );
                    })}
                  </div>
                  <p className="text-xs text-text-muted mt-1">* = Gelernte Version</p>
                </div>
              )}

          {isLoadingVariants ? (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="h-6 w-6 animate-spin text-primary-500" />
            </div>
          ) : displayEquipment ? (
            <div className="space-y-4">
              {/* Basic info */}
              <div className="flex flex-wrap gap-2">
                {displayEquipment.level !== undefined && displayEquipment.level !== null && (
                  <span className="text-sm px-2 py-1 rounded bg-bg-tertiary text-text-secondary">
                    Stufe {displayEquipment.level}
                  </span>
                )}
                {displayEquipment.itemSubcategory && (
                  <span className={`text-sm px-2 py-1 rounded ${subcategoryColor}`}>
                    {displayEquipment.itemSubcategory}
                  </span>
                )}
                {displayEquipment.price !== undefined && displayEquipment.price !== null && (
                  <span className="text-sm px-2 py-1 rounded bg-bg-tertiary text-text-secondary">
                    {displayEquipment.price} Gp
                  </span>
                )}
                {displayEquipment.bulk && (
                  <span className="text-sm px-2 py-1 rounded bg-bg-tertiary text-text-secondary">
                    Gewicht: {displayEquipment.bulk}
                  </span>
                )}
              </div>

              {/* Traits */}
              {displayEquipment.traits && displayEquipment.traits.length > 0 && (
                <div>
                  <h4 className="text-sm font-medium text-text-secondary mb-2">Eigenschaften</h4>
                  <div className="flex flex-wrap gap-1">
                    {displayEquipment.traits.map((trait, i) => (
                      <span
                        key={i}
                        className="text-xs px-2 py-1 rounded bg-primary-500/20 text-primary-400"
                      >
                        {trait}
                      </span>
                    ))}
                  </div>
                </div>
              )}

              {/* Activation */}
              {displayEquipment.activation && (
                <div>
                  <h4 className="text-sm font-medium text-text-secondary mb-1">Aktivierung</h4>
                  <p className="text-text-primary"><ActivationText text={displayEquipment.activation} /></p>
                </div>
              )}

              {/* Duration */}
              {displayEquipment.duration && (
                <div>
                  <h4 className="text-sm font-medium text-text-secondary mb-1">Dauer</h4>
                  <p className="text-text-primary">{displayEquipment.duration}</p>
                </div>
              )}

              {/* Usage */}
              {displayEquipment.usage && (
                <div>
                  <h4 className="text-sm font-medium text-text-secondary mb-1">Verwendung</h4>
                  <p className="text-text-primary">{displayEquipment.usage}</p>
                </div>
              )}

              {/* Effect - specific to this variant (prefer German translation) */}
              {(displayEquipment.effectGerman || displayEquipment.effect) && (
                <div className="p-3 rounded-lg bg-primary-500/10 border border-primary-500/20">
                  <h4 className="text-sm font-medium text-primary-400 mb-1">Effekt</h4>
                  <p className="text-text-primary text-sm">{displayEquipment.effectGerman || displayEquipment.effect}</p>
                </div>
              )}

              {/* Summary/Description */}
              {(displayEquipment.summaryGerman || displayEquipment.summary) && (
                <div>
                  <h4 className="text-sm font-medium text-text-secondary mb-1">Beschreibung</h4>
                  <p className="text-text-primary text-sm whitespace-pre-wrap">
                    {displayEquipment.summaryGerman || displayEquipment.summary}
                  </p>
                </div>
              )}

              {/* Link to Archives of Nethys */}
              {displayEquipment.url && (
                <a
                  href={`https://2e.aonprd.com${displayEquipment.url}`}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="inline-flex items-center gap-1 text-sm text-primary-400 hover:text-primary-300"
                >
                  Mehr auf Archives of Nethys
                </a>
              )}
            </div>
          ) : (
            <p className="text-text-muted text-center py-4">
              Keine Details verfügbar
            </p>
          )}
            </>
          )}
        </div>

        {/* Actions */}
        <div className="p-4 border-t border-border">
          <Button
            variant="outline"
            className="w-full border-red-500/30 text-red-400 hover:bg-red-500/10"
            onClick={handleRemove}
            disabled={isRemoving}
          >
            {isRemoving ? (
              <Loader2 className="h-4 w-4 animate-spin mr-2" />
            ) : (
              <Trash2 className="h-4 w-4 mr-2" />
            )}
            Formel entfernen
          </Button>
        </div>
      </Card>
    </div>
  );
}

// Add Formula Modal - Now browsable with level filtering
interface AddFormulaModalProps {
  campaignId: string;
  characterId: string;
  characterLevel: number;
  existingFormulaIds: string[];
  onClose: () => void;
  onAdd: (formula: CharacterFormula) => void;
}

function AddFormulaModal({
  campaignId,
  characterId,
  characterLevel,
  existingFormulaIds,
  onClose,
  onAdd,
}: AddFormulaModalProps) {
  const [search, setSearch] = useState('');
  const [results, setResults] = useState<Equipment[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isAdding, setIsAdding] = useState(false);
  const [addError, setAddError] = useState<string | null>(null);

  // Load initial results on mount
  useEffect(() => {
    loadItems('');
  }, []);

  const loadItems = async (query: string) => {
    setIsLoading(true);
    try {
      // Search for alchemical items up to character level
      const data = await api.searchEquipment({
        query: query,
        category: 'Alchemical Items',
        maxLevel: characterLevel,
        limit: 50,
      });
      // Filter out already known formulas
      const filtered = data.items.filter((item: Equipment) => !existingFormulaIds.includes(item.id));
      setResults(filtered);
    } catch (err) {
      console.error('Failed to search equipment:', err);
    } finally {
      setIsLoading(false);
    }
  };

  const handleSearch = () => {
    loadItems(search);
  };

  const handleAdd = async (equipment: Equipment) => {
    setIsAdding(true);
    setAddError(null);
    try {
      const formula = await api.addFormula(campaignId, characterId, {
        equipmentId: equipment.id,
        formulaSource: 'Purchased',
      });
      onAdd(formula);
    } catch (err: any) {
      const message = err.response?.data?.message || 'Fehler beim Hinzufügen der Formel';
      setAddError(message);
      console.error('Failed to add formula:', err);
    } finally {
      setIsAdding(false);
    }
  };

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4" onClick={onClose}>
      <Card className="w-full max-w-lg max-h-[80vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
        <div className="p-4 border-b border-border">
          <div className="flex items-center justify-between mb-2">
            <h2 className="text-lg font-bold text-text-primary">Formel hinzufügen</h2>
            <Button variant="ghost" size="icon" onClick={onClose}>
              <X className="h-5 w-5" />
            </Button>
          </div>
          <p className="text-sm text-text-secondary">
            Zeigt Gegenstände bis Stufe {characterLevel} (Charakterstufe)
          </p>
        </div>
        <div className="p-4">
          {addError && (
            <div className="mb-3 p-3 rounded-lg bg-red-500/10 border border-red-500/20">
              <p className="text-sm text-red-400">{addError}</p>
            </div>
          )}
          <div className="flex gap-2">
            <input
              type="text"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
              placeholder="Alchemistischen Gegenstand suchen..."
              className="flex-1 px-3 py-2 rounded-lg bg-bg-secondary border border-border text-text-primary placeholder:text-text-muted focus:outline-none focus:border-primary-500"
            />
            <Button onClick={handleSearch} disabled={isLoading}>
              {isLoading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Search className="h-4 w-4" />}
            </Button>
          </div>
        </div>
        <div className="flex-1 overflow-y-auto p-4 pt-0">
          {isLoading ? (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="h-6 w-6 animate-spin text-primary-500" />
            </div>
          ) : results.length === 0 ? (
            <p className="text-center text-text-muted py-8">
              Keine Ergebnisse gefunden
            </p>
          ) : (
            <div className="space-y-2">
              {results.map((item) => (
                  <div
                    key={item.id}
                    className="flex items-center justify-between p-3 rounded-lg bg-bg-secondary hover:bg-bg-tertiary"
                  >
                    <div className="flex-1 min-w-0">
                      <p className="font-medium text-text-primary truncate">
                        {item.nameGerman || item.name}
                      </p>
                      <div className="flex items-center gap-2 mt-1 flex-wrap">
                        {item.level !== undefined && item.level !== null && (
                          <span className="text-xs px-1.5 py-0.5 rounded bg-bg-tertiary text-text-secondary">
                            Lvl {item.level}
                          </span>
                        )}
                        {item.itemSubcategory && (
                          <span className={`text-xs px-1.5 py-0.5 rounded ${SUBCATEGORY_COLORS[item.itemSubcategory] || 'bg-bg-tertiary text-text-muted'}`}>
                            {item.itemSubcategory}
                          </span>
                        )}
                      </div>
                    </div>
                    <Button
                      size="sm"
                      onClick={() => handleAdd(item)}
                      disabled={isAdding}
                    >
                      <Plus className="h-4 w-4" />
                    </Button>
                  </div>
              ))}
            </div>
          )}
        </div>
      </Card>
    </div>
  );
}

// Prepare Items Modal - Now uses available formulas (includes upgraded versions)
interface PrepareItemsModalProps {
  campaignId: string;
  characterId: string;
  availableSlots: number;
  onClose: () => void;
  onPrepare: (items: CharacterPreparedItem[]) => void;
}

function PrepareItemsModal({
  campaignId,
  characterId,
  availableSlots,
  onClose,
  onPrepare,
}: PrepareItemsModalProps) {
  const [selections, setSelections] = useState<Record<string, number>>({});
  const [isLoading, setIsLoading] = useState(true);
  const [isPreparing, setIsPreparing] = useState(false);
  const [availableFormulas, setAvailableFormulas] = useState<AvailableFormula[]>([]);

  const totalSelected = Object.values(selections).reduce((sum, qty) => sum + qty, 0);

  // Load available formulas on mount
  useEffect(() => {
    loadAvailableFormulas();
  }, []);

  const loadAvailableFormulas = async () => {
    setIsLoading(true);
    try {
      const data = await api.getAvailableFormulas(campaignId, characterId);
      setAvailableFormulas(data);
    } catch (err) {
      console.error('Failed to load available formulas:', err);
    } finally {
      setIsLoading(false);
    }
  };

  const handleQuantityChange = (equipmentId: string, delta: number) => {
    setSelections((prev) => {
      const current = prev[equipmentId] || 0;
      const newValue = Math.max(0, current + delta);
      if (newValue === 0) {
        const { [equipmentId]: _, ...rest } = prev;
        return rest;
      }
      return { ...prev, [equipmentId]: newValue };
    });
  };

  const handlePrepare = async () => {
    const items = Object.entries(selections)
      .filter(([_, qty]) => qty > 0)
      .map(([equipmentId, qty]) => ({
        equipmentId,
        quantity: qty,
      }));

    if (items.length === 0) return;

    setIsPreparing(true);
    try {
      const result = await api.dailyPreparation(campaignId, characterId, items);
      onPrepare(result.preparedItems);
    } catch (err) {
      console.error('Failed to prepare items:', err);
    } finally {
      setIsPreparing(false);
    }
  };

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4" onClick={onClose}>
      <Card className="w-full max-w-lg max-h-[80vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
        <div className="p-4 border-b border-border">
          <h2 className="text-lg font-bold text-text-primary">Tägliche Vorbereitung</h2>
          <p className="text-sm text-text-secondary">
            Verfügbare Chargen: {availableSlots - totalSelected} / {availableSlots}
          </p>
          <p className="text-xs text-cyan-400 mt-1">
            Items werden als infundiert erstellt (verfallen beim Rasten)
          </p>
          <p className="text-xs text-green-400 mt-1">
            Zeigt alle Versionen bekannter Formeln bis zu deiner Stufe
          </p>
        </div>
        <div className="flex-1 overflow-y-auto p-4">
          {isLoading ? (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="h-6 w-6 animate-spin text-primary-500" />
            </div>
          ) : availableFormulas.length === 0 ? (
            <p className="text-center text-text-muted py-8">
              Keine Formeln verfügbar
            </p>
          ) : (
            <div className="space-y-2">
              {availableFormulas.map((formula) => (
                <div
                  key={formula.id}
                  className="flex items-center justify-between p-3 rounded-lg bg-bg-secondary"
                >
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2">
                      <p className="font-medium text-text-primary truncate">
                        {formula.nameGerman || formula.name}
                      </p>
                      {!formula.isLearned && (
                        <span className="text-xs px-1.5 py-0.5 rounded bg-green-500/20 text-green-400">
                          Upgrade
                        </span>
                      )}
                    </div>
                    <div className="flex items-center gap-2 mt-1">
                      {formula.level !== undefined && formula.level !== null && (
                        <span className="text-xs px-1.5 py-0.5 rounded bg-bg-tertiary text-text-secondary">
                          Lvl {formula.level}
                        </span>
                      )}
                      {formula.itemSubcategory && (
                        <span className={`text-xs px-1.5 py-0.5 rounded ${SUBCATEGORY_COLORS[formula.itemSubcategory] || 'bg-bg-tertiary text-text-muted'}`}>
                          {formula.itemSubcategory}
                        </span>
                      )}
                    </div>
                  </div>
                  <div className="flex items-center gap-2">
                    <Button
                      size="icon"
                      variant="outline"
                      className="h-8 w-8"
                      onClick={() => handleQuantityChange(formula.id, -1)}
                      disabled={(selections[formula.id] || 0) <= 0}
                    >
                      <Minus className="h-4 w-4" />
                    </Button>
                    <span className="font-bold min-w-[30px] text-center">
                      {selections[formula.id] || 0}
                    </span>
                    <Button
                      size="icon"
                      variant="outline"
                      className="h-8 w-8"
                      onClick={() => handleQuantityChange(formula.id, 1)}
                      disabled={totalSelected >= availableSlots}
                    >
                      <Plus className="h-4 w-4" />
                    </Button>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
        <div className="p-4 border-t border-border flex gap-2">
          <Button variant="outline" className="flex-1" onClick={onClose}>
            Abbrechen
          </Button>
          <Button
            className="flex-1"
            onClick={handlePrepare}
            disabled={totalSelected === 0 || isPreparing}
          >
            {isPreparing ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              `${totalSelected} Vorbereiten`
            )}
          </Button>
        </div>
      </Card>
    </div>
  );
}

// Quick Alchemy Modal - Now uses available formulas (includes upgraded versions)
interface QuickAlchemyModalProps {
  campaignId: string;
  characterId: string;
  onClose: () => void;
  onCreated: (item: CharacterPreparedItem) => void;
}

function QuickAlchemyModal({
  campaignId,
  characterId,
  onClose,
  onCreated,
}: QuickAlchemyModalProps) {
  const [isLoading, setIsLoading] = useState(true);
  const [isCreating, setIsCreating] = useState(false);
  const [search, setSearch] = useState('');
  const [availableFormulas, setAvailableFormulas] = useState<AvailableFormula[]>([]);

  // Load available formulas on mount
  useEffect(() => {
    loadAvailableFormulas();
  }, []);

  const loadAvailableFormulas = async () => {
    setIsLoading(true);
    try {
      const data = await api.getAvailableFormulas(campaignId, characterId);
      setAvailableFormulas(data);
    } catch (err) {
      console.error('Failed to load available formulas:', err);
    } finally {
      setIsLoading(false);
    }
  };

  const filteredFormulas = availableFormulas.filter((f) =>
    (f.nameGerman || f.name).toLowerCase().includes(search.toLowerCase())
  );

  const handleCreate = async (formula: AvailableFormula) => {
    setIsCreating(true);
    try {
      const item = await api.quickAlchemy(campaignId, characterId, formula.id);
      onCreated(item);
    } catch (err) {
      console.error('Failed to create item:', err);
    } finally {
      setIsCreating(false);
    }
  };

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4" onClick={onClose}>
      <Card className="w-full max-w-lg max-h-[80vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
        <div className="p-4 border-b border-border">
          <div className="flex items-center justify-between mb-2">
            <h2 className="text-lg font-bold text-text-primary">Schnelle Alchemie</h2>
            <Button variant="ghost" size="icon" onClick={onClose}>
              <X className="h-5 w-5" />
            </Button>
          </div>
          <p className="text-sm text-text-secondary">
            Verbrauche 1 Phiole, um sofort einen Gegenstand herzustellen
          </p>
          <p className="text-xs text-cyan-400 mt-1">
            Item wird als infundiert erstellt (verfällt beim Rasten)
          </p>
          <p className="text-xs text-green-400 mt-1">
            Zeigt alle Versionen bekannter Formeln bis zu deiner Stufe
          </p>
        </div>
        <div className="p-4">
          <input
            type="text"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Formel suchen..."
            className="w-full px-3 py-2 rounded-lg bg-bg-secondary border border-border text-text-primary placeholder:text-text-muted focus:outline-none focus:border-primary-500"
          />
        </div>
        <div className="flex-1 overflow-y-auto p-4 pt-0">
          {isLoading ? (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="h-6 w-6 animate-spin text-primary-500" />
            </div>
          ) : filteredFormulas.length === 0 ? (
            <p className="text-center text-text-muted py-8">
              {availableFormulas.length === 0 ? 'Keine Formeln verfügbar' : 'Keine Treffer'}
            </p>
          ) : (
            <div className="space-y-2">
              {filteredFormulas.map((formula) => (
                <button
                  key={formula.id}
                  className="w-full flex items-center justify-between p-3 rounded-lg bg-bg-secondary hover:bg-bg-tertiary text-left transition-colors disabled:opacity-50"
                  onClick={() => handleCreate(formula)}
                  disabled={isCreating}
                >
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2">
                      <p className="font-medium text-text-primary truncate">
                        {formula.nameGerman || formula.name}
                      </p>
                      {!formula.isLearned && (
                        <span className="text-xs px-1.5 py-0.5 rounded bg-green-500/20 text-green-400">
                          Upgrade
                        </span>
                      )}
                    </div>
                    <div className="flex items-center gap-2 mt-1">
                      {formula.level !== undefined && formula.level !== null && (
                        <span className="text-xs px-1.5 py-0.5 rounded bg-bg-tertiary text-text-secondary">
                          Lvl {formula.level}
                        </span>
                      )}
                      {formula.itemSubcategory && (
                        <span className={`text-xs px-1.5 py-0.5 rounded ${SUBCATEGORY_COLORS[formula.itemSubcategory] || 'bg-bg-tertiary text-text-muted'}`}>
                          {formula.itemSubcategory}
                        </span>
                      )}
                    </div>
                  </div>
                  <Zap className="h-5 w-5 text-purple-400 flex-shrink-0" />
                </button>
              ))}
            </div>
          )}
        </div>
      </Card>
    </div>
  );
}

// Craft Alchemy Modal - For permanent items
interface CraftAlchemyModalProps {
  campaignId: string;
  characterId: string;
  formulas: CharacterFormula[];
  onClose: () => void;
  onCrafted: (item: CharacterPreparedItem) => void;
}

function CraftAlchemyModal({
  campaignId,
  characterId,
  formulas,
  onClose,
  onCrafted,
}: CraftAlchemyModalProps) {
  const [search, setSearch] = useState('');
  const [isCrafting, setIsCrafting] = useState(false);
  const [selectedItem, setSelectedItem] = useState<CharacterFormula | null>(null);
  const [quantity, setQuantity] = useState(1);

  // Filter formulas by search
  const filteredFormulas = formulas.filter((formula) => {
    if (!search) return true;
    const searchLower = search.toLowerCase();
    const name = (formula.equipment?.nameGerman || formula.nameGerman || formula.name).toLowerCase();
    return name.includes(searchLower);
  });

  const handleCraft = async () => {
    if (!selectedItem?.equipmentId) return;
    setIsCrafting(true);
    try {
      const item = await api.craftAlchemy(campaignId, characterId, selectedItem.equipmentId, quantity);
      onCrafted(item);
    } catch (err) {
      console.error('Failed to craft item:', err);
    } finally {
      setIsCrafting(false);
    }
  };

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4" onClick={onClose}>
      <Card className="w-full max-w-lg max-h-[80vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
        <div className="p-4 border-b border-border">
          <div className="flex items-center justify-between mb-2">
            <h2 className="text-lg font-bold text-text-primary">Normale Alchemie</h2>
            <Button variant="ghost" size="icon" onClick={onClose}>
              <X className="h-5 w-5" />
            </Button>
          </div>
          <p className="text-sm text-text-secondary">
            Stelle einen alchemischen Gegenstand unter Aufwendung von Ressourcen her
          </p>
          <p className="text-xs text-green-400 mt-1">
            Item wird als hergestellt erstellt (bleibt beim Rasten erhalten)
          </p>
        </div>

        {!selectedItem ? (
          <>
            <div className="p-4">
              <input
                type="text"
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                placeholder="Formel suchen..."
                className="w-full px-3 py-2 rounded-lg bg-bg-secondary border border-border text-text-primary placeholder:text-text-muted focus:outline-none focus:border-primary-500"
              />
            </div>
            <div className="flex-1 overflow-y-auto p-4 pt-0">
              {formulas.length === 0 ? (
                <p className="text-center text-text-muted py-8">
                  Keine Formeln im Formelbuch
                </p>
              ) : filteredFormulas.length === 0 ? (
                <p className="text-center text-text-muted py-8">
                  Keine passenden Formeln gefunden
                </p>
              ) : (
                <div className="space-y-2">
                  {filteredFormulas.map((formula) => (
                    <button
                      key={formula.id}
                      className="w-full flex items-center justify-between p-3 rounded-lg bg-bg-secondary hover:bg-bg-tertiary text-left transition-colors"
                      onClick={() => setSelectedItem(formula)}
                    >
                      <div className="flex-1 min-w-0">
                        <p className="font-medium text-text-primary truncate">
                          {formula.equipment?.nameGerman || formula.nameGerman || formula.name}
                        </p>
                        <div className="flex items-center gap-2 mt-1 flex-wrap">
                          {formula.equipment?.level !== undefined && formula.equipment?.level !== null && (
                            <span className="text-xs px-1.5 py-0.5 rounded bg-bg-tertiary text-text-secondary">
                              Stufe {formula.equipment.level}
                            </span>
                          )}
                          {formula.equipment?.itemSubcategory && (
                            <span className={`text-xs px-1.5 py-0.5 rounded ${SUBCATEGORY_COLORS[formula.equipment.itemSubcategory] || 'bg-bg-tertiary text-text-muted'}`}>
                              {formula.equipment.itemSubcategory}
                            </span>
                          )}
                        </div>
                      </div>
                      <Hammer className="h-5 w-5 text-amber-400 flex-shrink-0" />
                    </button>
                  ))}
                </div>
              )}
            </div>
          </>
        ) : (
          <div className="flex-1 p-4">
            <div className="p-4 rounded-lg bg-bg-secondary mb-4">
              <div className="flex items-center justify-between mb-2">
                <h3 className="font-medium text-text-primary">
                  {selectedItem.equipment?.nameGerman || selectedItem.nameGerman || selectedItem.name}
                </h3>
                <Button variant="ghost" size="sm" onClick={() => setSelectedItem(null)}>
                  Ändern
                </Button>
              </div>
              <div className="flex items-center gap-2 flex-wrap">
                {selectedItem.equipment?.level !== undefined && selectedItem.equipment?.level !== null && (
                  <span className="text-xs px-1.5 py-0.5 rounded bg-bg-tertiary text-text-secondary">
                    Stufe {selectedItem.equipment.level}
                  </span>
                )}
                {selectedItem.equipment?.itemSubcategory && (
                  <span className={`text-xs px-1.5 py-0.5 rounded ${SUBCATEGORY_COLORS[selectedItem.equipment.itemSubcategory] || 'bg-bg-tertiary text-text-muted'}`}>
                    {selectedItem.equipment.itemSubcategory}
                  </span>
                )}
              </div>
            </div>

            <div className="flex items-center justify-center gap-4 mb-4">
              <Button
                size="icon"
                variant="outline"
                className="h-10 w-10"
                onClick={() => setQuantity(Math.max(1, quantity - 1))}
                disabled={quantity <= 1}
              >
                <Minus className="h-5 w-5" />
              </Button>
              <div className="text-center min-w-[100px]">
                <p className="text-3xl font-bold text-amber-400">{quantity}</p>
                <p className="text-xs text-text-secondary">Menge</p>
              </div>
              <Button
                size="icon"
                variant="outline"
                className="h-10 w-10"
                onClick={() => setQuantity(quantity + 1)}
              >
                <Plus className="h-5 w-5" />
              </Button>
            </div>

            <div className="flex gap-2">
              <Button variant="outline" className="flex-1" onClick={onClose}>
                Abbrechen
              </Button>
              <Button
                className="flex-1 bg-amber-600 hover:bg-amber-700"
                onClick={handleCraft}
                disabled={isCrafting}
              >
                {isCrafting ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : (
                  <>
                    <Hammer className="h-4 w-4 mr-2" />
                    Herstellen
                  </>
                )}
              </Button>
            </div>
          </div>
        )}
      </Card>
    </div>
  );
}
