/**
 * Sustainability API Service - Microservices Architecture
 * Fetches data from production and inventory services in parallel
 * Performs client-side aggregation of sustainability metrics
 */

import apiClient from '../client/apiClient';
import type {
  SustainabilityMetrics,
  SustainabilityWidgetData,
  SDGCompliance,
  EnvironmentalImpact,
  GrantReport,
  WasteMetrics,
  FinancialImpact,
  AvoidedWaste,
  GrantReadiness
} from '../types/sustainability';

// ===== SERVICE-SPECIFIC API CALLS =====

/**
 * Production Service: Get production waste metrics
 */
export async function getProductionWasteMetrics(
  tenantId: string,
  startDate?: string,
  endDate?: string
): Promise<any> {
  const params = new URLSearchParams();
  if (startDate) params.append('start_date', startDate);
  if (endDate) params.append('end_date', endDate);

  const queryString = params.toString();
  const url = `/tenants/${tenantId}/production/sustainability/waste-metrics${queryString ? `?${queryString}` : ''}`;

  return await apiClient.get<any>(url);
}

/**
 * Production Service: Get production baseline metrics
 */
export async function getProductionBaseline(
  tenantId: string,
  startDate?: string,
  endDate?: string
): Promise<any> {
  const params = new URLSearchParams();
  if (startDate) params.append('start_date', startDate);
  if (endDate) params.append('end_date', endDate);

  const queryString = params.toString();
  const url = `/tenants/${tenantId}/production/sustainability/baseline${queryString ? `?${queryString}` : ''}`;

  return await apiClient.get<any>(url);
}

/**
 * Production Service: Get AI impact on waste reduction
 */
export async function getProductionAIImpact(
  tenantId: string,
  startDate?: string,
  endDate?: string
): Promise<any> {
  const params = new URLSearchParams();
  if (startDate) params.append('start_date', startDate);
  if (endDate) params.append('end_date', endDate);

  const queryString = params.toString();
  const url = `/tenants/${tenantId}/production/sustainability/ai-impact${queryString ? `?${queryString}` : ''}`;

  return await apiClient.get<any>(url);
}

/**
 * Production Service: Get summary widget data
 */
export async function getProductionSummary(
  tenantId: string,
  days: number = 30
): Promise<any> {
  return await apiClient.get<any>(
    `/tenants/${tenantId}/production/sustainability/summary?days=${days}`
  );
}

/**
 * Inventory Service: Get inventory waste metrics
 */
export async function getInventoryWasteMetrics(
  tenantId: string,
  startDate?: string,
  endDate?: string
): Promise<any> {
  const params = new URLSearchParams();
  if (startDate) params.append('start_date', startDate);
  if (endDate) params.append('end_date', endDate);

  const queryString = params.toString();
  const url = `/tenants/${tenantId}/inventory/sustainability/waste-metrics${queryString ? `?${queryString}` : ''}`;

  return await apiClient.get<any>(url);
}

/**
 * Inventory Service: Get expiry alerts
 */
export async function getInventoryExpiryAlerts(
  tenantId: string,
  daysAhead: number = 7
): Promise<any> {
  return await apiClient.get<any>(
    `/tenants/${tenantId}/inventory/sustainability/expiry-alerts?days_ahead=${daysAhead}`
  );
}

/**
 * Inventory Service: Get waste events
 */
export async function getInventoryWasteEvents(
  tenantId: string,
  limit: number = 50,
  offset: number = 0,
  startDate?: string,
  endDate?: string,
  reasonCode?: string
): Promise<any> {
  const params = new URLSearchParams();
  params.append('limit', limit.toString());
  params.append('offset', offset.toString());
  if (startDate) params.append('start_date', startDate);
  if (endDate) params.append('end_date', endDate);
  if (reasonCode) params.append('reason_code', reasonCode);

  const queryString = params.toString();
  const url = `/tenants/${tenantId}/inventory/sustainability/waste-events?${queryString}`;

  return await apiClient.get<any>(url);
}

