/**
 * Performance Analytics Hooks
 * React Query hooks for fetching real-time performance data across all departments
 */

import { useQuery } from '@tanstack/react-query';
import { useMemo } from 'react';
import {
  PerformanceOverview,
  DepartmentPerformance,
  KPIMetric,
  PerformanceAlert,
  HourlyProductivity,
  ProductionPerformance,
  InventoryPerformance,
  SalesPerformance,
  ProcurementPerformance,
  TimePeriod,
} from '../types/performance';
import { useProductionDashboard, useActiveBatches } from './production';
import { inventoryService } from '../services/inventory';
import { useQuery } from '@tanstack/react-query';
import type { InventoryDashboardSummary } from '../types/inventory';
import { useSalesAnalytics } from './sales';
import { useProcurementDashboard } from './procurement';
import { useOrdersDashboard } from './orders';
import { useTenantCurrency } from '../../hooks/useTenantCurrency';

// ============================================================================
// Helper Functions
// ============================================================================

const getDateRangeForPeriod = (period: TimePeriod): { startDate: string; endDate: string } => {
  const endDate = new Date();
  const startDate = new Date();

  switch (period) {
    case 'day':
      startDate.setDate(endDate.getDate() - 1);
      break;
    case 'week':
      startDate.setDate(endDate.getDate() - 7);
      break;
    case 'month':
      startDate.setMonth(endDate.getMonth() - 1);
      break;
    case 'quarter':
      startDate.setMonth(endDate.getMonth() - 3);
      break;
    case 'year':
      startDate.setFullYear(endDate.getFullYear() - 1);
      break;
  }

  return {
    startDate: startDate.toISOString().split('T')[0],
    endDate: endDate.toISOString().split('T')[0],
  };
};

const getPreviousPeriodDates = (period: TimePeriod): { startDate: string; endDate: string } => {
  const endDate = new Date();
  const startDate = new Date();

  switch (period) {
    case 'day':
      // Previous day: 2 days ago to 1 day ago
      startDate.setDate(endDate.getDate() - 2);
      endDate.setDate(endDate.getDate() - 1);
      break;
    case 'week':
      // Previous week: 14 days ago to 7 days ago
      startDate.setDate(endDate.getDate() - 14);
      endDate.setDate(endDate.getDate() - 7);
      break;
    case 'month':
      // Previous month: 2 months ago to 1 month ago
      startDate.setMonth(endDate.getMonth() - 2);
      endDate.setMonth(endDate.getMonth() - 1);
      break;
    case 'quarter':
      // Previous quarter: 6 months ago to 3 months ago
      startDate.setMonth(endDate.getMonth() - 6);
      endDate.setMonth(endDate.getMonth() - 3);
      break;
    case 'year':
      // Previous year: 2 years ago to 1 year ago
      startDate.setFullYear(endDate.getFullYear() - 2);
      endDate.setFullYear(endDate.getFullYear() - 1);
      break;
  }

  return {
    startDate: startDate.toISOString().split('T')[0],
    endDate: endDate.toISOString().split('T')[0],
  };
};

const calculateTrend = (current: number, previous: number): 'up' | 'down' | 'stable' => {
  const change = ((current - previous) / previous) * 100;
  if (Math.abs(change) < 1) return 'stable';
  return change > 0 ? 'up' : 'down';
};

const calculateStatus = (current: number, target: number): 'good' | 'warning' | 'critical' => {
  const percentage = (current / target) * 100;
  if (percentage >= 95) return 'good';
  if (percentage >= 85) return 'warning';
  return 'critical';
};

// ============================================================================
// Production Performance Hook
// ============================================================================

export const useProductionPerformance = (tenantId: string, period: TimePeriod = 'week') => {
  const { data: dashboard, isLoading: dashboardLoading } = useProductionDashboard(tenantId);

  // Extract primitive values to prevent unnecessary recalculations
  const efficiencyPercentage = dashboard?.efficiency_percentage || 0;
  const qualityScore = dashboard?.average_quality_score || 0;
  const capacityUtilization = dashboard?.capacity_utilization || 0;
  const onTimeCompletionRate = dashboard?.on_time_completion_rate || 0;

  const performance: ProductionPerformance | undefined = useMemo(() => {
    if (!dashboard) return undefined;

    return {
      efficiency: efficiencyPercentage,
      average_batch_time: 0, // Not available in dashboard
      quality_rate: qualityScore,
      waste_percentage: 0, // Would need production-trends endpoint
      capacity_utilization: capacityUtilization,
      equipment_efficiency: capacityUtilization,
      on_time_completion_rate: onTimeCompletionRate,
      yield_rate: 0, // Would need production-trends endpoint
    };
  }, [efficiencyPercentage, qualityScore, capacityUtilization, onTimeCompletionRate]);

  return {
    data: performance,
    isLoading: dashboardLoading,
  };
};

// ============================================================================
// Inventory Performance Hook
// ============================================================================

