/**
 * SIM-05: Treibhauseffekt-Simulator — LOGIK
 *
 * Vereinfachtes Klimamodell:
 * - Sonneneinstrahlung (konstant ~1361 W/m²)
 * - Albedo (Reflexion, ~0.3)
 * - CO₂-Konzentration beeinflusst Treibhauseffekt
 * - Ergebnis: Gleichgewichtstemperatur der Erde
 *
 * Gezielt gegen Fehlkonzept: "Ozonloch = Klimawandel"
 * (Schuler 2011, Reinfried et al. 2010)
 *
 * Didaktischer Ablauf: Predict → Observe → Explain
 */

import { Simulation, SimulationMeta } from '@core/simulation'

const META: SimulationMeta = {
  id: 'sim-05',
  name: 'Treibhauseffekt-Simulator',
  educationLevels: [5, 6, 7, 8],  // AT: 1.–4. Kl. MS, DE: 5.–8., CH: Zyklus 3
  primaryLevel: 5,                 // Primär für AT 1. Klasse MS (= 5. Schulstufe)
  kompetenzbereich: 'Leben und Wirtschaften im Hinblick auf nachhaltige Ernährung',
  lernziele: [
    'Grundprinzip des Treibhauseffekts erklären können',
    'Zusammenhang zwischen CO₂-Konzentration und Temperatur verstehen',
    'Treibhauseffekt vom Ozonloch unterscheiden können',
  ],
  basiskonzepte: ['Veränderung und Wandel', 'Maßstabsebenen und Raum'],
  requiresReading: true,  // Text-basierte Reflexionsfragen
  dpiMinuten: 20,
  typ: 'sachsimulation',
  tier: 1,
}

/** Physikalische Konstanten (vereinfacht für Schulniveau) */
const SOLAR_CONSTANT = 1361       // W/m², Solarkonstante
const STEFAN_BOLTZMANN = 5.67e-8  // W/(m²·K⁴)
const PRE_INDUSTRIAL_CO2 = 280    // ppm
const CURRENT_CO2 = 425           // ppm (ca. 2026)

/**
 * Berechnet die Gleichgewichtstemperatur der Erde
 * basierend auf einem vereinfachten Strahlungsmodell.
 *
 * Ohne Treibhauseffekt: ~-18°C
 * Mit natürlichem Treibhauseffekt (280 ppm): ~15°C
 * Aktuell (425 ppm): ~16.1°C
 */
export function computeTemperature(co2ppm: number, albedo: number): number {
  // Absorbierte Sonnenstrahlung pro m²
  const absorbed = (SOLAR_CONSTANT / 4) * (1 - albedo)

  // Treibhauseffekt als logarithmische Funktion der CO₂-Konzentration
  // ΔT ≈ λ * ln(CO₂/CO₂_ref) — vereinfacht nach Arrhenius
  const climateSensitivity = 3.0  // °C pro Verdoppelung CO₂
  const deltaT = climateSensitivity * Math.log2(co2ppm / PRE_INDUSTRIAL_CO2)

  // Basistemperatur ohne Treibhauseffekt
  const tempNoGreenhouse = Math.pow(absorbed / STEFAN_BOLTZMANN, 0.25) - 273.15 // ~-18°C

  // Natürlicher Treibhauseffekt ~33°C
  const naturalGreenhouse = 33

  return tempNoGreenhouse + naturalGreenhouse + deltaT
}

/**
 * Berechnet Folgen der Temperaturänderung (vereinfacht)
 */
export function computeEffects(tempC: number): {
  seaLevelRise: number   // cm über vorindustriellem Niveau
  arcticIce: number      // % verbleibend (100% = vorindustriell)
  extremeEvents: number  // Faktor (1 = normal, 2 = doppelt so häufig)
} {
  const deltaT = tempC - 15  // Differenz zum vorindustriellen Mittel

  return {
    seaLevelRise: Math.max(0, deltaT * 15),  // ~15cm pro °C (vereinfacht)
    arcticIce: Math.max(0, Math.min(100, 100 - deltaT * 12)),
    extremeEvents: Math.max(1, 1 + deltaT * 0.3),
  }
}

export class TreibhausSimulation extends Simulation {
  constructor() {
    super(META)

    // Startwerte setzen
    const ranges = this.getVariableRanges()
    for (const [key, range] of Object.entries(ranges)) {
      this.state.variables[key] = range.default
    }
  }

  getVariableRanges() {
    return {
      co2: {
        min: 200,
        max: 1000,
        default: CURRENT_CO2,
        unit: 'ppm',
        label: 'CO₂-Konzentration',
      },
      albedo: {
        min: 0.1,
        max: 0.6,
        default: 0.3,
        unit: '',
        label: 'Albedo (Reflexion)',
      },
    }
  }

  compute() {
    const co2 = this.getVariable('co2')
    const albedo = this.getVariable('albedo')

    const temp = computeTemperature(co2, albedo)
    const effects = computeEffects(temp)

    const results = {
      temperature: Math.round(temp * 10) / 10,
      seaLevelRise: Math.round(effects.seaLevelRise),
      arcticIce: Math.round(effects.arcticIce),
      extremeEvents: Math.round(effects.extremeEvents * 10) / 10,
      tempWithoutGreenhouse: Math.round((Math.pow((SOLAR_CONSTANT / 4) * (1 - albedo) / STEFAN_BOLTZMANN, 0.25) - 273.15) * 10) / 10,
    }

    this.state.results = results
    return results
  }

  protected onVariableChange(_name: string, _value: number): void {
    this.compute()
  }
}