/**
 * Inventory Service: Get summary widget data
 */
export async function getInventorySummary(
  tenantId: string,
  days: number = 30
): Promise<any> {
  return await apiClient.get<any>(
    `/tenants/${tenantId}/inventory/sustainability/summary?days=${days}`
  );
}

// ===== AGGREGATION FUNCTIONS =====

/**
 * Environmental Constants for calculations
 */
const EnvironmentalConstants = {
  CO2_PER_KG_WASTE: 1.9,  // kg CO2e per kg waste
  WATER_PER_KG: 1500,     // liters per kg
  LAND_USE_PER_KG: 3.4,   // m² per kg
  TREES_PER_TON_CO2: 50,
  SDG_TARGET_REDUCTION: 0.50,  // 50% reduction target
  EU_BAKERY_BASELINE_WASTE: 0.25,  // 25% baseline
  MINIMUM_PRODUCTION_KG: 50  // Minimum production to show meaningful metrics
};

/**
 * Calculate environmental impact from total waste
 */
function calculateEnvironmentalImpact(totalWasteKg: number): EnvironmentalImpact {
  const co2Kg = totalWasteKg * EnvironmentalConstants.CO2_PER_KG_WASTE;
  const co2Tons = co2Kg / 1000;
  const waterLiters = totalWasteKg * EnvironmentalConstants.WATER_PER_KG;
  const landSqMeters = totalWasteKg * EnvironmentalConstants.LAND_USE_PER_KG;

  return {
    co2_emissions: {
      kg: Math.round(co2Kg * 100) / 100,
      tons: Math.round(co2Tons * 1000) / 1000,
      trees_to_offset: Math.ceil(co2Tons * EnvironmentalConstants.TREES_PER_TON_CO2)
    },
    water_footprint: {
      liters: Math.round(waterLiters),
      cubic_meters: Math.round(waterLiters / 1000 * 100) / 100
    },
    land_use: {
      square_meters: Math.round(landSqMeters * 100) / 100,
      hectares: Math.round(landSqMeters / 10000 * 1000) / 1000
    },
    human_equivalents: {
      car_km_equivalent: Math.round(co2Kg / 0.120),  // 120g CO2 per km
      smartphone_charges: Math.round(co2Kg * 1000 / 8),  // 8g CO2 per charge
      showers_equivalent: Math.round(waterLiters / 65),  // 65L per shower
      trees_planted: Math.ceil(co2Tons * EnvironmentalConstants.TREES_PER_TON_CO2)
    }
  };
}

/**
 * Calculate SDG compliance status
 */
function calculateSDGCompliance(
  currentWastePercentage: number,
  baselineWastePercentage: number
): SDGCompliance {
  const reductionAchieved = baselineWastePercentage > 0
    ? ((baselineWastePercentage - currentWastePercentage) / baselineWastePercentage) * 100
    : 0;

  const targetReduction = EnvironmentalConstants.SDG_TARGET_REDUCTION * 100;  // 50%
  const progressToTarget = Math.max(0, Math.min(100, (reductionAchieved / targetReduction) * 100));

  let status: 'sdg_compliant' | 'on_track' | 'progressing' | 'baseline' | 'above_baseline' = 'baseline';
  let statusLabel = 'Establishing Baseline';

  if (reductionAchieved >= targetReduction) {
    status = 'sdg_compliant';
    statusLabel = 'SDG Compliant';
  } else if (reductionAchieved >= 30) {
    status = 'on_track';
    statusLabel = 'On Track';
  } else if (reductionAchieved >= 10) {
    status = 'progressing';
    statusLabel = 'Progressing';
  } else if (reductionAchieved > 0) {
    status = 'baseline';
    statusLabel = 'Improving from Baseline';
  } else if (reductionAchieved < 0) {
    status = 'above_baseline';
    statusLabel = 'Above Baseline';
  }

  return {
    sdg_12_3: {
      baseline_waste_percentage: Math.round(baselineWastePercentage * 100) / 100,
      current_waste_percentage: Math.round(currentWastePercentage * 100) / 100,
      reduction_achieved: Math.round(reductionAchieved * 100) / 100,
      target_reduction: targetReduction,
      progress_to_target: Math.round(progressToTarget * 100) / 100,
      status,
      status_label: statusLabel,
      target_waste_percentage: baselineWastePercentage * (1 - EnvironmentalConstants.SDG_TARGET_REDUCTION)
    },
    baseline_period: 'first_90_days',
    certification_ready: status === 'sdg_compliant',
    improvement_areas: status === 'sdg_compliant' ? [] : ['reduce_waste_further']
  };
}