export const useInventoryPerformance = (tenantId: string) => {
  const { data: dashboard, isLoading: dashboardLoading } = useQuery<InventoryDashboardSummary>({
    queryKey: ['inventory-dashboard', tenantId],
    queryFn: () => inventoryService.getDashboardSummary(tenantId),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
  });

  // Extract primitive values to prevent unnecessary recalculations
  const totalItems = dashboard?.total_ingredients || 1;
  const lowStockCount = dashboard?.low_stock_items || 0;
  const outOfStockCount = dashboard?.out_of_stock_items || 0;
  const foodSafetyAlertsActive = dashboard?.food_safety_alerts_active || 0;
  const expiringItems = dashboard?.expiring_soon_items || 0;
  const stockValue = dashboard?.total_stock_value || 0;

  const performance: InventoryPerformance | undefined = useMemo(() => {
    if (!dashboard) return undefined;

    // Calculate inventory turnover rate estimate
    // Formula: (Cost of Goods Sold / Average Inventory) * 100
    // Since we don't have COGS, estimate using stock movements as proxy
    // Healthy range: 4-6 times per year (monthly turnover: 0.33-0.5)
    const recentMovements = dashboard.recent_movements || 0;
    const currentStockValue = stockValue || 1; // Avoid division by zero
    const turnoverRate = recentMovements > 0
      ? ((recentMovements / currentStockValue) * 100)
      : 0;

    // Calculate waste rate from stock movements
    // Formula: (Waste Quantity / Total Inventory) * 100
    // Typical food waste rate: 2-10% depending on product category
    const recentWaste = dashboard.recent_waste || 0;
    const totalStock = dashboard.total_stock_items || 1; // Avoid division by zero
    const wasteRate = (recentWaste / totalStock) * 100;

    return {
      stock_accuracy: 100 - ((lowStockCount + outOfStockCount) / totalItems * 100),
      turnover_rate: Math.min(100, Math.max(0, turnoverRate)), // Cap at 0-100%
      waste_rate: Math.min(100, Math.max(0, wasteRate)), // Cap at 0-100%
      low_stock_count: lowStockCount,
      compliance_rate: foodSafetyAlertsActive === 0 ? 100 : 90, // Simplified compliance
      expiring_items_count: expiringItems,
      stock_value: stockValue,
    };
  }, [dashboard, totalItems, lowStockCount, outOfStockCount, foodSafetyAlertsActive, expiringItems, stockValue]);

  return {
    data: performance,
    isLoading: dashboardLoading,
  };
};

// ============================================================================
// Sales Performance Hook
// ============================================================================

export const useSalesPerformance = (tenantId: string, period: TimePeriod = 'week') => {
  const { startDate, endDate } = getDateRangeForPeriod(period);

  // Get current period data
  const { data: salesData, isLoading: salesLoading } = useSalesAnalytics(
    tenantId,
    startDate,
    endDate
  );

  // Get previous period data for growth rate calculation
  const previousPeriod = getPreviousPeriodDates(period);
  const { data: previousSalesData } = useSalesAnalytics(
    tenantId,
    previousPeriod.startDate,
    previousPeriod.endDate
  );

  // Extract primitive values to prevent unnecessary recalculations
  const totalRevenue = salesData?.total_revenue || 0;
  const totalTransactions = salesData?.total_transactions || 0;
  const avgTransactionValue = salesData?.average_transaction_value || 0;
  const topProductsString = salesData?.top_products ? JSON.stringify(salesData.top_products) : '[]';
  const previousRevenue = previousSalesData?.total_revenue || 0;

  const performance: SalesPerformance | undefined = useMemo(() => {
    if (!salesData) return undefined;

    const topProducts = JSON.parse(topProductsString);

    // Calculate growth rate: ((current - previous) / previous) * 100
    let growthRate = 0;
    if (previousRevenue > 0 && totalRevenue > 0) {
      growthRate = ((totalRevenue - previousRevenue) / previousRevenue) * 100;
      // Cap at ±999% to avoid display issues
      growthRate = Math.max(-999, Math.min(999, growthRate));
    }

    // Parse channel performance from sales_by_channel if available
    const channelPerformance = salesData.sales_by_channel
      ? Object.entries(salesData.sales_by_channel).map(([channel, data]: [string, any]) => ({
          channel,
          revenue: data.revenue || 0,
          transactions: data.transactions || 0,
          growth: data.growth || 0,
        }))
      : [];

    return {
      total_revenue: totalRevenue,
      total_transactions: totalTransactions,
      average_transaction_value: avgTransactionValue,
      growth_rate: growthRate,
      channel_performance: channelPerformance,
      top_products: Array.isArray(topProducts)
        ? topProducts.map((product: any) => ({
            product_id: product.inventory_product_id || '',
            product_name: product.product_name || '',
            sales: product.total_quantity || 0,
            revenue: product.total_revenue || 0,
          }))
        : [],
    };
  }, [totalRevenue, totalTransactions, avgTransactionValue, topProductsString, previousRevenue]);

  return {
    data: performance,
    isLoading: salesLoading,
  };
};

// ============================================================================
// Procurement Performance Hook
// ============================================================================

