/**
 * Smart Scaling Algorithm for Carbon Impact Comparisons
 *
 * Selects the most appropriate and meaningful comparisons
 * based on the amount of CO2 being offset.
 */

import {
  CARBON_EQUIVALENCIES,
  calculateEquivalency,
  formatEquivalencyValue,
} from './carbonEquivalencies';
import { CarbonComparison, ComparisonCategory } from '../types/carbonEquivalencies';

/**
 * All available comparison definitions
 */
const COMPARISON_DEFINITIONS: Record<string, Omit<CarbonComparison, 'value'>> = {
  // TRANSPORTATION
  MILES_DRIVEN: {
    category: ComparisonCategory.TRANSPORTATION,
    icon: 'Car',
    unit: 'miles',
    label: 'Miles driven in an average car',
    source: 'EPA 2024',
    priority: 5,
  },
  GALLONS_GASOLINE: {
    category: ComparisonCategory.TRANSPORTATION,
    icon: 'Fuel',
    unit: 'gallons',
    label: 'Gallons of gasoline not burned',
    source: 'EPA 2024',
    priority: 4,
  },

  // AVIATION
  FLIGHT_KM_SHORT: {
    category: ComparisonCategory.AVIATION,
    icon: 'Plane',
    unit: 'passenger-km',
    label: 'Short-haul flight distance (economy)',
    source: 'DEFRA 2024',
    priority: 5,
  },
  FLIGHT_KM_LONG: {
    category: ComparisonCategory.AVIATION,
    icon: 'PlaneTakeoff',
    unit: 'passenger-km',
    label: 'Long-haul flight distance (economy)',
    source: 'DEFRA 2024',
    priority: 5,
  },

  // NATURAL
  TREE_SEEDLINGS: {
    category: ComparisonCategory.NATURAL,
    icon: 'TreePine',
    unit: 'trees',
    label: 'Tree seedlings grown for 10 years',
    source: 'EPA 2024',
    priority: 5,
  },
  FOREST_ACRES_1YR: {
    category: ComparisonCategory.NATURAL,
    icon: 'Trees',
    unit: 'acres',
    label: 'Acres of forest preserved for 1 year',
    source: 'EPA 2024',
    priority: 4,
  },
  FOREST_ACRES_10YR: {
    category: ComparisonCategory.NATURAL,
    icon: 'Trees',
    unit: 'acres',
    label: 'Acres of forest carbon sequestration over 10 years',
    source: 'EPA 2024',
    priority: 3,
  },

  // ENERGY
  ELECTRICITY_KWH: {
    category: ComparisonCategory.ENERGY,
    icon: 'Zap',
    unit: 'kWh',
    label: 'Kilowatt-hours of electricity',
    source: 'EPA 2024',
    priority: 4,
  },
  HOME_ENERGY_YEARS: {
    category: ComparisonCategory.ENERGY,
    icon: 'Home',
    unit: 'home-years',
    label: 'Years of home electricity use',
    source: 'EPA 2024',
    priority: 5,
  },
  BARRELS_OIL: {
    category: ComparisonCategory.ENERGY,
    icon: 'Droplet',
    unit: 'barrels',
    label: 'Barrels of oil not consumed',
    source: 'EPA 2024',
    priority: 3,
  },

  // YACHT-SPECIFIC
  MGO_LITERS: {
    category: ComparisonCategory.YACHT_SPECIFIC,
    icon: 'Waves',
    unit: 'liters',
    label: 'Liters of Marine Gas Oil avoided',
    source: 'IMO 2024',
    priority: 5,
  },
  MGO_TONNES: {
    category: ComparisonCategory.YACHT_SPECIFIC,
    icon: 'Droplets',
    unit: 'tonnes',
    label: 'Tonnes of Marine Gas Oil avoided',
    source: 'IMO 2024',
    priority: 4,
  },
  CRUISING_HOURS: {
    category: ComparisonCategory.YACHT_SPECIFIC,
    icon: 'Anchor',
    unit: 'hours',
    label: 'Hours of 60m yacht cruising avoided',
    source: 'IMO 2024',
    priority: 5,
  },
  SUPERYACHT_NAUTICAL_MILES: {
    category: ComparisonCategory.YACHT_SPECIFIC,
    icon: 'Ship',
    unit: 'nautical miles',
    label: 'Nautical miles of superyacht voyaging',
    source: 'IMO 2024',
    priority: 4,
  },
  SHORE_POWER_DAYS: {
    category: ComparisonCategory.YACHT_SPECIFIC,
    icon: 'Battery',
    unit: 'days',
    label: 'Days of shore power for large yacht',
    source: 'IMO 2024',
    priority: 3,
  },

  // LIFESTYLE
  SMARTPHONE_CHARGES: {
    category: ComparisonCategory.LIFESTYLE,
    icon: 'Smartphone',
    unit: 'charges',
    label: 'Smartphone charges',
    source: 'EPA 2024',
    priority: 5,
  },
  POUNDS_COAL: {
    category: ComparisonCategory.LIFESTYLE,
    icon: 'Flame',
    unit: 'pounds',
    label: 'Pounds of coal not burned',
    source: 'EPA 2024',
    priority: 3,
  },
};

/**
 * Smart scaling ranges - different comparisons for different CO2 amounts
 */
