// Real API hook for Critical Alerts using backend forecast alerts import { useState, useCallback, useEffect } from 'react'; import { useForecast } from '../api'; import { useTenantId } from './useTenantId'; export interface RealAlert { id: string; type: 'stock' | 'weather' | 'order' | 'production' | 'system'; severity: 'high' | 'medium' | 'low'; title: string; description: string; action?: string; time: string; } export const useRealAlerts = () => { const [alerts, setAlerts] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const { tenantId } = useTenantId(); const { getForecastAlerts, acknowledgeForecastAlert } = useForecast(); // Transform backend forecast alerts to frontend alert format const transformForecastAlert = (alert: any): RealAlert => { // Map alert types let type: RealAlert['type'] = 'system'; if (alert.alert_type?.includes('stock') || alert.alert_type?.includes('demand')) { type = 'stock'; } else if (alert.alert_type?.includes('weather')) { type = 'weather'; } else if (alert.alert_type?.includes('production')) { type = 'production'; } // Map severity let severity: RealAlert['severity'] = 'medium'; if (alert.severity === 'critical' || alert.severity === 'high') { severity = 'high'; } else if (alert.severity === 'low') { severity = 'low'; } // Generate user-friendly title and description let title = alert.message; let description = alert.message; if (alert.alert_type?.includes('high_demand')) { title = 'Alta Demanda Prevista'; description = `Se prevé alta demanda. ${alert.message}`; } else if (alert.alert_type?.includes('low_confidence')) { title = 'Predicción Incierta'; description = `Baja confianza en predicción. ${alert.message}`; } else if (alert.alert_type?.includes('stock_risk')) { title = 'Riesgo de Desabastecimiento'; description = `Posible falta de stock. ${alert.message}`; } return { id: alert.id, type, severity, title, description, action: 'Ver detalles', time: new Date(alert.created_at).toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit' }) }; }; // Load real alerts from backend const loadAlerts = useCallback(async () => { if (!tenantId) return; setIsLoading(true); setError(null); try { // Get forecast alerts from backend const forecastAlerts = await getForecastAlerts(tenantId); // Filter only active alerts const activeAlerts = forecastAlerts.filter(alert => alert.is_active); // Transform to frontend format const transformedAlerts = activeAlerts.map(transformForecastAlert); // Sort by severity and time (most recent first) transformedAlerts.sort((a, b) => { // First by severity (high > medium > low) const severityOrder = { high: 3, medium: 2, low: 1 }; const severityDiff = severityOrder[b.severity] - severityOrder[a.severity]; if (severityDiff !== 0) return severityDiff; // Then by time (most recent first) return b.time.localeCompare(a.time); }); setAlerts(transformedAlerts.slice(0, 3)); // Show max 3 alerts in dashboard } catch (error) { console.error('Error loading alerts:', error); setError(error instanceof Error ? error.message : 'Failed to load alerts'); // Fallback to sample alerts based on common scenarios setAlerts(generateFallbackAlerts()); } finally { setIsLoading(false); } }, [tenantId, getForecastAlerts]); // Handle alert acknowledgment const handleAlertAction = useCallback(async (alertId: string) => { if (!tenantId) return; try { await acknowledgeForecastAlert(tenantId, alertId); // Remove acknowledged alert from local state setAlerts(prev => prev.filter(alert => alert.id !== alertId)); } catch (error) { console.error('Error acknowledging alert:', error); } }, [tenantId, acknowledgeForecastAlert]); // Generate fallback alerts when API fails const generateFallbackAlerts = (): RealAlert[] => { const now = new Date(); const timeString = now.toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit' }); return [ { id: 'fallback-1', type: 'stock', severity: 'high', title: 'Stock Bajo de Croissants', description: 'Se prevé alta demanda este fin de semana', action: 'Aumentar producción', time: timeString } ]; }; // Load alerts on mount and when tenant changes useEffect(() => { loadAlerts(); // Refresh alerts every 5 minutes const interval = setInterval(loadAlerts, 5 * 60 * 1000); return () => clearInterval(interval); }, [loadAlerts]); return { alerts, isLoading, error, onAlertAction: handleAlertAction, reload: loadAlerts, clearError: () => setError(null), }; };