export const useProcurementPerformance = (tenantId: string) => {
  const { data: dashboard, isLoading } = useProcurementDashboard(tenantId);

  // Extract primitive values to prevent unnecessary recalculations
  const avgFulfillmentRate = dashboard?.performance_metrics?.average_fulfillment_rate || 0;
  const avgOnTimeDelivery = dashboard?.performance_metrics?.average_on_time_delivery || 0;
  const costAccuracy = dashboard?.performance_metrics?.cost_accuracy || 0;
  const supplierPerformance = dashboard?.performance_metrics?.supplier_performance || 0;
  const totalPlans = dashboard?.summary?.total_plans || 0;
  const lowStockCount = dashboard?.low_stock_alerts?.length || 0;
  const overdueCount = dashboard?.overdue_requirements?.length || 0;

  const performance: ProcurementPerformance | undefined = useMemo(() => {
    if (!dashboard) return undefined;

    return {
      fulfillment_rate: avgFulfillmentRate,
      on_time_delivery_rate: avgOnTimeDelivery,
      cost_accuracy: costAccuracy,
      supplier_performance_score: supplierPerformance,
      active_plans: totalPlans,
      critical_requirements: lowStockCount + overdueCount,
    };
  }, [avgFulfillmentRate, avgOnTimeDelivery, costAccuracy, supplierPerformance, totalPlans, lowStockCount, overdueCount]);

  return {
    data: performance,
    isLoading,
  };
};

// ============================================================================
// Performance Overview Hook (Aggregates All Departments)
// ============================================================================

export const usePerformanceOverview = (tenantId: string, period: TimePeriod = 'week') => {
  const { data: production, isLoading: productionLoading } = useProductionPerformance(tenantId, period);
  const { data: inventory, isLoading: inventoryLoading } = useInventoryPerformance(tenantId);
  const { data: sales, isLoading: salesLoading } = useSalesPerformance(tenantId, period);
  const { data: procurement, isLoading: procurementLoading } = useProcurementPerformance(tenantId);
  const { data: orders, isLoading: ordersLoading } = useOrdersDashboard(tenantId);

  const overview: PerformanceOverview | undefined = useMemo(() => {
    if (!production || !inventory || !sales || !procurement || !orders) return undefined;

    // Calculate customer satisfaction from order fulfillment and delivery performance
    const totalOrders = orders.total_orders_today || 1;
    const deliveredOrders = orders.delivered_orders || 0;
    const orderFulfillmentRate = (deliveredOrders / totalOrders) * 100;

    const customerSatisfaction = (orderFulfillmentRate + procurement.on_time_delivery_rate) / 2;

    return {
      overall_efficiency: production.efficiency,
      average_production_time: production.average_batch_time,
      quality_score: production.quality_rate,
      employee_productivity: production.capacity_utilization,
      customer_satisfaction: customerSatisfaction,
      resource_utilization: production.equipment_efficiency || production.capacity_utilization,
    };
  }, [production, inventory, sales, procurement, orders]);

  return {
    data: overview,
    isLoading: productionLoading || inventoryLoading || salesLoading || procurementLoading || ordersLoading,
  };
};

// ============================================================================
// Department Performance Hook
// ============================================================================

