import { describe, it, expect } from 'vitest'
import { computeMagnitude, computeCityImpact, ErdbebenSimulation } from '../../src/sims/sim-07-erdbeben/logic'

describe('Erdbeben — Magnitude-Berechnung', () => {

  it('geringe Spannung → niedrige Magnitude', () => {
    const mag = computeMagnitude(1, 0.5)
    expect(mag).toBeLessThan(4)
  })

  it('hohe Spannung → hohe Magnitude', () => {
    const mag = computeMagnitude(5000, 1.5)
    expect(mag).toBeGreaterThan(5)
  })

  it('Magnitude nie über 9.5', () => {
    const mag = computeMagnitude(10000, 10)
    expect(mag).toBeLessThanOrEqual(9.5)
  })

  it('härteres Gestein → stärkeres Beben bei gleicher Spannung', () => {
    const soft = computeMagnitude(10, 0.5)
    const hard = computeMagnitude(10, 1.5)
    expect(hard).toBeGreaterThan(soft)
  })
})

describe('Erdbeben — Stadtauswirkungen', () => {

  it('hohe Bauqualität → weniger Schaden', () => {
    const rich = computeCityImpact(7, 30, 0.9)
    const poor = computeCityImpact(7, 30, 0.1)
    expect(rich.damage).toBeLessThan(poor.damage)
  })

  it('gleiche Magnitude, gleiche Distanz, verschiedene Bauqualität → verschiedene Opferzahlen', () => {
    const rich = computeCityImpact(7, 30, 0.9)
    const poor = computeCityImpact(7, 30, 0.1)
    expect(poor.casualties).toBeGreaterThan(rich.casualties)
  })

  it('größere Entfernung → weniger Schaden', () => {
    const near = computeCityImpact(7, 10, 0.5)
    const far = computeCityImpact(7, 300, 0.5)
    expect(far.damage).toBeLessThan(near.damage)
  })

  it('schwaches Beben → wenig Schaden auch bei schlechter Bauqualität', () => {
    const impact = computeCityImpact(3, 30, 0.1)
    expect(impact.damage).toBeLessThan(20)
  })

  it('starkes Beben + schlechte Bauqualität → hoher Gebäudekollaps', () => {
    const impact = computeCityImpact(8, 20, 0.1)
    expect(impact.buildingCollapse).toBeGreaterThan(30)
  })
})

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

  it('hat korrekte Metadaten', () => {
    const sim = new ErdbebenSimulation()
    expect(sim.meta.id).toBe('sim-07')
    expect(sim.meta.primaryLevel).toBe(5)
    expect(sim.meta.tier).toBe(1)
  })

  it('Spannung baut sich über Ticks auf', () => {
    const sim = new ErdbebenSimulation()
    sim.tick()
    sim.tick()
    sim.tick()
    expect(sim.getStress()).toBeGreaterThan(0)
  })

  it('irgendwann kommt ein Erdbeben', () => {
    const sim = new ErdbebenSimulation()
    sim.setVariable('plateSpeed', 15)
    let quake = null
    for (let i = 0; i < 100 && !quake; i++) {
      quake = sim.tick()
    }
    expect(quake).not.toBeNull()
    expect(quake!.magnitude).toBeGreaterThan(0)
  })

  it('Vergleich der Stadtauswirkungen funktioniert', () => {
    const sim = new ErdbebenSimulation()
    const { cityA, cityB } = sim.compareImpact(7)
    expect(cityA.type).toBe('rich')
    expect(cityB.type).toBe('poor')
    expect(cityB.damage).toBeGreaterThan(cityA.damage)
  })

  it('schnellere Platten → häufigere Beben', () => {
    const slow = new ErdbebenSimulation()
    slow.setVariable('plateSpeed', 2)
    const fast = new ErdbebenSimulation()
    fast.setVariable('plateSpeed', 15)

    let slowQuakes = 0, fastQuakes = 0
    for (let i = 0; i < 200; i++) {
      if (slow.tick()) slowQuakes++
      if (fast.tick()) fastQuakes++
    }
    expect(fastQuakes).toBeGreaterThan(slowQuakes)
  })
})
