/** * AI Recommendation Engine * Analyzes user assessment data and generates personalized, prioritized recommendations * using decision-tree logic based on real emission factors */ import { EMISSION_FACTORS } from './carbonCalculator.js'; const PRIORITY = { HIGH: 'HIGH', MEDIUM: 'MEDIUM', LOW: 'LOW' }; /** * Generate personalized recommendations from assessment data and calculated emissions * @param {Object} assessmentData - user input data * @param {Object} emissions - calculated emission breakdown * @returns {Array} sorted array of recommendation objects */ export function generateRecommendations(assessmentData, emissions) { const recommendations = []; // === TRANSPORTATION RECOMMENDATIONS === _analyzeTransport(assessmentData, emissions, recommendations); // === ENERGY RECOMMENDATIONS === _analyzeEnergy(assessmentData, emissions, recommendations); // === FOOD RECOMMENDATIONS === _analyzeFood(assessmentData, emissions, recommendations); // === SHOPPING RECOMMENDATIONS === _analyzeShopping(assessmentData, emissions, recommendations); // Sort: HIGH priority first, then by estimated savings descending return recommendations.sort((a, b) => { const priorityOrder = { HIGH: 0, MEDIUM: 1, LOW: 2 }; const priorityDiff = priorityOrder[a.priority] - priorityOrder[b.priority]; if (priorityDiff !== 0) return priorityDiff; return b.estimatedSavings - a.estimatedSavings; }); } function _analyzeTransport(data, emissions, recs) { const { dailyCarKm = 0, carFuelType = 'none', publicTransportKmPerWeek = 0, shortFlightsPerYear = 0, longFlightsPerYear = 0, cyclingKmPerWeek: _cyclingKmPerWeek = 0, } = data; const totalFlights = shortFlightsPerYear + longFlightsPerYear; const flightEmission = shortFlightsPerYear * EMISSION_FACTORS.flight.short_haul + longFlightsPerYear * EMISSION_FACTORS.flight.long_haul; // 1. EV switch recommendation if (dailyCarKm > 10 && carFuelType === 'petrol') { const currentCarEmission = dailyCarKm * EMISSION_FACTORS.car.petrol * 365; const evCarEmission = dailyCarKm * EMISSION_FACTORS.car.electric * 365; const savings = Math.round(currentCarEmission - evCarEmission); recs.push({ title: 'Switch to an Electric Vehicle', description: `You drive ${dailyCarKm}km daily on petrol, generating ~${Math.round(currentCarEmission)}kg CO₂/year. An EV running on grid electricity would cut this by ~75%, saving ${savings}kg annually.`, estimatedSavings: savings, priority: savings > 1500 ? PRIORITY.HIGH : PRIORITY.MEDIUM, category: 'transport', }); } if (dailyCarKm > 10 && carFuelType === 'diesel') { const currentCarEmission = dailyCarKm * EMISSION_FACTORS.car.diesel * 365; const evCarEmission = dailyCarKm * EMISSION_FACTORS.car.electric * 365; const savings = Math.round(currentCarEmission - evCarEmission); recs.push({ title: 'Switch to an Electric Vehicle', description: `Your diesel vehicle contributes ~${Math.round(currentCarEmission)}kg CO₂/year. Switching to an EV could save ${savings}kg annually and reduce urban air pollution.`, estimatedSavings: savings, priority: savings > 1200 ? PRIORITY.HIGH : PRIORITY.MEDIUM, category: 'transport', }); } // 2. Cycling recommendation if (dailyCarKm > 3 && carFuelType !== 'none') { const carFactor = EMISSION_FACTORS.car[carFuelType] ?? 0.21; // Assume 30% of short trips could be cycled const cyclableKmPerDay = Math.min(dailyCarKm * 0.3, 5); const savings = Math.round(cyclableKmPerDay * carFactor * 365); recs.push({ title: 'Replace Short Trips with Cycling or Walking', description: `Cycling or walking for journeys under 5km instead of driving could save ~${savings}kg CO₂/year while improving your health and reducing congestion.`, estimatedSavings: savings, priority: PRIORITY.MEDIUM, category: 'transport', }); } // 3. Public transport recommendation if (dailyCarKm > 15 && publicTransportKmPerWeek < 20 && carFuelType !== 'electric') { const carFactor = EMISSION_FACTORS.car[carFuelType] ?? 0.21; const potentialPTKm = dailyCarKm * 5; // weekday trips const savings = Math.round(potentialPTKm * 52 * (carFactor - EMISSION_FACTORS.publicTransport)); recs.push({ title: 'Use Public Transport for Commuting', description: `Switching even 2 days/week to public transport for your ${dailyCarKm}km daily commute could save ~${savings}kg CO₂/year and reduce traffic stress.`, estimatedSavings: Math.max(0, savings), priority: savings > 800 ? PRIORITY.HIGH : PRIORITY.MEDIUM, category: 'transport', }); } // 4. Flight reduction if (totalFlights >= 2) { const savings = Math.round(flightEmission * 0.5); recs.push({ title: 'Reduce Air Travel by 50%', description: `Your ${totalFlights} annual flight${totalFlights > 1 ? 's' : ''} contribute ~${Math.round(flightEmission)}kg CO₂. Cutting flights in half through video calls, trains, or choosing fewer trips saves ${savings}kg annually.`, estimatedSavings: savings, priority: flightEmission > 2000 ? PRIORITY.HIGH : PRIORITY.MEDIUM, category: 'transport', }); } if (longFlightsPerYear >= 1) { recs.push({ title: 'Choose Train Over Short-Haul Flights', description: `A long-haul flight emits ~1,620kg CO₂. For routes under 800km, trains emit 75–90% less CO₂ and are often as fast door-to-door.`, estimatedSavings: Math.round(longFlightsPerYear * 1620 * 0.85), priority: PRIORITY.HIGH, category: 'transport', }); } // 5. Carpool suggestion if (dailyCarKm > 20 && publicTransportKmPerWeek < 10 && carFuelType !== 'electric') { const carFactor = EMISSION_FACTORS.car[carFuelType] ?? 0.21; const savings = Math.round(dailyCarKm * carFactor * 365 * 0.35); recs.push({ title: 'Start Carpooling', description: `Sharing your commute with just one other person halves both your per-person emissions and fuel costs, saving an estimated ${savings}kg CO₂/year.`, estimatedSavings: savings, priority: PRIORITY.LOW, category: 'transport', }); } } function _analyzeEnergy(data, emissions, recs) { const { monthlyElectricityKwh = 0, renewablePercentage = 0 } = data; const annualKwh = monthlyElectricityKwh * 12; // 1. Renewable energy tariff if (renewablePercentage < 50 && monthlyElectricityKwh > 100) { const currentEmission = annualKwh * 0.233 * (1 - renewablePercentage / 100); const renewableEmission = annualKwh * 0.233 * 0.1; const savings = Math.round(currentEmission - renewableEmission); recs.push({ title: 'Switch to a 100% Renewable Energy Tariff', description: `Only ${renewablePercentage}% of your electricity comes from renewables. Switching to a green tariff costs little to nothing extra but can save ~${savings}kg CO₂/year immediately.`, estimatedSavings: savings, priority: savings > 600 ? PRIORITY.HIGH : PRIORITY.MEDIUM, category: 'energy', }); } // 2. Solar panels if (renewablePercentage < 30 && monthlyElectricityKwh > 200) { const savings = Math.round(emissions.energyEmission * 0.7); recs.push({ title: 'Install Solar Panels', description: `With your electricity consumption of ${monthlyElectricityKwh}kWh/month, rooftop solar panels could generate 70-80% of your electricity needs and save ~${savings}kg CO₂/year.`, estimatedSavings: savings, priority: PRIORITY.HIGH, category: 'energy', }); } // 3. Reduce consumption if (monthlyElectricityKwh > 300) { const savings = Math.round( monthlyElectricityKwh * 0.25 * 12 * 0.233 * (1 - renewablePercentage / 100) ); recs.push({ title: 'Reduce Home Electricity Consumption', description: `Your usage of ${monthlyElectricityKwh}kWh/month is above average. Upgrading to LED lighting, smart thermostats, and A-rated appliances can reduce consumption by 20-30%, saving ~${savings}kg CO₂/year.`, estimatedSavings: Math.max(0, savings), priority: PRIORITY.MEDIUM, category: 'energy', }); } // 4. Smart heating if (monthlyElectricityKwh > 150) { recs.push({ title: 'Install a Smart Thermostat', description: 'Smart thermostats learn your schedule and can reduce heating and cooling energy use by 10-15%, with typical savings of 150-400kg CO₂/year depending on home size.', estimatedSavings: Math.round(emissions.energyEmission * 0.12), priority: PRIORITY.LOW, category: 'energy', }); } } function _analyzeFood(data, emissions, recs) { const { dietType = 'mixed' } = data; if (dietType === 'heavy_meat') { recs.push({ title: 'Reduce Red Meat Consumption', description: 'A heavy meat diet generates ~3,300kg CO₂/year from food alone. Cutting beef and lamb to twice a week while keeping other meat saves ~800kg CO₂/year — one of the highest-impact individual changes.', estimatedSavings: 800, priority: PRIORITY.HIGH, category: 'food', }); recs.push({ title: 'Try Meat-Free Mondays', description: 'Going vegetarian just one day per week saves ~150kg CO₂/year. Extending to 3 meat-free days reduces your diet footprint by over 600kg annually.', estimatedSavings: 500, priority: PRIORITY.MEDIUM, category: 'food', }); } if (dietType === 'mixed') { recs.push({ title: 'Adopt a Vegetarian Diet', description: 'Switching from a mixed to vegetarian diet saves ~800kg CO₂/year. Plant proteins like beans, lentils and tofu have 10-20x lower carbon footprints than beef.', estimatedSavings: 800, priority: PRIORITY.MEDIUM, category: 'food', }); } if (dietType !== 'vegan') { recs.push({ title: 'Reduce Food Waste', description: 'Around 30% of food is wasted globally. Meal planning, proper storage and composting can reduce your food footprint by 10-15%, saving ~150-300kg CO₂/year.', estimatedSavings: Math.round(EMISSION_FACTORS.food[dietType] * 0.12), priority: PRIORITY.LOW, category: 'food', }); recs.push({ title: 'Choose Local & Seasonal Produce', description: 'Out-of-season produce shipped by air can have 50x higher emissions than local seasonal equivalents. Shopping at farmers markets and choosing seasonal food reduces transport emissions.', estimatedSavings: Math.round(EMISSION_FACTORS.food[dietType] * 0.08), priority: PRIORITY.LOW, category: 'food', }); } } function _analyzeShopping(data, emissions, recs) { const { clothingItemsPerYear = 0, electronicsItemsPerYear = 0 } = data; if (clothingItemsPerYear > 10) { const savings = Math.round(clothingItemsPerYear * EMISSION_FACTORS.clothing * 0.6); recs.push({ title: 'Buy Second-Hand Clothing', description: `You buy ~${clothingItemsPerYear} clothing items per year. Sourcing 60% from charity shops, vintage stores or clothing swaps saves ~${savings}kg CO₂/year while reducing textile waste.`, estimatedSavings: savings, priority: clothingItemsPerYear > 20 ? PRIORITY.MEDIUM : PRIORITY.LOW, category: 'shopping', }); } if (electronicsItemsPerYear >= 2) { const savings = Math.round(electronicsItemsPerYear * EMISSION_FACTORS.electronics * 0.5); recs.push({ title: 'Repair & Extend Electronics Lifespan', description: `Manufacturing ${electronicsItemsPerYear} devices/year contributes ~${electronicsItemsPerYear * EMISSION_FACTORS.electronics}kg CO₂. Repairing devices and buying refurbished saves ~${savings}kg CO₂/year and significant money.`, estimatedSavings: savings, priority: PRIORITY.MEDIUM, category: 'shopping', }); } if (clothingItemsPerYear > 5 || electronicsItemsPerYear >= 1) { recs.push({ title: 'Choose Products with Lower Carbon Footprints', description: 'Look for products with eco-certifications, made from recycled materials, or manufactured locally. Even small changes in purchasing habits compound over time.', estimatedSavings: Math.round(emissions.shoppingEmission * 0.15), priority: PRIORITY.LOW, category: 'shopping', }); } }