export const useDepartmentPerformance = (tenantId: string, period: TimePeriod = 'week') => {
  const { data: production, isLoading: productionLoading } = useProductionPerformance(tenantId, period);
  const { data: inventory, isLoading: inventoryLoading } = useInventoryPerformance(tenantId);
  const { data: sales, isLoading: salesLoading } = useSalesPerformance(tenantId, period);
  const { data: procurement, isLoading: procurementLoading } = useProcurementPerformance(tenantId);
  const { currencySymbol } = useTenantCurrency();

  // Extract primitive values before useMemo to prevent unnecessary recalculations
  const productionEfficiency = production?.efficiency || 0;
  const productionAvgBatchTime = production?.average_batch_time || 0;
  const productionQualityRate = production?.quality_rate || 0;
  const productionWastePercentage = production?.waste_percentage || 0;
  const salesTotalRevenue = sales?.total_revenue || 0;
  const salesGrowthRate = sales?.growth_rate || 0;
  const salesTotalTransactions = sales?.total_transactions || 0;
  const salesAvgTransactionValue = sales?.average_transaction_value || 0;
  const inventoryStockAccuracy = inventory?.stock_accuracy || 0;
  const inventoryLowStockCount = inventory?.low_stock_count || 0;
  const inventoryTurnoverRate = inventory?.turnover_rate || 0;
  const procurementFulfillmentRate = procurement?.fulfillment_rate || 0;
  const procurementOnTimeDeliveryRate = procurement?.on_time_delivery_rate || 0;
  const procurementCostAccuracy = procurement?.cost_accuracy || 0;

  const departments: DepartmentPerformance[] | undefined = useMemo(() => {
    if (!production || !inventory || !sales || !procurement) return undefined;

    return [
      {
        department_id: 'production',
        department_name: 'Producción',
        efficiency: productionEfficiency,
        trend: productionEfficiency >= 85 ? 'up' : productionEfficiency >= 75 ? 'stable' : 'down',
        metrics: {
          primary_metric: {
            label: 'Tiempo promedio de lote',
            value: productionAvgBatchTime,
            unit: 'h',
          },
          secondary_metric: {
            label: 'Tasa de calidad',
            value: productionQualityRate,
            unit: '%',
          },
          tertiary_metric: {
            label: 'Desperdicio',
            value: productionWastePercentage,
            unit: '%',
          },
        },
      },
      {
        department_id: 'sales',
        department_name: 'Ventas',
        efficiency: (salesTotalRevenue / 10000) * 100, // Normalize to percentage
        trend: salesGrowthRate > 0 ? 'up' : salesGrowthRate < 0 ? 'down' : 'stable',
        metrics: {
          primary_metric: {
            label: 'Ingresos totales',
            value: salesTotalRevenue,
            unit: currencySymbol,
          },
          secondary_metric: {
            label: 'Transacciones',
            value: salesTotalTransactions,
            unit: '',
          },
          tertiary_metric: {
            label: 'Valor promedio',
            value: salesAvgTransactionValue,
            unit: currencySymbol,
          },
        },
      },
      {
        department_id: 'inventory',
        department_name: 'Inventario',
        efficiency: inventoryStockAccuracy,
        trend: inventoryLowStockCount < 5 ? 'up' : inventoryLowStockCount < 10 ? 'stable' : 'down',
        metrics: {
          primary_metric: {
            label: 'Rotación de stock',
            value: inventoryTurnoverRate,
            unit: 'x',
          },
          secondary_metric: {
            label: 'Precisión',
            value: inventoryStockAccuracy,
            unit: '%',
          },
          tertiary_metric: {
            label: 'Items con bajo stock',
            value: inventoryLowStockCount,
            unit: '',
          },
        },
      },
      {
        department_id: 'administration',
        department_name: 'Administración',
        efficiency: procurementFulfillmentRate,
        trend: procurementOnTimeDeliveryRate >= 95 ? 'up' : procurementOnTimeDeliveryRate >= 85 ? 'stable' : 'down',
        metrics: {
          primary_metric: {
            label: 'Tasa de cumplimiento',
            value: procurementFulfillmentRate,
            unit: '%',
          },
          secondary_metric: {
            label: 'Entrega a tiempo',
            value: procurementOnTimeDeliveryRate,
            unit: '%',
          },
          tertiary_metric: {
            label: 'Precisión de costos',
            value: procurementCostAccuracy,
            unit: '%',
          },
        },
      },
    ];
  }, [
    productionEfficiency,
    productionAvgBatchTime,
    productionQualityRate,
    productionWastePercentage,
    salesTotalRevenue,
    salesGrowthRate,
    salesTotalTransactions,
    salesAvgTransactionValue,
    inventoryStockAccuracy,
    inventoryLowStockCount,
    inventoryTurnoverRate,
    procurementFulfillmentRate,
    procurementOnTimeDeliveryRate,
    procurementCostAccuracy,
  ]);

  return {
    data: departments,
    isLoading: productionLoading || inventoryLoading || salesLoading || procurementLoading,
  };
};

// ============================================================================
// KPI Metrics Hook
// ============================================================================

export const useKPIMetrics = (tenantId: string, period: TimePeriod = 'week') => {
  const { data: production, isLoading: productionLoading } = useProductionPerformance(tenantId, period);
  const { data: inventory, isLoading: inventoryLoading } = useInventoryPerformance(tenantId);
  const { data: procurement, isLoading: procurementLoading } = useProcurementPerformance(tenantId);

  // Get previous period data for trend calculation
  const previousPeriod = getPreviousPeriodDates(period);
  const { data: previousProduction } = useProductionPerformance(tenantId, period);
  const { data: previousInventory } = useInventoryPerformance(tenantId);
  const { data: previousProcurement } = useProcurementPerformance(tenantId);

  const kpis: KPIMetric[] | undefined = useMemo(() => {
    if (!production || !inventory || !procurement) return undefined;

    // Calculate trends using previous period data if available, otherwise estimate
    const prevProductionEfficiency = previousProduction?.efficiency || production.efficiency * 0.95;
    const prevInventoryAccuracy = previousInventory?.stock_accuracy || inventory.stock_accuracy * 0.98;
    const prevProcurementOnTime = previousProcurement?.on_time_delivery_rate || procurement.on_time_delivery_rate * 0.97;
    const prevProductionQuality = previousProduction?.quality_rate || production.quality_rate * 0.96;

    return [
      {
        id: 'overall-efficiency',
        name: 'Eficiencia General',
        current_value: production.efficiency,
        target_value: 90,
        previous_value: prevProductionEfficiency,
        unit: '%',
        trend: calculateTrend(production.efficiency, prevProductionEfficiency),
        status: calculateStatus(production.efficiency, 90),
      },
      {
        id: 'quality-rate',
        name: 'Tasa de Calidad',
        current_value: production.quality_rate,
        target_value: 95,
        previous_value: prevProductionQuality,
        unit: '%',
        trend: calculateTrend(production.quality_rate, prevProductionQuality),
        status: calculateStatus(production.quality_rate, 95),
      },
      {
        id: 'on-time-delivery',
        name: 'Entrega a Tiempo',
        current_value: procurement.on_time_delivery_rate,
        target_value: 95,
        previous_value: prevProcurementOnTime,
        unit: '%',
        trend: calculateTrend(procurement.on_time_delivery_rate, prevProcurementOnTime),
        status: calculateStatus(procurement.on_time_delivery_rate, 95),
      },
      {
        id: 'inventory-accuracy',
        name: 'Precisión de Inventario',
        current_value: inventory.stock_accuracy,
        target_value: 98,
        previous_value: prevInventoryAccuracy,
        unit: '%',
        trend: calculateTrend(inventory.stock_accuracy, prevInventoryAccuracy),
        status: calculateStatus(inventory.stock_accuracy, 98),
      },
    ];
  }, [production, inventory, procurement]);

  return {
    data: kpis,
    isLoading: productionLoading || inventoryLoading || procurementLoading,
  };
};