/**
 * Assess grant readiness based on SDG compliance
 */
function assessGrantReadiness(sdgCompliance: SDGCompliance): GrantReadiness {
  const reductionAchieved = sdgCompliance.sdg_12_3.reduction_achieved;
  const isSdgCompliant = sdgCompliance.certification_ready;

  const grantPrograms: Record<string, any> = {
    life_circular_economy: {
      eligible: reductionAchieved >= 30,
      confidence: reductionAchieved >= 40 ? 'high' : reductionAchieved >= 30 ? 'medium' : 'low',
      requirements_met: reductionAchieved >= 30,
      funding_eur: 73_000_000,
      deadline: '2025-09-23',
      program_type: 'grant'
    },
    horizon_europe_cluster_6: {
      eligible: isSdgCompliant,
      confidence: isSdgCompliant ? 'high' : 'low',
      requirements_met: isSdgCompliant,
      funding_eur: 880_000_000,
      deadline: 'rolling_2025',
      program_type: 'grant'
    },
    fedima_sustainability_grant: {
      eligible: reductionAchieved >= 20,
      confidence: reductionAchieved >= 25 ? 'high' : reductionAchieved >= 20 ? 'medium' : 'low',
      requirements_met: reductionAchieved >= 20,
      funding_eur: 20_000,
      deadline: '2025-06-30',
      program_type: 'grant',
      sector_specific: 'bakery'
    },
    eit_food_retail: {
      eligible: reductionAchieved >= 15,
      confidence: reductionAchieved >= 20 ? 'high' : reductionAchieved >= 15 ? 'medium' : 'low',
      requirements_met: reductionAchieved >= 15,
      funding_eur: 45_000,
      deadline: 'rolling',
      program_type: 'grant',
      sector_specific: 'retail'
    },
    un_sdg_certified: {
      eligible: isSdgCompliant,
      confidence: isSdgCompliant ? 'high' : 'low',
      requirements_met: isSdgCompliant,
      funding_eur: 0,
      deadline: 'ongoing',
      program_type: 'certification'
    }
  };

  const recommendedApplications = Object.entries(grantPrograms)
    .filter(([_, program]) => program.eligible && program.confidence !== 'low')
    .map(([name, _]) => name);

  const eligibleCount = Object.values(grantPrograms).filter(p => p.eligible).length;
  const overallReadiness = (eligibleCount / Object.keys(grantPrograms).length) * 100;

  return {
    overall_readiness_percentage: Math.round(overallReadiness),
    grant_programs: grantPrograms,
    recommended_applications: recommendedApplications,
    spain_compliance: {
      law_1_2025: reductionAchieved >= 50,
      circular_economy_strategy: reductionAchieved >= 30
    }
  };
}

// ===== MAIN AGGREGATION FUNCTION =====

/**
 * Get default metrics for insufficient data state
 */
