/**
 * Enterprise Dashboard Hooks
 *
 * Direct service calls for enterprise network metrics.
 * Fetch data from individual microservices and perform client-side aggregation.
 */

import { useQuery, UseQueryResult } from '@tanstack/react-query';
import { tenantService } from '../services/tenant';
import { salesService } from '../services/sales';
import { inventoryService } from '../services/inventory';
import { productionService } from '../services/production';
import { distributionService } from '../services/distribution';
import { forecastingService } from '../services/forecasting';
import { getPendingApprovalPurchaseOrders } from '../services/purchase_orders';
import { ProcurementService } from '../services/procurement-service';

// ================================================================
// TYPE DEFINITIONS
// ================================================================

export interface ChildTenant {
  id: string;
  name: string;
  business_name: string;
  account_type: string;
  parent_tenant_id: string | null;
  is_active: boolean;
}

export interface SalesSummary {
  total_revenue: number;
  total_quantity: number;
  total_orders: number;
  average_order_value: number;
  top_products: Array<{
    product_name: string;
    quantity_sold: number;
    revenue: number;
  }>;
}

export interface InventorySummary {
  tenant_id: string;
  total_value: number;
  out_of_stock_count: number;
  low_stock_count: number;
  adequate_stock_count: number;
  total_ingredients: number;
}

export interface ProductionSummary {
  tenant_id: string;
  total_batches: number;
  pending_batches: number;
  in_progress_batches: number;
  completed_batches: number;
  total_planned_quantity: number;
  total_actual_quantity: number;
  efficiency_rate: number;
}

export interface NetworkSummary {
  parent_tenant_id: string;
  child_tenant_count: number;
  network_sales_30d: number;
  production_volume_30d: number;
  pending_internal_transfers_count: number;
  active_shipments_count: number;
}

export interface ChildPerformance {
  rank: number;
  tenant_id: string;
  outlet_name: string;
  metric_value: number;
}

export interface PerformanceRankings {
  parent_tenant_id: string;
  metric: string;
  period_days: number;
  rankings: ChildPerformance[];
  total_children: number;
}

export interface DistributionOverview {
  date: string;
  route_sequences: any[]; // Define more specific type as needed
  status_counts: Record<string, number>;
}

export interface ForecastSummary {
  days_forecast: number;
  aggregated_forecasts: Record<string, any>; // Define more specific type as needed
  last_updated: string;
}

// ================================================================
// CHILD TENANTS
// ================================================================

/**
 * Get list of child tenants for a parent
 */
export const useChildTenants = (
  parentTenantId: string,
  options?: { enabled?: boolean }
): UseQueryResult<ChildTenant[]> => {
  return useQuery({
    queryKey: ['tenants', 'children', parentTenantId],
    queryFn: async () => {
      const response = await tenantService.getChildTenants(parentTenantId);
      // Map TenantResponse to ChildTenant
      return response.map(tenant => ({
        id: tenant.id,
        name: tenant.name,
        business_name: tenant.name, // TenantResponse uses 'name' as business name
        account_type: tenant.business_type, // TenantResponse uses 'business_type'
        parent_tenant_id: parentTenantId, // Set from the parent
        is_active: tenant.is_active,
      }));
    },
    staleTime: 60000, // 1 min cache (doesn't change often)
    enabled: options?.enabled ?? true,
  });
};

// ================================================================
// NETWORK SUMMARY (Client-Side Aggregation)
// ================================================================

/**
 * Get network summary by aggregating data from multiple services client-side
 */