// ============================================================================
// Performance Alerts Hook
// ============================================================================

export const usePerformanceAlerts = (tenantId: string) => {
  const { data: inventory, isLoading: inventoryLoading } = useQuery<InventoryDashboardSummary>({
    queryKey: ['inventory-dashboard', tenantId],
    queryFn: () => inventoryService.getDashboardSummary(tenantId),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // 30 seconds
  });
  const { data: procurement, isLoading: procurementLoading } = useProcurementDashboard(tenantId);

  // Extract primitive values to prevent unnecessary recalculations
  const lowStockCount = inventory?.low_stock_items || 0;
  const outOfStockCount = inventory?.out_of_stock_items || 0;
  const foodSafetyAlerts = inventory?.food_safety_alerts_active || 0;
  const expiringCount = inventory?.expiring_soon_items || 0;
  const lowStockAlertsCount = procurement?.low_stock_alerts?.length || 0;
  const overdueReqsCount = procurement?.overdue_requirements?.length || 0;

  const alerts: PerformanceAlert[] | undefined = useMemo(() => {
    if (!inventory || !procurement) return undefined;

    const alertsList: PerformanceAlert[] = [];

    // Low stock alerts
    if (lowStockCount > 0) {
      alertsList.push({
        id: `low-stock-${Date.now()}`,
        type: 'warning',
        department: 'Inventario',
        message: `${lowStockCount} ingredientes con stock bajo`,
        timestamp: new Date().toISOString(),
        metric_affected: 'Stock',
        current_value: lowStockCount,
      });
    }

    // Out of stock alerts
    if (outOfStockCount > 0) {
      alertsList.push({
        id: `out-of-stock-${Date.now()}`,
        type: 'critical',
        department: 'Inventario',
        message: `${outOfStockCount} ingredientes sin stock`,
        timestamp: new Date().toISOString(),
        metric_affected: 'Stock',
        current_value: outOfStockCount,
      });
    }

    // Food safety alerts
    if (foodSafetyAlerts > 0) {
      alertsList.push({
        id: `food-safety-${Date.now()}`,
        type: 'critical',
        department: 'Inventario',
        message: `${foodSafetyAlerts} alertas de seguridad alimentaria activas`,
        timestamp: new Date().toISOString(),
        metric_affected: 'Seguridad Alimentaria',
        current_value: foodSafetyAlerts,
      });
    }

    // Expiring items alerts
    if (expiringCount > 0) {
      alertsList.push({
        id: `expiring-${Date.now()}`,
        type: 'warning',
        department: 'Inventario',
        message: `${expiringCount} ingredientes próximos a vencer`,
        timestamp: new Date().toISOString(),
        metric_affected: 'Caducidad',
        current_value: expiringCount,
      });
    }

    // Critical procurement requirements
    const criticalCount = lowStockAlertsCount + overdueReqsCount;

    if (criticalCount > 0) {
      alertsList.push({
        id: `procurement-critical-${Date.now()}`,
        type: 'warning',
        department: 'Administración',
        message: `${criticalCount} requisitos de compra críticos`,
        timestamp: new Date().toISOString(),
        metric_affected: 'Aprovisionamiento',
        current_value: criticalCount,
      });
    }

    // Sort by severity: critical > warning > info
    return alertsList.sort((a, b) => {
      const severityOrder = { critical: 0, warning: 1, info: 2 };
      return severityOrder[a.type] - severityOrder[b.type];
    });
  }, [lowStockCount, outOfStockCount, foodSafetyAlerts, expiringCount, lowStockAlertsCount, overdueReqsCount]);

  return {
    data: alerts || [],
    isLoading: inventoryLoading || procurementLoading,
  };
};

// ============================================================================
// Hourly Productivity Hook
// ============================================================================

