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 { useTenant } from '../../../stores/tenant.store';
import { useCreatePurchaseOrder } from '../../../api/hooks/purchase-orders';
import { useCreateProductionBatch } from '../../../api/hooks/production';
import { toast } from 'react-hot-toast';
import type { ProductionBatchCreate } from '../../../api/types/production';
import { ProductionPriorityEnum } from '../../../api/types/production';

// 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';
import { PurchaseOrderWizardSteps } from './wizards/PurchaseOrderWizard';
import { ProductionBatchWizardSteps } from './wizards/ProductionBatchWizard';

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<UnifiedAddWizardProps> = ({
  isOpen,
  onClose,
  onComplete,
  initialItemType,
}) => {
  const [selectedItemType, setSelectedItemType] = useState<ItemType | null>(
    initialItemType || null
  );
  const [wizardData, setWizardData] = useState<AnyWizardData>({});
  const [isSubmitting, setIsSubmitting] = useState(false);

  // Get current tenant
  const { currentTenant } = useTenant();

  // API hooks
  const createPurchaseOrderMutation = useCreatePurchaseOrder();
  const createProductionBatchMutation = useCreateProductionBatch();

  // 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<AnyWizardData>({});

  // Update ref whenever data changes
  useEffect(() => {
    dataRef.current = wizardData;
  }, [wizardData]);

  // Reset state when modal closes
  const handleClose = useCallback(() => {
    setSelectedItemType(initialItemType || null);
    setWizardData({});
    dataRef.current = {};
    setIsSubmitting(false);
    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 with API submission
  const handleWizardComplete = useCallback(
    async () => {
      if (!selectedItemType || !currentTenant?.id) {
        return;
      }

      setIsSubmitting(true);

      try {
        const finalData = dataRef.current as any; // Cast to any for flexible data access

        // Handle Purchase Order submission
        if (selectedItemType === 'purchase-order') {
          // Validate items have positive quantities and prices
          if ((finalData.items || []).some((item: any) =>
            Number(item.ordered_quantity) < 0.01 || Number(item.unit_price) < 0.01
          )) {
            throw new Error('Todos los productos deben tener cantidad y precio mayor a 0');
          }

          const subtotal = (finalData.items || []).reduce(
            (sum: number, item: any) => sum + (Number(item.ordered_quantity) * Number(item.unit_price)),
            0
          );

          // Convert date string to ISO datetime with timezone (start of day in local timezone)
          const deliveryDate = new Date(finalData.required_delivery_date + 'T00:00:00');
          if (isNaN(deliveryDate.getTime())) {
            throw new Error('Fecha de entrega inválida');
          }
          const requiredDeliveryDateTime = deliveryDate.toISOString();

          await createPurchaseOrderMutation.mutateAsync({
            tenantId: currentTenant.id,
            data: {
              supplier_id: finalData.supplier_id,
              required_delivery_date: requiredDeliveryDateTime,
              priority: finalData.priority || 'normal',
              subtotal: subtotal,
              tax_amount: Number(finalData.tax_amount) || 0,
              shipping_cost: Number(finalData.shipping_cost) || 0,
              discount_amount: Number(finalData.discount_amount) || 0,
              notes: finalData.notes || undefined,
              items: (finalData.items || []).map((item: any) => ({
                inventory_product_id: item.inventory_product_id,
                ordered_quantity: Number(item.ordered_quantity),
                unit_price: Number(item.unit_price),
                unit_of_measure: item.unit_of_measure,
              })),
            },
          });
          toast.success('Orden de compra creada exitosamente');
        }

        // Handle Production Batch submission
        if (selectedItemType === 'production-batch') {
          // Validate quantities
          if (Number(finalData.planned_quantity) < 0.01) {
            throw new Error('La cantidad planificada debe ser mayor a 0');
          }
          if (Number(finalData.planned_duration_minutes) < 1) {
            throw new Error('La duración planificada debe ser mayor a 0');
          }

          // Convert staff_assigned from string to array
          const staffArray = finalData.staff_assigned_string
            ? finalData.staff_assigned_string.split(',').map((s: string) => s.trim()).filter((s: string) => s.length > 0)
            : [];

          // Convert datetime-local strings to ISO datetime with timezone
          const plannedStartDate = new Date(finalData.planned_start_time);
          const plannedEndDate = new Date(finalData.planned_end_time);

          if (isNaN(plannedStartDate.getTime()) || isNaN(plannedEndDate.getTime())) {
            throw new Error('Fechas de inicio o fin inválidas');
          }

          if (plannedEndDate <= plannedStartDate) {
            throw new Error('La fecha de fin debe ser posterior a la fecha de inicio');
          }

          const batchData: ProductionBatchCreate = {
            product_id: finalData.product_id,
            product_name: finalData.product_name,
            recipe_id: finalData.recipe_id || undefined,
            planned_start_time: plannedStartDate.toISOString(),
            planned_end_time: plannedEndDate.toISOString(),
            planned_quantity: Number(finalData.planned_quantity),
            planned_duration_minutes: Number(finalData.planned_duration_minutes),
            priority: (finalData.priority || ProductionPriorityEnum.MEDIUM) as ProductionPriorityEnum,
            is_rush_order: finalData.is_rush_order || false,
            is_special_recipe: finalData.is_special_recipe || false,
            production_notes: finalData.production_notes || undefined,
            batch_number: finalData.batch_number || undefined,
            order_id: finalData.order_id || undefined,
            forecast_id: finalData.forecast_id || undefined,
            equipment_used: [],
            staff_assigned: staffArray,
            station_id: finalData.station_id || undefined,
          };

          await createProductionBatchMutation.mutateAsync({
            tenantId: currentTenant.id,
            batchData,
          });
          toast.success('Lote de producción creado exitosamente');
        }

        // Call the parent's onComplete callback
        onComplete?.(selectedItemType, finalData);

        // Close the modal
        handleClose();
      } catch (error: any) {
        console.error('Error submitting wizard data:', error);
        toast.error(error.message || 'Error al crear el elemento');
      } finally {
        setIsSubmitting(false);
      }
    },
    [
      selectedItemType,
      currentTenant,
      createPurchaseOrderMutation,
      createProductionBatchMutation,
      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: () => (
            <ItemTypeSelector onSelect={handleItemTypeSelect} />
          ),
        },
      ];
    }

    // 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);
      case 'purchase-order':
        return PurchaseOrderWizardSteps(dataRef, setWizardData);
      case 'production-batch':
        return ProductionBatchWizardSteps(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<ItemType, string> = {
      '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',
      'purchase-order': 'Crear Orden de Compra',
      'production-batch': 'Crear Lote de Producción',
    };

    return titleMap[selectedItemType] || 'Agregar Contenido';
  };

  return (
    <WizardModal
      isOpen={isOpen}
      onClose={handleClose}
      onComplete={handleWizardComplete}
      title={getWizardTitle()}
      steps={wizardSteps}
      icon={<Sparkles className="w-6 h-6" />}
      size="xl"
      dataRef={dataRef}
      onDataChange={handleDataChange}
    />
  );
};

export default UnifiedAddWizard;
