/** * Inventory setup hook for creating inventory from suggestions */ import { useState, useCallback } from 'react'; import { useCreateIngredient, useCreateSalesRecord, } from '../../../api'; import { useCurrentTenant } from '../../../stores'; import type { ProductSuggestionResponse } from './types'; interface InventorySetupState { isLoading: boolean; error: string | null; createdItems: any[]; inventoryMapping: { [productName: string]: string }; salesImportResult: { success: boolean; imported: boolean; records_created: number; message: string; } | null; isInventoryConfigured: boolean; } interface InventorySetupActions { createInventoryFromSuggestions: ( suggestions: ProductSuggestionResponse[] ) => Promise<{ success: boolean; createdItems?: any[]; inventoryMapping?: { [productName: string]: string }; }>; importSalesData: ( salesData: any, inventoryMapping: { [productName: string]: string } ) => Promise<{ success: boolean; recordsCreated: number; message: string; }>; clearError: () => void; reset: () => void; } export const useInventorySetup = () => { const [state, setState] = useState({ isLoading: false, error: null, createdItems: [], inventoryMapping: {}, salesImportResult: null, isInventoryConfigured: false, }); const createIngredientMutation = useCreateIngredient(); const createSalesRecordMutation = useCreateSalesRecord(); const currentTenant = useCurrentTenant(); const createInventoryFromSuggestions = useCallback(async ( suggestions: ProductSuggestionResponse[] ): Promise<{ success: boolean; createdItems?: any[]; inventoryMapping?: { [productName: string]: string }; }> => { console.log('useInventorySetup - createInventoryFromSuggestions called with:', { suggestionsCount: suggestions?.length, suggestions: suggestions?.slice(0, 3), // Log first 3 for debugging tenantId: currentTenant?.id }); if (!suggestions || suggestions.length === 0) { console.error('useInventorySetup - No suggestions provided'); setState(prev => ({ ...prev, error: 'No hay sugerencias para crear el inventario', })); return { success: false }; } if (!currentTenant?.id) { console.error('useInventorySetup - No tenant ID available'); setState(prev => ({ ...prev, error: 'No se pudo obtener información del tenant', })); return { success: false }; } setState(prev => ({ ...prev, isLoading: true, error: null })); try { const createdItems = []; const inventoryMapping: { [key: string]: string } = {}; console.log('useInventorySetup - Creating ingredients from suggestions...'); // Create ingredients from approved suggestions for (const suggestion of suggestions) { try { const ingredientData = { name: suggestion.suggested_name || suggestion.original_name, category: suggestion.category || 'Sin categoría', description: suggestion.notes || '', unit_of_measure: suggestion.unit_of_measure || 'units', low_stock_threshold: 10, // Default low stock threshold reorder_point: 15, // Default reorder point (must be > low_stock_threshold) reorder_quantity: 50, // Default reorder quantity shelf_life_days: suggestion.estimated_shelf_life_days || 30, requires_refrigeration: suggestion.requires_refrigeration || false, requires_freezing: suggestion.requires_freezing || false, is_seasonal: suggestion.is_seasonal || false, cost_per_unit: 0, // Will be set by user later notes: suggestion.notes || `Producto clasificado automáticamente desde: ${suggestion.original_name}`, }; console.log('useInventorySetup - Creating ingredient:', { name: ingredientData.name, category: ingredientData.category, original_name: suggestion.original_name, ingredientData: ingredientData, tenantId: currentTenant.id, apiUrl: `/tenants/${currentTenant.id}/ingredients` }); const createdItem = await createIngredientMutation.mutateAsync({ tenantId: currentTenant.id, ingredientData, }); console.log('useInventorySetup - Created ingredient successfully:', { id: createdItem.id, name: createdItem.name }); createdItems.push(createdItem); // Map both original and suggested names to the same ingredient ID for flexibility inventoryMapping[suggestion.original_name] = createdItem.id; if (suggestion.suggested_name && suggestion.suggested_name !== suggestion.original_name) { inventoryMapping[suggestion.suggested_name] = createdItem.id; } } catch (error) { console.error(`Error creating ingredient ${suggestion.suggested_name || suggestion.original_name}:`, error); // Continue with other ingredients even if one fails } } if (createdItems.length === 0) { throw new Error('No se pudo crear ningún elemento del inventario'); } console.log('useInventorySetup - Successfully created ingredients:', { createdCount: createdItems.length, totalSuggestions: suggestions.length, inventoryMapping }); setState(prev => ({ ...prev, isLoading: false, createdItems, inventoryMapping, isInventoryConfigured: true, })); return { success: true, createdItems, inventoryMapping, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Error creando el inventario'; console.error('useInventorySetup - Error in createInventoryFromSuggestions:', error); setState(prev => ({ ...prev, isLoading: false, error: errorMessage })); return { success: false }; } }, [createIngredientMutation, currentTenant]); const importSalesData = useCallback(async ( salesData: any, inventoryMapping: { [productName: string]: string } ): Promise<{ success: boolean; recordsCreated: number; message: string; }> => { if (!currentTenant?.id) { setState(prev => ({ ...prev, error: 'No se pudo obtener información del tenant', })); return { success: false, recordsCreated: 0, message: 'Error: No se pudo obtener información del tenant', }; } if (!salesData || !salesData.product_list) { setState(prev => ({ ...prev, error: 'No hay datos de ventas para importar', })); return { success: false, recordsCreated: 0, message: 'Error: No hay datos de ventas para importar', }; } setState(prev => ({ ...prev, isLoading: true, error: null })); try { let recordsCreated = 0; // Process actual sales data and create sales records if (salesData.raw_data && Array.isArray(salesData.raw_data)) { for (const salesRecord of salesData.raw_data) { try { // Map product name to inventory product ID const inventoryProductId = inventoryMapping[salesRecord.product_name]; if (inventoryProductId) { const salesRecordData = { date: salesRecord.date, product_name: salesRecord.product_name, inventory_product_id: inventoryProductId, quantity_sold: salesRecord.quantity, unit_price: salesRecord.unit_price, total_revenue: salesRecord.total_amount || (salesRecord.quantity * salesRecord.unit_price), channel: salesRecord.channel || 'tienda', customer_info: salesRecord.customer_info || {}, notes: salesRecord.notes || '', }; await createSalesRecordMutation.mutateAsync({ tenantId: currentTenant.id, salesData: salesRecordData, }); recordsCreated++; } } catch (error) { console.error('Error creating sales record:', error); // Continue with next record } } } const result = { success: recordsCreated > 0, imported: recordsCreated > 0, records_created: recordsCreated, message: recordsCreated > 0 ? `Se importaron ${recordsCreated} registros de ventas exitosamente` : 'No se pudieron importar registros de ventas', }; setState(prev => ({ ...prev, isLoading: false, salesImportResult: result, })); return { success: result.success, recordsCreated, message: result.message, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Error importando datos de ventas'; const result = { success: false, imported: false, records_created: 0, message: errorMessage, }; setState(prev => ({ ...prev, isLoading: false, error: errorMessage, salesImportResult: result, })); return { success: false, recordsCreated: 0, message: errorMessage, }; } }, [createSalesRecordMutation, currentTenant]); const clearError = useCallback(() => { setState(prev => ({ ...prev, error: null })); }, []); const reset = useCallback(() => { setState({ isLoading: false, error: null, createdItems: [], inventoryMapping: {}, salesImportResult: null, isInventoryConfigured: false, }); }, []); return { // State isLoading: state.isLoading, error: state.error, createdItems: state.createdItems, inventoryMapping: state.inventoryMapping, salesImportResult: state.salesImportResult, isInventoryConfigured: state.isInventoryConfigured, // Actions createInventoryFromSuggestions, importSalesData, clearError, reset, } satisfies InventorySetupState & InventorySetupActions; };