import React, { useState, useCallback, useMemo, useEffect, useRef } from 'react'; import { Sparkles } from 'lucide-react'; import { WizardModal, WizardStep } from '../../ui/WizardModal/WizardModal'; import { ItemTypeSelector, ItemType } from './ItemTypeSelector'; import { AnyWizardData } from './types'; // Import specific wizards import { InventoryWizardSteps, ProductTypeStep, BasicInfoStep, StockConfigStep } from './wizards/InventoryWizard'; import { SupplierWizardSteps } from './wizards/SupplierWizard'; import { RecipeWizardSteps } from './wizards/RecipeWizard'; import { EquipmentWizardSteps } from './wizards/EquipmentWizard'; import { QualityTemplateWizardSteps } from './wizards/QualityTemplateWizard'; import { CustomerOrderWizardSteps } from './wizards/CustomerOrderWizard'; import { CustomerWizardSteps } from './wizards/CustomerWizard'; import { TeamMemberWizardSteps } from './wizards/TeamMemberWizard'; import { SalesEntryWizardSteps } from './wizards/SalesEntryWizard'; interface UnifiedAddWizardProps { isOpen: boolean; onClose: () => void; onComplete?: (itemType: ItemType, data?: any) => void; // Optional: Start with a specific item type (when opened from individual page buttons) initialItemType?: ItemType; } export const UnifiedAddWizard: React.FC = ({ isOpen, onClose, onComplete, initialItemType, }) => { const [selectedItemType, setSelectedItemType] = useState( initialItemType || null ); const [wizardData, setWizardData] = useState({}); // Use a ref to store the current data - this allows step components // to always access the latest data without causing the steps array to be recreated const dataRef = useRef({}); // Update ref whenever data changes useEffect(() => { dataRef.current = wizardData; }, [wizardData]); // Reset state when modal closes const handleClose = useCallback(() => { setSelectedItemType(initialItemType || null); setWizardData({}); dataRef.current = {}; onClose(); }, [onClose, initialItemType]); // Handle item type selection from step 0 const handleItemTypeSelect = useCallback((itemType: ItemType) => { setSelectedItemType(itemType); }, []); // CRITICAL FIX: Update both ref AND state, but wizardSteps won't recreate // The step component needs to re-render to show typed text (controlled inputs) // But wizardSteps useMemo ensures steps array doesn't recreate, so no component recreation const handleDataChange = useCallback((newData: AnyWizardData) => { // Update ref first for immediate access dataRef.current = newData; // Update state to trigger re-render (controlled inputs need this) setWizardData(newData); }, []); // Handle wizard completion const handleWizardComplete = useCallback( (data?: any) => { if (selectedItemType) { // On completion, sync the ref to state for submission setWizardData(dataRef.current); onComplete?.(selectedItemType, dataRef.current); } handleClose(); }, [selectedItemType, onComplete, handleClose] ); // Get wizard steps based on selected item type // ARCHITECTURAL SOLUTION: We pass dataRef and setWizardData to wizard step functions. // The wizard steps use these in their component wrappers, which creates a closure // that always accesses the CURRENT data from dataRef.current, without needing // to recreate the steps array on every data change. const wizardSteps = useMemo((): WizardStep[] => { if (!selectedItemType) { // Step 0: Item Type Selection return [ { id: 'item-type-selection', title: 'Seleccionar tipo', description: 'Elige qué deseas agregar', component: () => ( ), }, ]; } // Pass dataRef and setWizardData - the wizard step functions will use // dataRef.current to always access fresh data without recreating steps switch (selectedItemType) { case 'inventory': return InventoryWizardSteps(dataRef, setWizardData); case 'supplier': return SupplierWizardSteps(dataRef, setWizardData); case 'recipe': return RecipeWizardSteps(dataRef, setWizardData); case 'equipment': return EquipmentWizardSteps(dataRef, setWizardData); case 'quality-template': return QualityTemplateWizardSteps(dataRef, setWizardData); case 'customer-order': return CustomerOrderWizardSteps(dataRef, setWizardData); case 'customer': return CustomerWizardSteps(dataRef, setWizardData); case 'team-member': return TeamMemberWizardSteps(dataRef, setWizardData); case 'sales-entry': return SalesEntryWizardSteps(dataRef, setWizardData); default: return []; } }, [selectedItemType, handleItemTypeSelect, wizardData.entryMethod]); // Add entryMethod for dynamic sales-entry steps // Get wizard title based on selected item type const getWizardTitle = (): string => { if (!selectedItemType) { return 'Agregar Contenido'; } const titleMap: Record = { 'inventory': 'Agregar Inventario', 'supplier': 'Agregar Proveedor', 'recipe': 'Agregar Receta', 'equipment': 'Agregar Equipo', 'quality-template': 'Agregar Plantilla de Calidad', 'customer-order': 'Agregar Pedido', 'customer': 'Agregar Cliente', 'team-member': 'Agregar Miembro del Equipo', 'sales-entry': 'Registrar Ventas', }; return titleMap[selectedItemType] || 'Agregar Contenido'; }; return ( } size="xl" dataRef={dataRef} onDataChange={handleDataChange} /> ); }; export default UnifiedAddWizard;