function getInsufficientDataMetrics(
  totalProductionKg: number,
  startDate?: string,
  endDate?: string
): SustainabilityMetrics {
  return {
    period: {
      start_date: startDate || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
      end_date: endDate || new Date().toISOString(),
      days: 30
    },
    waste_metrics: {
      total_waste_kg: 0,
      production_waste_kg: 0,
      expired_waste_kg: 0,
      waste_percentage: 0,
      waste_by_reason: {}
    },
    environmental_impact: {
      co2_emissions: { kg: 0, tons: 0, trees_to_offset: 0 },
      water_footprint: { liters: 0, cubic_meters: 0 },
      land_use: { square_meters: 0, hectares: 0 },
      human_equivalents: { car_km_equivalent: 0, smartphone_charges: 0, showers_equivalent: 0, trees_planted: 0 }
    },
    sdg_compliance: {
      sdg_12_3: {
        baseline_waste_percentage: 0,
        current_waste_percentage: 0,
        reduction_achieved: 0,
        target_reduction: 50,
        progress_to_target: 0,
        status: 'baseline',
        status_label: 'Collecting Baseline Data',
        target_waste_percentage: 0
      },
      baseline_period: 'not_available',
      certification_ready: false,
      improvement_areas: ['start_production_tracking']
    },
    avoided_waste: {
      waste_avoided_kg: 0,
      ai_assisted_batches: 0,
      environmental_impact_avoided: { co2_kg: 0, water_liters: 0 },
      methodology: 'insufficient_data'
    },
    financial_impact: {
      waste_cost_eur: 0,
      cost_per_kg: 3.50,
      potential_monthly_savings: 0,
      annual_projection: 0
    },
    grant_readiness: {
      overall_readiness_percentage: 0,
      grant_programs: {
        life_circular_economy: { eligible: false, confidence: 'low', requirements_met: false, funding_eur: 73_000_000 },
        horizon_europe_cluster_6: { eligible: false, confidence: 'low', requirements_met: false, funding_eur: 880_000_000 },
        fedima_sustainability_grant: { eligible: false, confidence: 'low', requirements_met: false, funding_eur: 20_000 },
        eit_food_retail: { eligible: false, confidence: 'low', requirements_met: false, funding_eur: 45_000 },
        un_sdg_certified: { eligible: false, confidence: 'low', requirements_met: false, funding_eur: 0 }
      },
      recommended_applications: [],
      spain_compliance: { law_1_2025: false, circular_economy_strategy: false }
    },
    data_sufficient: false,
    minimum_production_required_kg: EnvironmentalConstants.MINIMUM_PRODUCTION_KG,
    current_production_kg: totalProductionKg
  };
}

/**
 * Get comprehensive sustainability metrics by aggregating production and inventory data
 */
