/**
 * Climate projections for the ClimateDashboard component.
 * Add new cities here — each one exports a `CityProjection` ready to plug in.
 */

export type CityProjection = {
  /** Display name (e.g. "Paris"). */
  city: string;
  /** Region label shown under the city (e.g. "Île-de-France"). */
  region: string;
  /** Start year of the projection. */
  yearStart: number;
  /** End year of the projection. */
  yearEnd: number;
  /** Baseline summer mean temperature at yearStart, in °C. */
  tempBaseline: number;
  /** Baseline count of days > 30 °C / year at yearStart. */
  daysBaseline: number;
  /** Summer mean temperature (°C) at year index i (0 = yearStart). */
  tempAt: (i: number) => number;
  /** Days > 30 °C / year at year index i. */
  daysAt: (i: number) => number;
  /** Covatherm reduction on AC bill (%) at year index i. */
  gainPctAt: (i: number) => number;
  /** Covatherm reduction under the roof (°C) at year index i. */
  gainDegAt: (i: number) => number;
};

/**
 * Paris — Île-de-France (DRIAS RCP 4.5, calibrated 2026 → 2046).
 * Summer mean climbs from 21.2 °C to ~24.5 °C, days > 30 °C from 14 to ~38.
 */
export const PARIS: CityProjection = {
  city: 'Paris',
  region: 'Île-de-France',
  yearStart: 2026,
  yearEnd: 2046,
  tempBaseline: 21.2,
  daysBaseline: 14,
  tempAt: (i) =>
    Math.round(
      (21.2 + 3.3 * (i / 20) + 0.35 * Math.sin(i * 1.3) + (i % 3 === 0 ? 0.2 : -0.1)) * 10,
    ) / 10,
  daysAt: (i) =>
    Math.max(
      8,
      Math.round(14 + 24 * Math.pow(i / 20, 1.15) + Math.sin(i * 1.7) * 1.5 + (i % 4 === 0 ? 1 : 0)),
    ),
  gainPctAt: (i) => Math.round(28 + (i / 20) * 8), // 28% → 36%
  gainDegAt: (i) => Math.round(7 + (i / 20) * 3), //  7°C → 10°C
};

/**
 * Example template for adding another city.
 * Adjust the polynomial / sine coefficients to match local DRIAS projections.
 */
export const LYON: CityProjection = {
  city: 'Lyon',
  region: 'Auvergne-Rhône-Alpes',
  yearStart: 2026,
  yearEnd: 2046,
  tempBaseline: 22.4,
  daysBaseline: 22,
  tempAt: (i) =>
    Math.round(
      (22.4 + 3.6 * (i / 20) + 0.4 * Math.sin(i * 1.2) + (i % 3 === 0 ? 0.2 : -0.1)) * 10,
    ) / 10,
  daysAt: (i) =>
    Math.max(12, Math.round(22 + 28 * Math.pow(i / 20, 1.1) + Math.sin(i * 1.6) * 2)),
  gainPctAt: (i) => Math.round(30 + (i / 20) * 9),
  gainDegAt: (i) => Math.round(8 + (i / 20) * 3),
};