const SCALING_RANGES = [
  {
    minTons: 0,
    maxTons: 0.1,
    comparisonKeys: ['MILES_DRIVEN', 'SMARTPHONE_CHARGES', 'TREE_SEEDLINGS'],
    rangeDescription: 'Very small offsets (< 0.1 tons)',
  },
  {
    minTons: 0.1,
    maxTons: 1,
    comparisonKeys: ['MILES_DRIVEN', 'TREE_SEEDLINGS', 'GALLONS_GASOLINE'],
    rangeDescription: 'Small offsets (0.1 - 1 tons)',
  },
  {
    minTons: 1,
    maxTons: 5,
    comparisonKeys: ['FLIGHT_KM_SHORT', 'TREE_SEEDLINGS', 'ELECTRICITY_KWH'],
    rangeDescription: 'Medium offsets (1 - 5 tons)',
  },
  {
    minTons: 5,
    maxTons: 20,
    comparisonKeys: ['FLIGHT_KM_LONG', 'FOREST_ACRES_1YR', 'MGO_LITERS'],
    rangeDescription: 'Large offsets (5 - 20 tons)',
  },
  {
    minTons: 20,
    maxTons: 100,
    comparisonKeys: ['CRUISING_HOURS', 'FOREST_ACRES_1YR', 'HOME_ENERGY_YEARS'],
    rangeDescription: 'Very large offsets (20 - 100 tons)',
  },
  {
    minTons: 100,
    maxTons: Infinity,
    comparisonKeys: ['FOREST_ACRES_10YR', 'CRUISING_HOURS', 'SUPERYACHT_NAUTICAL_MILES'],
    rangeDescription: 'Massive offsets (100+ tons)',
  },
];

/**
 * Select the most appropriate comparisons for the given CO2 amount
 *
 * @param tons - Metric tons of CO2e to offset
 * @param count - Number of comparisons to return (default: 3)
 * @returns Array of carbon comparisons with calculated values
 */
export function selectComparisons(tons: number, count: number = 3): CarbonComparison[] {
  // Find the appropriate range for this amount
  const range = SCALING_RANGES.find(
    (r) => tons >= r.minTons && tons < r.maxTons
  );

  if (!range) {
    console.warn(`No comparison range found for ${tons} tons, using default`);
    return getDefaultComparisons(tons, count);
  }

  // Get the comparison definitions for this range
  const comparisons: CarbonComparison[] = range.comparisonKeys
    .slice(0, count)
    .map((key) => {
      const definition = COMPARISON_DEFINITIONS[key];
      const factor = getFactorForKey(key);
      const value = calculateEquivalency(tons, factor);

      return {
        ...definition,
        value: parseFloat(formatEquivalencyValue(value)),
      };
    });

  return comparisons;
}

/**
 * Get the conversion factor for a comparison key
 */
function getFactorForKey(key: string): number {
  const factorMap: Record<string, number> = {
    MILES_DRIVEN: CARBON_EQUIVALENCIES.MILES_DRIVEN_AVG_CAR,
    GALLONS_GASOLINE: CARBON_EQUIVALENCIES.GALLONS_GASOLINE,
    FLIGHT_KM_SHORT: CARBON_EQUIVALENCIES.FLIGHT_KM_ECONOMY_SHORT,
    FLIGHT_KM_LONG: CARBON_EQUIVALENCIES.FLIGHT_KM_ECONOMY_LONG,
    TREE_SEEDLINGS: CARBON_EQUIVALENCIES.TREE_SEEDLINGS_10YR,
    FOREST_ACRES_1YR: CARBON_EQUIVALENCIES.FOREST_ACRES_1YR,
    FOREST_ACRES_10YR: CARBON_EQUIVALENCIES.FOREST_ACRES_10YR,
    ELECTRICITY_KWH: CARBON_EQUIVALENCIES.ELECTRICITY_KWH,
    HOME_ENERGY_YEARS: CARBON_EQUIVALENCIES.HOME_ENERGY_YEARS,
    BARRELS_OIL: CARBON_EQUIVALENCIES.BARRELS_OIL,
    MGO_LITERS: CARBON_EQUIVALENCIES.MGO_LITERS_AVOIDED,
    MGO_TONNES: CARBON_EQUIVALENCIES.MGO_TONNES_AVOIDED,
    CRUISING_HOURS: CARBON_EQUIVALENCIES.CRUISING_HOURS_60M,
    SUPERYACHT_NAUTICAL_MILES: CARBON_EQUIVALENCIES.SUPERYACHT_NAUTICAL_MILES,
    SHORE_POWER_DAYS: CARBON_EQUIVALENCIES.SHORE_POWER_DAYS,
    SMARTPHONE_CHARGES: CARBON_EQUIVALENCIES.SMARTPHONE_CHARGES,
    POUNDS_COAL: CARBON_EQUIVALENCIES.POUNDS_COAL_BURNED,
  };

  return factorMap[key] || 1;
}

/**
 * Get default comparisons when no range matches
 */
function getDefaultComparisons(tons: number, count: number): CarbonComparison[] {
  const defaultKeys = ['MILES_DRIVEN', 'TREE_SEEDLINGS', 'ELECTRICITY_KWH'];

  return defaultKeys.slice(0, count).map((key) => {
    const definition = COMPARISON_DEFINITIONS[key];
    const factor = getFactorForKey(key);
    const value = calculateEquivalency(tons, factor);

    return {
      ...definition,
      value: parseFloat(formatEquivalencyValue(value)),
    };
  });
}

/**
 * Get all available comparison categories
 */
export function getAvailableCategories(): ComparisonCategory[] {
  return Object.values(ComparisonCategory);
}

/**
 * Get comparisons by category
 */
export function getComparisonsByCategory(
  category: ComparisonCategory,
  tons: number
): CarbonComparison[] {
  const categoryKeys = Object.entries(COMPARISON_DEFINITIONS)
    .filter(([_, def]) => def.category === category)
    .map(([key]) => key);

  return categoryKeys.map((key) => {
    const definition = COMPARISON_DEFINITIONS[key];
    const factor = getFactorForKey(key);
    const value = calculateEquivalency(tons, factor);

    return {
      ...definition,
      value: parseFloat(formatEquivalencyValue(value)),
    };
  });
}