export async function getSustainabilityMetrics(
  tenantId: string,
  startDate?: string,
  endDate?: string
): Promise<SustainabilityMetrics> {
  try {
    // Fetch data from both services in parallel
    const [productionData, inventoryData, productionBaseline, aiImpact] = await Promise.all([
      getProductionWasteMetrics(tenantId, startDate, endDate),
      getInventoryWasteMetrics(tenantId, startDate, endDate),
      getProductionBaseline(tenantId, startDate, endDate),
      getProductionAIImpact(tenantId, startDate, endDate)
    ]);

    // Calculate total production
    const totalProductionKg = productionData.total_planned || 0;

    // Check if we have sufficient data for meaningful metrics
    // Minimum: 50kg production to avoid false metrics on empty accounts
    const hasDataSufficient = totalProductionKg >= EnvironmentalConstants.MINIMUM_PRODUCTION_KG;

    // If insufficient data, return a "collecting data" state
    if (!hasDataSufficient) {
      return getInsufficientDataMetrics(totalProductionKg, startDate, endDate);
    }

    // Aggregate waste metrics
    const productionWaste = (productionData.total_production_waste || 0) + (productionData.total_defects || 0);
    const totalWasteKg = productionWaste + (inventoryData.inventory_waste_kg || 0);

    const wastePercentage = totalProductionKg > 0
      ? (totalWasteKg / totalProductionKg) * 100
      : 0;

    const wasteMetrics: WasteMetrics = {
      total_waste_kg: Math.round(totalWasteKg * 100) / 100,
      production_waste_kg: Math.round(productionWaste * 100) / 100,
      expired_waste_kg: Math.round((inventoryData.inventory_waste_kg || 0) * 100) / 100,
      waste_percentage: Math.round(wastePercentage * 100) / 100,
      waste_by_reason: {
        ...(productionData.waste_by_defect_type || {}),
        ...(inventoryData.waste_by_reason || {})
      }
    };

    // Calculate environmental impact
    const environmentalImpact = calculateEnvironmentalImpact(totalWasteKg);

    // Calculate SDG compliance
    const baselineWastePercentage = productionBaseline.waste_percentage ||
      EnvironmentalConstants.EU_BAKERY_BASELINE_WASTE * 100;
    const sdgCompliance = calculateSDGCompliance(wastePercentage, baselineWastePercentage);

    // Calculate avoided waste from AI
    const wasteAvoidedKg = aiImpact.impact?.waste_avoided_kg || 0;
    const avoidedWaste: AvoidedWaste = {
      waste_avoided_kg: Math.round(wasteAvoidedKg * 100) / 100,
      ai_assisted_batches: aiImpact.ai_batches?.count || 0,
      environmental_impact_avoided: {
        co2_kg: Math.round(wasteAvoidedKg * EnvironmentalConstants.CO2_PER_KG_WASTE * 100) / 100,
        water_liters: Math.round(wasteAvoidedKg * EnvironmentalConstants.WATER_PER_KG)
      },
      methodology: 'ai_vs_manual_comparison'
    };

    // Calculate financial impact
    const inventoryCost = inventoryData.waste_cost_eur || 0;
    const productionCost = productionWaste * 3.50;  // €3.50/kg avg
    const totalCost = inventoryCost + productionCost;

    const financialImpact: FinancialImpact = {
      waste_cost_eur: Math.round(totalCost * 100) / 100,
      cost_per_kg: 3.50,
      potential_monthly_savings: Math.round((aiImpact.impact?.cost_savings_eur || 0) * 100) / 100,
      annual_projection: Math.round((aiImpact.impact?.cost_savings_eur || 0) * 12 * 100) / 100
    };

    // Assess grant readiness
    const grantReadiness = assessGrantReadiness(sdgCompliance);

    return {
      period: productionData.period || {
        start_date: startDate || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
        end_date: endDate || new Date().toISOString(),
        days: 30
      },
      waste_metrics: wasteMetrics,
      environmental_impact: environmentalImpact,
      sdg_compliance: sdgCompliance,
      avoided_waste: avoidedWaste,
      financial_impact: financialImpact,
      grant_readiness: grantReadiness,
      data_sufficient: true,
      minimum_production_required_kg: EnvironmentalConstants.MINIMUM_PRODUCTION_KG,
      current_production_kg: totalProductionKg
    };

  } catch (error) {
    console.error('Error aggregating sustainability metrics:', error);
    throw error;
  }
}

/**
 * Get simplified sustainability widget data
 */