export const useNetworkSummary = (
  parentTenantId: string,
  options?: { enabled?: boolean }
): UseQueryResult<NetworkSummary> => {
  const { data: childTenants } = useChildTenants(parentTenantId, options);

  return useQuery({
    queryKey: ['enterprise', 'network-summary', parentTenantId],
    queryFn: async () => {
      const childTenantIds = (childTenants || []).map((c) => c.id);
      const allTenantIds = [parentTenantId, ...childTenantIds];

      // Calculate date range for 30-day sales
      const endDate = new Date();
      const startDate = new Date();
      startDate.setDate(startDate.getDate() - 30);

      // Fetch all data in parallel using service abstractions
      const [salesBatch, productionData, pendingPOs, shipmentsData] = await Promise.all([
        // Sales for all tenants (batch)
        salesService.getBatchSalesSummary(
          allTenantIds,
          startDate.toISOString().split('T')[0],
          endDate.toISOString().split('T')[0]
        ),

        // Production volume for parent
        productionService.getDashboardSummary(parentTenantId),

        // Pending internal transfers (purchase orders marked as internal)
        getPendingApprovalPurchaseOrders(parentTenantId, 100),

        // Active shipments
        distributionService.getShipments(parentTenantId),
      ]);

      // Ensure data are arrays before filtering
      const shipmentsList = Array.isArray(shipmentsData) ? shipmentsData : [];
      const posList = Array.isArray(pendingPOs) ? pendingPOs : [];

      // Aggregate network sales
      const networkSales = Object.values(salesBatch).reduce(
        (sum: number, summary: any) => sum + (summary?.total_revenue || 0),
        0
      );

      // Count active shipments
      const activeStatuses = ['pending', 'in_transit', 'packed'];
      const activeShipmentsCount = shipmentsList.filter((s: any) =>
        activeStatuses.includes(s.status)
      ).length;

      // Count pending transfers (assuming POs with internal flag)
      const pendingTransfers = posList.filter((po: any) =>
        po.reference_number?.includes('INTERNAL') || po.notes?.toLowerCase().includes('internal')
      ).length;

      return {
        parent_tenant_id: parentTenantId,
        child_tenant_count: childTenantIds.length,
        network_sales_30d: networkSales,
        production_volume_30d: (productionData as any)?.total_value || 0,
        pending_internal_transfers_count: pendingTransfers,
        active_shipments_count: activeShipmentsCount,
      };
    },
    staleTime: 30000, // 30s cache
    enabled: (options?.enabled ?? true) && !!childTenants,
  });
};

// ================================================================
// CHILDREN PERFORMANCE (Client-Side Aggregation)
// ================================================================

/**
 * Get performance rankings for child tenants
 */
export const useChildrenPerformance = (
  parentTenantId: string,
  metric: 'sales' | 'inventory_value' | 'production',
  periodDays: number = 30,
  options?: { enabled?: boolean }
): UseQueryResult<PerformanceRankings> => {
  const { data: childTenants } = useChildTenants(parentTenantId, options);

  return useQuery({
    queryKey: ['enterprise', 'children-performance', parentTenantId, metric, periodDays],
    queryFn: async () => {
      if (!childTenants || childTenants.length === 0) {
        return {
          parent_tenant_id: parentTenantId,
          metric,
          period_days: periodDays,
          rankings: [],
          total_children: 0,
        };
      }

      const childTenantIds = childTenants.map((c) => c.id);

      let batchData: Record<string, any> = {};

      if (metric === 'sales') {
        // Fetch sales batch
        const endDate = new Date();
        const startDate = new Date();
        startDate.setDate(startDate.getDate() - periodDays);

        batchData = await salesService.getBatchSalesSummary(
          childTenantIds,
          startDate.toISOString().split('T')[0],
          endDate.toISOString().split('T')[0]
        );
      } else if (metric === 'inventory_value') {
        // Fetch inventory batch
        batchData = await inventoryService.getBatchInventorySummary(childTenantIds);
      } else if (metric === 'production') {
        // Fetch production batch
        batchData = await productionService.getBatchProductionSummary(childTenantIds);
      }

      // Build performance data
      const performanceData = childTenants.map((child) => {
        const summary = batchData[child.id] || {};
        let metricValue = 0;

        if (metric === 'sales') {
          metricValue = summary.total_revenue || 0;
        } else if (metric === 'inventory_value') {
          metricValue = summary.total_value || 0;
        } else if (metric === 'production') {
          metricValue = summary.completed_batches || 0;
        }

        return {
          tenant_id: child.id,
          outlet_name: child.name,
          metric_value: metricValue,
        };
      });

      // Sort by metric value descending
      performanceData.sort((a, b) => b.metric_value - a.metric_value);

      // Add rankings
      const rankings = performanceData.map((data, index) => ({
        rank: index + 1,
        ...data,
      }));

      return {
        parent_tenant_id: parentTenantId,
        metric,
        period_days: periodDays,
        rankings,
        total_children: childTenants.length,
      };
    },
    staleTime: 30000, // 30s cache
    enabled: (options?.enabled ?? true) && !!childTenants,
  });
};

// ================================================================
// DISTRIBUTION OVERVIEW
// ================================================================

/**
 * Get distribution overview for enterprise
 */