export const useHourlyProductivity = (tenantId: string) => {
  // Aggregate production batch data by hour for productivity tracking
  const { data: activeBatches } = useActiveBatches(tenantId);
  const { data: salesData } = useSalesPerformance(tenantId, 'day');

  return useQuery<HourlyProductivity[]>({
    queryKey: ['performance', 'hourly', tenantId, activeBatches, salesData],
    queryFn: async () => {
      if (!activeBatches?.batches) return [];

      // Create hourly buckets for the last 24 hours
      const now = new Date();
      const hourlyMap = new Map<string, {
        production_count: number;
        completed_batches: number;
        total_batches: number;
        total_planned_quantity: number;
        total_actual_quantity: number;
      }>();

      // Initialize buckets for last 24 hours
      for (let i = 23; i >= 0; i--) {
        const hourDate = new Date(now);
        hourDate.setHours(now.getHours() - i, 0, 0, 0);
        const hourKey = hourDate.toISOString().substring(0, 13); // YYYY-MM-DDTHH

        hourlyMap.set(hourKey, {
          production_count: 0,
          completed_batches: 0,
          total_batches: 0,
          total_planned_quantity: 0,
          total_actual_quantity: 0,
        });
      }

      // Aggregate batch data by hour
      activeBatches.batches.forEach((batch) => {
        // Use actual_start_time if available, otherwise planned_start_time
        const batchTime = batch.actual_start_time || batch.planned_start_time;
        if (!batchTime) return;

        const batchDate = new Date(batchTime);
        const hourKey = batchDate.toISOString().substring(0, 13);

        const bucket = hourlyMap.get(hourKey);
        if (!bucket) return; // Outside our 24-hour window

        bucket.total_batches += 1;
        bucket.total_planned_quantity += batch.planned_quantity || 0;

        if (batch.status === 'COMPLETED') {
          bucket.completed_batches += 1;
          bucket.total_actual_quantity += batch.actual_quantity || batch.planned_quantity || 0;
          bucket.production_count += batch.actual_quantity || batch.planned_quantity || 0;
        } else if (batch.status === 'IN_PROGRESS' || batch.status === 'QUALITY_CHECK') {
          // For in-progress, estimate based on time elapsed
          const elapsed = now.getTime() - batchDate.getTime();
          const duration = (batch.actual_duration_minutes || batch.planned_duration_minutes || 60) * 60 * 1000;
          const progress = Math.min(1, elapsed / duration);
          bucket.production_count += Math.floor((batch.planned_quantity || 0) * progress);
        }
      });

      // Convert to HourlyProductivity array
      const result: HourlyProductivity[] = Array.from(hourlyMap.entries())
        .map(([hourKey, data]) => {
          // Calculate efficiency: (actual output / planned output) * 100
          const efficiency = data.total_planned_quantity > 0
            ? Math.min(100, (data.total_actual_quantity / data.total_planned_quantity) * 100)
            : 0;

          return {
            hour: hourKey,
            efficiency: Math.round(efficiency * 10) / 10, // Round to 1 decimal
            production_count: data.production_count,
            sales_count: 0, // Sales data would need separate hourly aggregation
          };
        })
        .filter((entry) => entry.hour); // Filter out any invalid entries

      return result;
    },
    enabled: !!tenantId && !!activeBatches,
    staleTime: 5 * 60 * 1000, // 5 minutes
    refetchInterval: 10 * 60 * 1000, // Refetch every 10 minutes
  });
};

// ============================================================================
// Cross-Functional Performance Metrics
// ============================================================================

/**
 * Cycle Time: Order-to-Delivery
 * Measures the complete time from order creation to delivery
 */
export const useCycleTimeMetrics = (tenantId: string, period: TimePeriod = 'week') => {
  const { data: orders, isLoading: ordersLoading } = useOrdersDashboard(tenantId);
  const { data: production, isLoading: productionLoading } = useProductionPerformance(tenantId, period);

  // Extract primitive values before useMemo to prevent unnecessary recalculations
  const totalOrders = orders?.total_orders_today || 1;
  const deliveredOrders = orders?.delivered_orders || 0;
  const pendingOrders = orders?.pending_orders || 0;
  const avgProductionTime = production?.average_batch_time || 2;
  const onTimeCompletionRate = production?.on_time_completion_rate || 0;

  const cycleTime = useMemo(() => {
    if (!orders || !production) return undefined;

    // Estimate average cycle time based on fulfillment rate and production efficiency
    const fulfillmentRate = (deliveredOrders / totalOrders) * 100;

    // Estimated total cycle time includes: order processing + production + delivery
    const estimatedCycleTime = avgProductionTime + (pendingOrders > 0 ? 1.5 : 0.5); // Add wait time

    return {
      average_cycle_time: estimatedCycleTime,
      order_to_production_time: 0.5, // Order processing time
      production_time: avgProductionTime,
      production_to_delivery_time: pendingOrders > 0 ? 1.0 : 0.3,
      fulfillment_rate: fulfillmentRate,
      on_time_delivery_rate: onTimeCompletionRate,
    };
  }, [totalOrders, deliveredOrders, pendingOrders, avgProductionTime, onTimeCompletionRate]);

  return {
    data: cycleTime,
    isLoading: ordersLoading || productionLoading,
  };
};

/**
 * Process Efficiency Score
 * Combined efficiency across all departments
 */