export async function getSustainabilityWidgetData(
  tenantId: string,
  days: number = 30
): Promise<SustainabilityWidgetData> {
  try {
    // Fetch summaries from both services in parallel
    const [productionSummary, inventorySummary] = await Promise.all([
      getProductionSummary(tenantId, days),
      getInventorySummary(tenantId, days)
    ]);

    const productionWasteWidget = (productionSummary.total_production_waste || 0) + (productionSummary.total_defects || 0);
    const totalWasteKg = productionWasteWidget + (inventorySummary.inventory_waste_kg || 0);

    const totalProduction = productionSummary.total_planned || productionSummary.total_production_kg || 0;
    const wastePercentage = totalProduction > 0 ? ((totalWasteKg / totalProduction) * 100) : 0;

    const baselinePercentage = productionSummary.waste_percentage || 25;
    const reductionPercentage = baselinePercentage > 0
      ? ((baselinePercentage - wastePercentage) / baselinePercentage) * 100
      : 0;

    const co2SavedKg = totalWasteKg * EnvironmentalConstants.CO2_PER_KG_WASTE;
    const waterSavedLiters = totalWasteKg * EnvironmentalConstants.WATER_PER_KG;

    return {
      total_waste_kg: Math.round(totalWasteKg * 100) / 100,
      waste_reduction_percentage: Math.round(reductionPercentage * 100) / 100,
      co2_saved_kg: Math.round(co2SavedKg * 100) / 100,
      water_saved_liters: Math.round(waterSavedLiters),
      trees_equivalent: Math.ceil((co2SavedKg / 1000) * EnvironmentalConstants.TREES_PER_TON_CO2),
      sdg_status: reductionPercentage >= 50 ? 'sdg_compliant' :
                  reductionPercentage >= 37.5 ? 'on_track' :
                  reductionPercentage >= 12.5 ? 'progressing' : 'baseline',
      sdg_progress: Math.min(100, (reductionPercentage / 50) * 100),
      grant_programs_ready: reductionPercentage >= 50 ? 5 :
                            reductionPercentage >= 30 ? 3 :
                            reductionPercentage >= 15 ? 2 : 0,
      financial_savings_eur: Math.round(
        ((inventorySummary.waste_cost_eur || 0) + (productionWasteWidget * 3.50)) * 100
      ) / 100
    };

  } catch (error) {
    console.error('Error fetching sustainability widget data:', error);
    throw error;
  }
}

/**
 * Get SDG 12.3 compliance status
 */
export async function getSDGCompliance(tenantId: string): Promise<SDGCompliance> {
  const metrics = await getSustainabilityMetrics(tenantId);
  return metrics.sdg_compliance;
}

/**
 * Get environmental impact metrics
 */
export async function getEnvironmentalImpact(
  tenantId: string,
  days: number = 30
): Promise<EnvironmentalImpact> {
  const endDate = new Date().toISOString();
  const startDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();

  const metrics = await getSustainabilityMetrics(tenantId, startDate, endDate);
  return metrics.environmental_impact;
}

/**
 * Export grant application report
 * Note: This still uses the aggregated metrics approach
 */
export async function exportGrantReport(
  tenantId: string,
  grantType: string = 'general',
  startDate?: string,
  endDate?: string
): Promise<GrantReport> {
  const metrics = await getSustainabilityMetrics(tenantId, startDate, endDate);

  return {
    report_metadata: {
      generated_at: new Date().toISOString(),
      report_type: grantType,
      period: metrics.period,
      tenant_id: tenantId
    },
    executive_summary: {
      total_waste_reduced_kg: metrics.avoided_waste.waste_avoided_kg,
      waste_reduction_percentage: metrics.sdg_compliance.sdg_12_3.reduction_achieved,
      co2_emissions_avoided_kg: metrics.avoided_waste.environmental_impact_avoided.co2_kg,
      financial_savings_eur: metrics.financial_impact.potential_monthly_savings,
      sdg_compliance_status: metrics.sdg_compliance.sdg_12_3.status_label
    },
    detailed_metrics: metrics,
    certifications: {
      sdg_12_3_compliant: metrics.sdg_compliance.certification_ready,
      grant_programs_eligible: metrics.grant_readiness.recommended_applications
    },
    supporting_data: {
      baseline_comparison: {
        baseline: metrics.sdg_compliance.sdg_12_3.baseline_waste_percentage,
        current: metrics.sdg_compliance.sdg_12_3.current_waste_percentage,
        improvement: metrics.sdg_compliance.sdg_12_3.reduction_achieved
      },
      environmental_benefits: metrics.environmental_impact,
      financial_benefits: metrics.financial_impact
    }
  };
}
