'use client'; import { useState } from 'react'; import { ActionButton } from '@/components/ui/action-button'; import { GameCard } from '@/components/ui/game-card'; import { SectionHeader } from '@/components/ui/section-header'; import { StatRow } from '@/components/ui/stat-row'; import { Badge } from '@/components/ui/badge'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Separator } from '@/components/ui/separator'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog'; import { Trash2, CheckCircle, AlertTriangle } from 'lucide-react'; import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment'; import type { EquipmentInstance, AppliedEnchantment, LootInventory, EquipmentCraftingProgress } from '@/lib/game/types'; import type { EquipmentSlot } from '@/lib/game/types'; import { fmt } from '@/lib/game/stores'; import { useGameStore, useCraftingStore, useManaStore } from '@/lib/game/stores'; import { useGameToast } from '@/components/game/GameToast'; export interface EnchantmentPreparerProps { selectedEquipmentInstance: string | null; setSelectedEquipmentInstance: (id: string | null) => void; } export function EnchantmentPreparer({ selectedEquipmentInstance, setSelectedEquipmentInstance, }: EnchantmentPreparerProps) { const showToast = useGameToast(); const equippedInstances = useCraftingStore((s) => s.equippedInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances); const preparationProgress = useCraftingStore((s) => s.preparationProgress); const rawMana = useManaStore((s) => s.rawMana); const startPreparing = useCraftingStore((s) => s.startPreparing); const cancelPreparation = useCraftingStore((s) => s.cancelPreparation); // Get equipped items as array const equippedItems = Object.entries(equippedInstances) .filter(([, instanceId]) => instanceId && equipmentInstances[instanceId]) .map(([slot, instanceId]) => ({ slot: slot as EquipmentSlot, instance: equipmentInstances[instanceId!], })); // Confirm dialog state const [showConfirmDialog, setShowConfirmDialog] = useState(false); const handleStartPreparation = () => { if (!selectedEquipmentInstance) return; const instance = equipmentInstances[selectedEquipmentInstance]; if (!instance) return; // If item has existing enchantments, show confirm dialog (bug #8) if (instance.enchantments.length > 0) { setShowConfirmDialog(true); } else { startPreparingWithToast(selectedEquipmentInstance); } }; const startPreparingWithToast = (instanceId: string) => { const instance = equipmentInstances[instanceId]; startPreparing(instanceId); if (instance) { showToast('info', 'Preparation Started', `Preparing ${instance.name} for enchantment...`); } }; const confirmPreparation = () => { if (selectedEquipmentInstance) { startPreparingWithToast(selectedEquipmentInstance); setShowConfirmDialog(false); } }; return (
{/* Equipment Selection */} {preparationProgress ? (
Preparing: {equipmentInstances[preparationProgress.equipmentInstanceId]?.name}
{preparationProgress.progress.toFixed(1)}h / {preparationProgress.required.toFixed(1)}h Mana paid: {fmt(preparationProgress.manaCostPaid)}
{ cancelPreparation(); showToast('warning', 'Preparation Cancelled', 'Equipment preparation was cancelled.'); }}>Cancel
) : (
{equippedItems.map(({ slot, instance }) => { const hasEnchantments = instance.enchantments.length > 0; const isReady = instance.tags?.includes('Ready for Enchantment'); return (
setSelectedEquipmentInstance(instance.instanceId)} role="button" tabIndex={0} aria-label={`${instance.name}${hasEnchantments ? ' (has enchantments)' : ''}${isReady ? ' (ready for enchantment)' : ''}`} >
{instance.name}
{slot}
{hasEnchantments && (
{instance.enchantments.length} enchantments - Preparation will remove them
)} {isReady && (
Ready for Enchantment
)}
{instance.usedCapacity}/{instance.totalCapacity} cap
{instance.enchantments.length} enchants
{/* Requirement: Visual badge for 'Ready for Enchantment' */} {isReady && ( Ready )}
); })} {equippedItems.length === 0 && (
No equipped items
)}
)} {/* Preparation Details */} {!selectedEquipmentInstance ? (
Select equipment to prepare
) : preparationProgress ? (
Preparation in progress...
) : ( (() => { const instance = equipmentInstances[selectedEquipmentInstance]; if (!instance) return null; const hasEnchantments = instance.enchantments.length > 0; const isReady = instance.tags?.includes('Ready for Enchantment'); const prepTime = 2 + Math.floor(instance.totalCapacity / 50); const manaCost = instance.totalCapacity * 10; // Calculate disenchant recovery const recoveryRate = 0.1; // Base recovery rate const totalRecoverable = instance.enchantments.reduce( (sum, e) => sum + Math.floor(e.actualCost * recoveryRate), 0 ); return (
{instance.name}
{/* Show warning if item has enchantments - Requirement: button reads "Prepare — removes existing enchantments" */} {hasEnchantments && !isReady && (
Equipment has enchantments
Preparation will remove all existing enchantments and recover some mana.
Recoverable Mana: {fmt(totalRecoverable)}
)} {/* Show ready status */} {isReady && (
Ready for Enchantment
This item has been prepared and is ready for enchantment application.
)}
{fmt(manaCost)} } highlight={rawMana < manaCost ? 'danger' : 'success'} />
{/* Requirement (bug #8): Confirm dialog before proceeding if item has enchantments */} {hasEnchantments ? ( <> Prepare — removes existing enchantments ({prepTime}h, {fmt(manaCost)} mana) ) : ( <>Start Preparation ({prepTime}h, {fmt(manaCost)} mana) )} Confirm Preparation This equipment has {instance.enchantments.length} existing enchantment(s). Preparation will permanently remove all existing enchantments and recover approximately {fmt(totalRecoverable)} mana.
Equipment: {instance.name}
Enchantments to remove: {instance.enchantments.length}
setShowConfirmDialog(false)} > Cancel Yes, Remove Enchantments & Prepare
); })() )}
); } EnchantmentPreparer.displayName = 'EnchantmentPreparer';