export const useProcessEfficiencyScore = (tenantId: string, period: TimePeriod = 'week') => {
  const { data: production, isLoading: productionLoading } = useProductionPerformance(tenantId, period);
  const { data: inventory, isLoading: inventoryLoading } = useInventoryPerformance(tenantId);
  const { data: procurement, isLoading: procurementLoading } = useProcurementPerformance(tenantId);
  const { data: orders, isLoading: ordersLoading } = useOrdersDashboard(tenantId);

  // Extract primitive values before useMemo to prevent unnecessary recalculations
  const productionEfficiency = production?.efficiency || 0;
  const inventoryStockAccuracy = inventory?.stock_accuracy || 0;
  const procurementFulfillmentRate = procurement?.fulfillment_rate || 0;
  const totalOrders = orders?.total_orders_today || 1;
  const deliveredOrders = orders?.delivered_orders || 0;

  const score = useMemo(() => {
    if (!production || !inventory || !procurement || !orders) return undefined;

    // Weighted efficiency score across departments
    const productionWeight = 0.35;
    const inventoryWeight = 0.25;
    const procurementWeight = 0.25;
    const ordersWeight = 0.15;

    const orderEfficiency = (deliveredOrders / totalOrders) * 100;

    const overallScore =
      (productionEfficiency * productionWeight) +
      (inventoryStockAccuracy * inventoryWeight) +
      (procurementFulfillmentRate * procurementWeight) +
      (orderEfficiency * ordersWeight);

    return {
      overall_score: overallScore,
      production_efficiency: productionEfficiency,
      inventory_efficiency: inventoryStockAccuracy,
      procurement_efficiency: procurementFulfillmentRate,
      order_efficiency: orderEfficiency,
      breakdown: {
        production: { value: productionEfficiency, weight: productionWeight * 100 },
        inventory: { value: inventoryStockAccuracy, weight: inventoryWeight * 100 },
        procurement: { value: procurementFulfillmentRate, weight: procurementWeight * 100 },
        orders: { value: orderEfficiency, weight: ordersWeight * 100 },
      },
    };
  }, [productionEfficiency, inventoryStockAccuracy, procurementFulfillmentRate, totalOrders, deliveredOrders]);

  return {
    data: score,
    isLoading: productionLoading || inventoryLoading || procurementLoading || ordersLoading,
  };
};

/**
 * Resource Utilization Rate
 * Cross-departmental resource balance and utilization
 */
export const useResourceUtilization = (tenantId: string, period: TimePeriod = 'week') => {
  const { data: production, isLoading: productionLoading } = useProductionPerformance(tenantId, period);
  const { data: inventory, isLoading: inventoryLoading } = useInventoryPerformance(tenantId);

  // Extract primitive values before useMemo to prevent unnecessary recalculations
  const equipmentEfficiency = production?.equipment_efficiency || 0;
  const turnoverRate = inventory?.turnover_rate || 0;
  const stockAccuracy = inventory?.stock_accuracy || 0;
  const capacityUtilization = production?.capacity_utilization || 0;

  const utilization = useMemo(() => {
    if (!production || !inventory) return undefined;

    // Equipment utilization from production
    const equipmentUtilization = equipmentEfficiency;

    // Inventory utilization based on turnover and stock levels
    const inventoryUtilization = turnoverRate > 0
      ? Math.min(turnoverRate * 10, 100) // Normalize turnover to percentage
      : stockAccuracy;

    // Combined resource utilization
    const overallUtilization = (equipmentUtilization + inventoryUtilization) / 2;

    return {
      overall_utilization: overallUtilization,
      equipment_utilization: equipmentUtilization,
      inventory_utilization: inventoryUtilization,
      capacity_used: capacityUtilization,
      resource_balance: Math.abs(equipmentUtilization - inventoryUtilization) < 10 ? 'balanced' : 'imbalanced',
    };
  }, [equipmentEfficiency, turnoverRate, stockAccuracy, capacityUtilization]);

  return {
    data: utilization,
    isLoading: productionLoading || inventoryLoading,
  };
};

/**
 * Cost-to-Revenue Ratio
 * Overall profitability metric
 */
export const useCostRevenueRatio = (tenantId: string, period: TimePeriod = 'week') => {
  const { data: sales, isLoading: salesLoading } = useSalesPerformance(tenantId, period);
  const { data: inventory, isLoading: inventoryLoading } = useInventoryPerformance(tenantId);
  const { data: production, isLoading: productionLoading } = useProductionPerformance(tenantId, period);

  // Extract primitive values before useMemo to prevent unnecessary recalculations
  const totalRevenue = sales?.total_revenue || 0;
  const stockValue = inventory?.stock_value || 0;
  const wastePercentage = production?.waste_percentage || 0;

  const ratio = useMemo(() => {
    if (!sales || !inventory || !production) return undefined;

    // Estimate costs from inventory value and waste
    const inventoryCosts = stockValue * 0.1; // Approximate monthly inventory cost
    const wasteCosts = (stockValue * wastePercentage) / 100;
    const estimatedTotalCosts = inventoryCosts + wasteCosts;

    const costRevenueRatio = totalRevenue > 0 ? (estimatedTotalCosts / totalRevenue) * 100 : 0;
    const profitMargin = totalRevenue > 0 ? ((totalRevenue - estimatedTotalCosts) / totalRevenue) * 100 : 0;

    return {
      cost_revenue_ratio: costRevenueRatio,
      profit_margin: profitMargin,
      total_revenue: totalRevenue,
      estimated_costs: estimatedTotalCosts,
      inventory_costs: inventoryCosts,
      waste_costs: wasteCosts,
    };
  }, [totalRevenue, stockValue, wastePercentage]);

  return {
    data: ratio,
    isLoading: salesLoading || inventoryLoading || productionLoading,
  };
};

/**
 * Quality Impact Index
 * Quality issues across all departments
 */
