import { describe, it, expect } from 'vitest'
import { computeTemperature, computeEffects, TreibhausSimulation } from '../../src/sims/sim-05-treibhaus/logic'

describe('Treibhauseffekt — Physik-Modell', () => {

  it('berechnet korrekte Temperatur ohne Treibhauseffekt (Albedo 0.3)', () => {
    // Ohne CO₂ (theoretisch 0 ppm → ln(0) ist undefiniert, daher sehr niedrig)
    // Bei 1 ppm sollte Temp nahe -18°C + 33°C - großer negativer Wert sein
    // Besser: Prüfen, dass 280 ppm → ~15°C ergibt
    const temp = computeTemperature(280, 0.3)
    expect(temp).toBeGreaterThan(13.5)
    expect(temp).toBeLessThan(16)  // ~14-15°C, vereinfachtes Modell
  })

  it('ergibt ~16°C bei aktuellem CO₂-Niveau (425 ppm)', () => {
    const temp = computeTemperature(425, 0.3)
    expect(temp).toBeGreaterThan(15.5)
    expect(temp).toBeLessThan(17)
  })

  it('Verdoppelung von CO₂ erhöht Temperatur um ~3°C', () => {
    const temp280 = computeTemperature(280, 0.3)
    const temp560 = computeTemperature(560, 0.3)
    const delta = temp560 - temp280
    expect(delta).toBeCloseTo(3.0, 0.5)
  })

  it('höhere Albedo → kältere Temperatur', () => {
    const tempLow = computeTemperature(400, 0.2)
    const tempHigh = computeTemperature(400, 0.5)
    expect(tempLow).toBeGreaterThan(tempHigh)
  })

  it('steigende CO₂ → steigende Temperatur (monoton)', () => {
    const temps = [200, 300, 400, 600, 800, 1000].map(co2 => computeTemperature(co2, 0.3))
    for (let i = 1; i < temps.length; i++) {
      expect(temps[i]).toBeGreaterThan(temps[i - 1])
    }
  })
})

describe('Treibhauseffekt — Folgen-Berechnung', () => {

  it('vorindustrielle Temperatur → kein Meeresspiegelanstieg', () => {
    const effects = computeEffects(15)
    expect(effects.seaLevelRise).toBe(0)
  })

  it('+2°C → messbarer Meeresspiegelanstieg', () => {
    const effects = computeEffects(17)
    expect(effects.seaLevelRise).toBeGreaterThan(20)
  })

  it('arktisches Eis sinkt mit steigender Temperatur', () => {
    const ice15 = computeEffects(15).arcticIce
    const ice18 = computeEffects(18).arcticIce
    expect(ice15).toBeGreaterThan(ice18)
  })

  it('Extremereignisse steigen mit Temperatur', () => {
    const events15 = computeEffects(15).extremeEvents
    const events20 = computeEffects(20).extremeEvents
    expect(events20).toBeGreaterThan(events15)
  })
})

describe('TreibhausSimulation — Klasse', () => {

  it('hat korrekte Metadaten', () => {
    const sim = new TreibhausSimulation()
    expect(sim.meta.id).toBe('sim-05')
    expect(sim.meta.primaryLevel).toBe(5)
    expect(sim.meta.educationLevels).toContain(5)
    expect(sim.meta.tier).toBe(1)
    expect(sim.meta.dpiMinuten).toBe(20)
  })

  it('startet mit Standardwerten', () => {
    const sim = new TreibhausSimulation()
    expect(sim.getVariable('co2')).toBe(425)
    expect(sim.getVariable('albedo')).toBe(0.3)
  })

  it('berechnet Ergebnisse nach Variable-Änderung', () => {
    const sim = new TreibhausSimulation()
    sim.setVariable('co2', 560)
    const results = sim.compute()
    expect(results.temperature).toBeGreaterThan(17)
  })

  it('loggt Variablenänderungen im Assessment', () => {
    const sim = new TreibhausSimulation()
    sim.setVariable('co2', 300)
    sim.setVariable('co2', 600)
    const assessment = sim.getAssessmentData()
    expect(assessment.processLog.length).toBeGreaterThanOrEqual(2)
    expect(assessment.processLog.some(l => l.action === 'set-variable')).toBe(true)
  })

  it('Predict-Observe-Explain Workflow funktioniert', () => {
    const sim = new TreibhausSimulation()

    // Predict
    sim.nextPhase() // intro → predict
    sim.setPrediction('temp_at_800ppm', 'Ich glaube über 20°C')

    // Simulate
    sim.nextPhase() // predict → simulate
    sim.setVariable('co2', 800)

    // Observe
    sim.nextPhase() // simulate → observe
    const results = sim.compute()
    expect(results.temperature).toBeDefined()

    // Reflect
    sim.nextPhase() // observe → reflect
    sim.addReflection('Die Temperatur ist höher als ich dachte')

    const assessment = sim.getAssessmentData()
    expect(assessment.predictions['temp_at_800ppm']).toBeDefined()
    expect(assessment.reflections.length).toBe(1)
    expect(assessment.completedPhases).toContain('reflect')
  })
})
