// Live website copy and pricing. The static marketing site reads this from the
// quote-engine backend through the same-origin /api rewrite in vercel.json.

const DEFAULT_LIVE_SYSTEMS = {
  tiers: [
    { panels:10, battery:'Sigen 6.0', batteryKwh:6.02, pricesBeforeGrant:{ slate:10850, tile:10400, metal:9950 } },
    { panels:12, battery:'Sigen 9.0', batteryKwh:9.04, pricesBeforeGrant:{ slate:11850, tile:11300, metal:10800 } },
    { panels:14, battery:'Sigen 9.0', batteryKwh:9.04, pricesBeforeGrant:{ slate:12450, tile:11850, metal:11250 } },
    { panels:16, battery:'Sigen 9.0', batteryKwh:9.04, pricesBeforeGrant:{ slate:13100, tile:12400, metal:11750 } },
    { panels:18, battery:'Sigen 9.0', batteryKwh:9.04, pricesBeforeGrant:{ slate:13700, tile:12950, metal:12200 } },
    { panels:20, battery:'Sigen 9.0', batteryKwh:9.04, pricesBeforeGrant:{ slate:14350, tile:13500, metal:12600 } },
  ],
  bands: [
    { minBill:100, maxBill:160, panels:10 }, { minBill:161, maxBill:200, panels:12 },
    { minBill:201, maxBill:240, panels:14 }, { minBill:241, maxBill:290, panels:16 },
    { minBill:291, maxBill:340, panels:18 }, { minBill:341, maxBill:null, panels:20 },
  ],
  model: {
    panelWattage:470, yieldKwhPerKwp:851.064, unitRate:0.36, standingChargePerMonth:25,
    selfConsumptionRatio:0.7, batteryRoutedShare:0.6, batteryRoundTrip:0.92, exportRate:0.185,
    degradationPerYear:0.005, electricityInflation:0.02, projectionYears:25,
    priceRangeLowerEur:200, priceRangeUpperEur:500, priceRangeRoundingEur:50,
    minBillForRecommendation:100, sliderMinBill:50, sliderMaxBill:500, sliderStepEur:10, sliderDefaultBill:180,
  },
};

const DEFAULT_LIVE_PRICING = {
  grantTier1PerKwp:700, grantTier1Kwp:2, grantTier2PerKwp:200, grantTier2Kwp:4, grantCap:1800,
};

let liveSiteConfig = { systems:DEFAULT_LIVE_SYSTEMS, pricing:DEFAULT_LIVE_PRICING, content:{} };
let liveSitePromise = null;
const liveSiteListeners = new Set();

function loadLiveSiteConfig() {
  if (!liveSitePromise) {
    liveSitePromise = fetch('/api/site-config', { headers:{ Accept:'application/json' } })
      .then(response => {
        if (!response.ok) throw new Error('Website configuration unavailable');
        return response.json();
      })
      .then(value => {
        liveSiteConfig = {
          systems: value.systems || DEFAULT_LIVE_SYSTEMS,
          pricing: value.pricing || DEFAULT_LIVE_PRICING,
          content: value.content || {},
        };
        liveSiteListeners.forEach(listener => listener(liveSiteConfig));
        return liveSiteConfig;
      })
      .catch(() => liveSiteConfig);
  }
  return liveSitePromise;
}

function useSiteConfig() {
  const [value, setValue] = React.useState(liveSiteConfig);
  React.useEffect(() => {
    liveSiteListeners.add(setValue);
    loadLiveSiteConfig();
    return () => liveSiteListeners.delete(setValue);
  }, []);
  return value;
}

function seaiGrant(kwp, pricing=DEFAULT_LIVE_PRICING) {
  const first = Math.min(kwp, pricing.grantTier1Kwp) * pricing.grantTier1PerKwp;
  const second = Math.max(0, Math.min(kwp, pricing.grantTier2Kwp) - pricing.grantTier1Kwp) * pricing.grantTier2PerKwp;
  return Math.min(pricing.grantCap, Math.round(first + second));
}

function roundDown(value, increment) { return Math.floor(value / increment) * increment; }
function roundUp(value, increment) { return Math.ceil(value / increment) * increment; }

function configuredQuote(monthlyBill, roofType='tile', config=liveSiteConfig) {
  const systems = config.systems || DEFAULT_LIVE_SYSTEMS;
  const pricing = config.pricing || DEFAULT_LIVE_PRICING;
  const model = systems.model;
  const band = systems.bands.find(item => monthlyBill >= item.minBill && (item.maxBill === null || monthlyBill <= item.maxBill));
  const tier = band && systems.tiers.find(item => item.panels === band.panels);
  if (!tier) return null;

  const kwp = tier.panels * model.panelWattage / 1000;
  const production = Math.round(kwp * model.yieldKwhPerKwp);
  const grant = seaiGrant(kwp, pricing);
  const listPrice = tier.pricesBeforeGrant[roofType] ?? tier.pricesBeforeGrant.tile;
  const netPrice = Math.max(0, listPrice - grant);
  const rounding = model.priceRangeRoundingEur || 50;
  const priceLow = roundDown(Math.max(0, netPrice - model.priceRangeLowerEur), rounding);
  const priceHigh = roundUp(netPrice + model.priceRangeUpperEur, rounding);
  const annualUsage = Math.max(0, ((monthlyBill - model.standingChargePerMonth) * 12) / model.unitRate);
  const selfUsed = Math.min(annualUsage, production * model.selfConsumptionRatio);
  const directUsed = selfUsed * (1 - model.batteryRoutedShare);
  const batteryUsed = selfUsed * model.batteryRoutedShare * model.batteryRoundTrip;
  const exported = Math.max(0, production - selfUsed);
  const annualSaving = Math.round(Math.min(monthlyBill * 12, (directUsed + batteryUsed) * model.unitRate + exported * model.exportRate));
  let cumulative = 0;
  let paybackYears = model.projectionYears;
  for (let year=0; year<model.projectionYears; year++) {
    cumulative += annualSaving * Math.pow(1 - model.degradationPerYear, year) * Math.pow(1 + model.electricityInflation, year);
    if (cumulative >= netPrice && paybackYears === model.projectionYears) paybackYears = year + 1;
  }
  return { tier, band, kwp, production, grant, netPrice, priceLow, priceHigh, annualSaving, paybackYears, lifetimeSaving:Math.round(cumulative) };
}

function livePricingCards(config=liveSiteConfig) {
  const systems = config.systems || DEFAULT_LIVE_SYSTEMS;
  return systems.bands.map((band, index) => {
    const bill = band.maxBill === null ? Math.max(band.minBill, systems.model.sliderMaxBill) : Math.round((band.minBill + band.maxBill) / 2);
    const quote = configuredQuote(bill, 'tile', config);
    return quote && {
      ...quote,
      billLabel: band.maxBill === null ? `€${band.minBill}+ / month bill` : `€${band.minBill}–€${band.maxBill} / month bill`,
      featured: index === Math.floor(systems.bands.length / 2),
    };
  }).filter(Boolean);
}

window.useSiteConfig = useSiteConfig;
window.configuredQuote = configuredQuote;
window.livePricingCards = livePricingCards;
window.loadLiveSiteConfig = loadLiveSiteConfig;