export const useQualityImpactIndex = (tenantId: string, period: TimePeriod = 'week') => {
  const { data: production, isLoading: productionLoading } = useProductionPerformance(tenantId, period);
  const { data: inventory, isLoading: inventoryLoading } = useInventoryPerformance(tenantId);

  // Extract primitive values before useMemo to prevent unnecessary recalculations
  const productionQuality = production?.quality_rate || 0;
  const wasteImpact = production?.waste_percentage || 0;
  const expiringItems = inventory?.expiring_items_count || 0;
  const lowStockItems = inventory?.low_stock_count || 0;

  const qualityIndex = useMemo(() => {
    if (!production || !inventory) return undefined;

    // Inventory quality
    const totalItems = (expiringItems + lowStockItems) || 1;
    const inventoryQualityScore = 100 - ((expiringItems + lowStockItems) / totalItems * 10);

    // Combined quality index (weighted average)
    const overallQuality = (productionQuality * 0.7) + (inventoryQualityScore * 0.3);

    return {
      overall_quality_index: overallQuality,
      production_quality: productionQuality,
      inventory_quality: inventoryQualityScore,
      waste_impact: wasteImpact,
      quality_issues: {
        production_defects: 100 - productionQuality,
        waste_percentage: wasteImpact,
        expiring_items: expiringItems,
        low_stock_affecting_quality: lowStockItems,
      },
    };
  }, [productionQuality, wasteImpact, expiringItems, lowStockItems]);

  return {
    data: qualityIndex,
    isLoading: productionLoading || inventoryLoading,
  };
};

/**
 * Critical Bottlenecks
 * Identifies process bottlenecks across operations
 */
export const useCriticalBottlenecks = (tenantId: string, period: TimePeriod = 'week') => {
  const { data: production, isLoading: productionLoading } = useProductionPerformance(tenantId, period);
  const { data: inventory, isLoading: inventoryLoading } = useInventoryPerformance(tenantId);
  const { data: procurement, isLoading: procurementLoading } = useProcurementPerformance(tenantId);
  const { data: orders, isLoading: ordersLoading } = useOrdersDashboard(tenantId);

  // Extract primitive values before useMemo to prevent unnecessary recalculations
  const capacityUtilization = production?.capacity_utilization || 0;
  const onTimeCompletionRate = production?.on_time_completion_rate || 0;
  const lowStockCount = inventory?.low_stock_count || 0;
  const criticalRequirements = procurement?.critical_requirements || 0;
  const onTimeDeliveryRate = procurement?.on_time_delivery_rate || 0;
  const totalOrders = orders?.total_orders_today || 1;
  const pendingOrders = orders?.pending_orders || 0;

  const bottlenecks = useMemo(() => {
    if (!production || !inventory || !procurement || !orders) return undefined;

    const bottlenecksList = [];

    // Production bottlenecks
    if (capacityUtilization > 90) {
      bottlenecksList.push({
        area: 'production',
        severity: 'high',
        description: 'Capacidad de producción al límite',
        metric: 'capacity_utilization',
        value: capacityUtilization,
      });
    }

    if (onTimeCompletionRate < 85) {
      bottlenecksList.push({
        area: 'production',
        severity: 'medium',
        description: 'Retrasos en completitud de producción',
        metric: 'on_time_completion',
        value: onTimeCompletionRate,
      });
    }

    // Inventory bottlenecks
    if (lowStockCount > 10) {
      bottlenecksList.push({
        area: 'inventory',
        severity: 'high',
        description: 'Alto número de ingredientes con stock bajo',
        metric: 'low_stock_count',
        value: lowStockCount,
      });
    }

    // Procurement bottlenecks
    if (criticalRequirements > 5) {
      bottlenecksList.push({
        area: 'procurement',
        severity: 'high',
        description: 'Requisitos de compra críticos pendientes',
        metric: 'critical_requirements',
        value: criticalRequirements,
      });
    }

    if (onTimeDeliveryRate < 85) {
      bottlenecksList.push({
        area: 'procurement',
        severity: 'medium',
        description: 'Entregas de proveedores retrasadas',
        metric: 'on_time_delivery',
        value: onTimeDeliveryRate,
      });
    }

    // Orders bottlenecks
    const pendingRate = (pendingOrders / totalOrders) * 100;

    if (pendingRate > 30) {
      bottlenecksList.push({
        area: 'orders',
        severity: 'medium',
        description: 'Alto volumen de pedidos pendientes',
        metric: 'pending_orders',
        value: pendingOrders,
      });
    }

    return {
      total_bottlenecks: bottlenecksList.length,
      critical_count: bottlenecksList.filter(b => b.severity === 'high').length,
      bottlenecks: bottlenecksList,
      most_critical_area: bottlenecksList.length > 0
        ? bottlenecksList.sort((a, b) => {
            const severityOrder = { high: 0, medium: 1, low: 2 };
            return severityOrder[a.severity as 'high' | 'medium' | 'low'] - severityOrder[b.severity as 'high' | 'medium' | 'low'];
          })[0].area
        : null,
    };
  }, [capacityUtilization, onTimeCompletionRate, lowStockCount, criticalRequirements, onTimeDeliveryRate, totalOrders, pendingOrders]);

  return {
    data: bottlenecks,
    isLoading: productionLoading || inventoryLoading || procurementLoading || ordersLoading,
  };
};