export const useDistributionOverview = (
  parentTenantId: string,
  date: string,
  options?: { enabled?: boolean; refetchInterval?: number }
): UseQueryResult<DistributionOverview> => {
  return useQuery({
    queryKey: ['enterprise', 'distribution-overview', parentTenantId, date],
    queryFn: async () => {
      // Get distribution data directly from distribution service
      const routes = await distributionService.getRouteSequences(parentTenantId, date);
      const shipments = await distributionService.getShipments(parentTenantId, date);

      // Count shipment statuses
      const statusCounts: Record<string, number> = {};
      const shipmentsList = Array.isArray(shipments) ? shipments : [];
      for (const shipment of shipmentsList) {
        statusCounts[shipment.status] = (statusCounts[shipment.status] || 0) + 1;
      }

      return {
        date,
        route_sequences: Array.isArray(routes) ? routes : [],
        status_counts: statusCounts,
      };
    },
    staleTime: 30000, // 30s cache
    enabled: options?.enabled ?? true,
    refetchInterval: options?.refetchInterval,
  });
};

// ================================================================
// FORECAST SUMMARY
// ================================================================

/**
 * Get aggregated forecast summary for the enterprise network
 */
export const useForecastSummary = (
  parentTenantId: string,
  daysAhead: number = 7,
  options?: { enabled?: boolean }
): UseQueryResult<ForecastSummary> => {
  return useQuery({
    queryKey: ['enterprise', 'forecast-summary', parentTenantId, daysAhead],
    queryFn: async () => {
      // Get forecast data directly from forecasting service
      // Using existing batch forecasting functionality from the service
      const endDate = new Date();
      const startDate = new Date();
      startDate.setDate(startDate.getDate() + 1); // Tomorrow
      endDate.setDate(endDate.getDate() + daysAhead); // End of forecast period

      // Get forecast data directly from forecasting service
      // Get forecasts for the next N days
      const forecastsResponse = await forecastingService.getTenantForecasts(parentTenantId, {
        start_date: startDate.toISOString().split('T')[0],
        end_date: endDate.toISOString().split('T')[0],
      });

      // Extract forecast data from response
      const forecastItems = forecastsResponse?.items || [];
      const aggregated_forecasts: Record<string, any> = {};

      // Group forecasts by date
      for (const forecast of forecastItems) {
        const date = forecast.forecast_date || forecast.date;
        if (date) {
          aggregated_forecasts[date] = forecast;
        }
      }

      return {
        days_forecast: daysAhead,
        aggregated_forecasts,
        last_updated: new Date().toISOString(),
      };
    },
    staleTime: 300000, // 5 min cache (forecasts don't change very frequently)
    enabled: options?.enabled ?? true,
  });
};

// ================================================================
// INDIVIDUAL CHILD METRICS (for detailed views)
// ================================================================

/**
 * Get sales for a specific child tenant
 */
export const useChildSales = (
  tenantId: string,
  periodDays: number = 30,
  options?: { enabled?: boolean }
): UseQueryResult<SalesSummary> => {
  return useQuery({
    queryKey: ['sales', 'summary', tenantId, periodDays],
    queryFn: async () => {
      const endDate = new Date();
      const startDate = new Date();
      startDate.setDate(startDate.getDate() - periodDays);

      return await salesService.getSalesAnalytics(
        tenantId,
        startDate.toISOString().split('T')[0],
        endDate.toISOString().split('T')[0]
      ) as any;
    },
    staleTime: 30000,
    enabled: options?.enabled ?? true,
  });
};

/**
 * Get inventory for a specific child tenant
 */
export const useChildInventory = (
  tenantId: string,
  options?: { enabled?: boolean }
): UseQueryResult<InventorySummary> => {
  return useQuery({
    queryKey: ['inventory', 'summary', tenantId],
    queryFn: async () => {
      return await inventoryService.getDashboardSummary(tenantId) as any;
    },
    staleTime: 30000,
    enabled: options?.enabled ?? true,
  });
};

/**
 * Get production for a specific child tenant
 */
export const useChildProduction = (
  tenantId: string,
  options?: { enabled?: boolean }
): UseQueryResult<ProductionSummary> => {
  return useQuery({
    queryKey: ['production', 'summary', tenantId],
    queryFn: async () => {
      return await productionService.getDashboardSummary(tenantId) as any;
    },
    staleTime: 30000,
    enabled: options?.enabled ?? true,
  });
};