/**
 * SIM-12: Flussmanagement — Simulationslogik
 *
 * Nichtlineares Simulationsmodell fuer Flussmanagement.
 * 6 Steuermassnahmen → 8 Zustandsparameter → 4 Zielbereiche.
 *
 * Alle Werte liegen im Bereich 0–100.
 * Abnehmender Grenznutzen, ueberproportionale Nebenwirkungen bei Extremen.
 */

// === Typen ===

export interface Controls {
  straightening: number    // Flussbegradigung (0–100)
  levees: number           // Daemme/Deiche (0–100)
  dredging: number         // Ausbaggern (0–100)
  floodplainRelease: number // Auen freigeben (0–100)
  renaturation: number     // Renaturierung (0–100)
  irrigation: number       // Bewaesserung (0–100)
}

export interface State {
  floodLocal: number       // Lokales Hochwasserrisiko
  floodDownstream: number  // Hochwasser flussabwaerts
  erosion: number          // Erosionsrisiko
  soilFertility: number    // Bodenfruchtbarkeit
  biodiversity: number     // Biodiversitaet
  groundwater: number      // Grundwasserspiegel
  usableLand: number       // Nutzbare Flaeche
  economy: number          // Wirtschaftsleistung
}

export interface Conditions {
  rainfall: number         // Niederschlag
  extremeWeather: number   // Extremwetter-Wahrscheinlichkeit
  slope: number            // Gefaelle
  populationPressure: number // Bevoelkerungsdruck
  budget: number           // Budget (Punkte, nicht 0–100)
}

export interface ScoreBreakdown {
  safety: number
  ecology: number
  agriculture: number
  economy: number
  total: number
}

export interface LevelEvent {
  round: number
  type: 'flood_event' | 'drought' | 'economic_boost'
  intensity: number        // 0–100
}

export interface LevelDefinition {
  id: string
  title: string
  description: string
  durationTargetMinutes: number
  rounds: number
  initialState: State
  conditions: Conditions
  allowedControls: (keyof Controls)[]
  controlLimits?: Partial<Controls>
  scoreWeights: { safety: number; ecology: number; agriculture: number; economy: number }
  events?: LevelEvent[]
  winConditions: { minScore?: number; targetScores?: Partial<ScoreBreakdown> }
  loseConditions?: { maxFloodLocal?: number; maxFloodDownstream?: number; minGroundwater?: number }
}

// === Hilfsfunktionen ===

/** Wert auf 0–100 begrenzen */
function clamp(v: number): number {
  return Math.max(0, Math.min(100, v))
}

/** Abnehmender Grenznutzen: hohe Intensitaet bringt weniger */
function diminishing(intensity: number): number {
  // f(x) = 1 - (1 - x/100)^2  → schneller Anstieg am Anfang, flacher am Ende
  const x = intensity / 100
  return (1 - Math.pow(1 - x, 2)) * 100
}

/** Ueberproportionale Nebenwirkung bei hoher Intensitaet */
function sideEffect(intensity: number): number {
  // f(x) = x^1.8 / 100^0.8  → bei 50: ~35, bei 100: 100
  return Math.pow(intensity, 1.8) / Math.pow(100, 0.8)
}

/** Moderater Effekt (linear mit leichtem Bogen) */
function moderate(intensity: number): number {
  const x = intensity / 100
  return x * 0.7 + x * x * 0.3
}

// === Simulation ===

/**
 * Berechnet den neuen Zustand nach einer Runde.
 * Kern der nichtlinearen Simulation.
 */
export function simulateRound(
  state: State,
  controls: Controls,
  conditions: Conditions,
  event?: LevelEvent
): State {
  const s = { ...state }

  // --- Basis-Effekte der Rahmenbedingungen ---
  const rainFactor = conditions.rainfall / 60    // 1.0 bei normalem Regen
  const slopeFactor = conditions.slope / 50      // 1.0 bei normalem Gefaelle
  const popFactor = conditions.populationPressure / 50

  // --- FLUSSBEGRADIGUNG ---
  // + Mehr nutzbare Flaeche, + Wirtschaft
  // - Mehr Hochwasser flussabwaerts, - Biodiversitaet, - Grundwasser
  if (controls.straightening > 0) {
    const eff = diminishing(controls.straightening)
    const side = sideEffect(controls.straightening)
    s.usableLand = clamp(s.usableLand + eff * 0.15)
    s.economy = clamp(s.economy + eff * 0.08)
    s.floodLocal = clamp(s.floodLocal - eff * 0.08)
    s.floodDownstream = clamp(s.floodDownstream + side * 0.25 * rainFactor)
    s.biodiversity = clamp(s.biodiversity - side * 0.18)
    s.groundwater = clamp(s.groundwater - moderate(controls.straightening) * 12)
    s.erosion = clamp(s.erosion + side * 0.12 * slopeFactor)
  }

  // --- DAEMME/DEICHE ---
  // + Lokaler Hochwasserschutz
  // - Flussabwaerts schlimmer, - Grundwasser (Fluss vom Umland getrennt)
  if (controls.levees > 0) {
    const eff = diminishing(controls.levees)
    const side = sideEffect(controls.levees)
    s.floodLocal = clamp(s.floodLocal - eff * 0.3)
    s.floodDownstream = clamp(s.floodDownstream + side * 0.15)
    s.groundwater = clamp(s.groundwater - moderate(controls.levees) * 8)
    s.soilFertility = clamp(s.soilFertility - side * 0.06)
    s.biodiversity = clamp(s.biodiversity - side * 0.05)
  }

  // --- AUSBAGGERN ---
  // + Tieferer Fluss = weniger lokales Hochwasser, + Schifffahrt/Wirtschaft
  // - Erosion, - Biodiversitaet, temporaerer Effekt
  if (controls.dredging > 0) {
    const eff = diminishing(controls.dredging)
    const side = sideEffect(controls.dredging)
    s.floodLocal = clamp(s.floodLocal - eff * 0.15)
    s.economy = clamp(s.economy + eff * 0.1)
    s.erosion = clamp(s.erosion + side * 0.3 * slopeFactor)
    s.biodiversity = clamp(s.biodiversity - side * 0.15)
    s.groundwater = clamp(s.groundwater - moderate(controls.dredging) * 6)
  }

  // --- AUEN FREIGEBEN ---
  // + Reduziert Hochwasser (Retentionsflaeche), + Grundwasser, + Biodiversitaet
  // - Weniger nutzbare Flaeche, - Wirtschaft
  if (controls.floodplainRelease > 0) {
    const eff = diminishing(controls.floodplainRelease)
    const side = sideEffect(controls.floodplainRelease)
    s.floodLocal = clamp(s.floodLocal - eff * 0.2)
    s.floodDownstream = clamp(s.floodDownstream - eff * 0.15)
    s.groundwater = clamp(s.groundwater + eff * 0.15)
    s.biodiversity = clamp(s.biodiversity + eff * 0.12)
    s.soilFertility = clamp(s.soilFertility + eff * 0.05)
    s.usableLand = clamp(s.usableLand - side * 0.2)
    s.economy = clamp(s.economy - side * 0.08)
  }

  // --- RENATURIERUNG ---
  // + Biodiversitaet, + Grundwasser, + Bodenfruchtbarkeit, + Erosionsschutz
  // - Nutzbare Flaeche, - Wirtschaft, hohe Kosten
  if (controls.renaturation > 0) {
    const eff = diminishing(controls.renaturation)
    const side = sideEffect(controls.renaturation)
    s.biodiversity = clamp(s.biodiversity + eff * 0.25)
    s.groundwater = clamp(s.groundwater + eff * 0.12)
    s.soilFertility = clamp(s.soilFertility + eff * 0.1)
    s.erosion = clamp(s.erosion - eff * 0.15)
    s.floodLocal = clamp(s.floodLocal - eff * 0.08)
    s.floodDownstream = clamp(s.floodDownstream - eff * 0.08)
    s.usableLand = clamp(s.usableLand - side * 0.15)
    s.economy = clamp(s.economy - side * 0.1)
  }

  // --- BEWAESSERUNG ---
  // + Bodenfruchtbarkeit, + Wirtschaft (Landwirtschaftsertrag)
  // - Grundwasser (Entnahme), - bei Extreme: Versalzung
  if (controls.irrigation > 0) {
    const eff = diminishing(controls.irrigation)
    const side = sideEffect(controls.irrigation)
    s.soilFertility = clamp(s.soilFertility + eff * 0.18)
    s.economy = clamp(s.economy + eff * 0.08)
    s.groundwater = clamp(s.groundwater - side * 0.2)
    // Versalzung bei extremer Bewaesserung in trockenem Klima
    if (controls.irrigation > 70 && conditions.rainfall < 40) {
      s.soilFertility = clamp(s.soilFertility - side * 0.12)
    }
  }

  // --- Natuerliche Dynamik ---
  // Regen hebt Grundwasser, Erosion verschlechtert Bodenqualitaet
  s.groundwater = clamp(s.groundwater + (rainFactor - 1) * 3)
  s.soilFertility = clamp(s.soilFertility - s.erosion * 0.02)

  // Bevoelkerungsdruck erhoeht Wirtschaftsbedarf, reduziert Biodiversitaet
  s.economy = clamp(s.economy + (popFactor - 1) * 2)
  s.biodiversity = clamp(s.biodiversity - (popFactor - 1) * 1.5)

  // --- Events ---
  if (event) {
    if (event.type === 'flood_event') {
      const floodForce = event.intensity / 100
      s.floodLocal = clamp(s.floodLocal + 25 * floodForce * rainFactor)
      s.floodDownstream = clamp(s.floodDownstream + 20 * floodForce)
      s.erosion = clamp(s.erosion + 15 * floodForce * slopeFactor)
      s.usableLand = clamp(s.usableLand - 10 * floodForce)
      s.economy = clamp(s.economy - 8 * floodForce)
    }
    if (event.type === 'drought') {
      const droughtForce = event.intensity / 100
      s.groundwater = clamp(s.groundwater - 20 * droughtForce)
      s.soilFertility = clamp(s.soilFertility - 12 * droughtForce)
      s.biodiversity = clamp(s.biodiversity - 8 * droughtForce)
      s.floodLocal = clamp(s.floodLocal - 10 * droughtForce) // weniger Hochwasser
    }
    if (event.type === 'economic_boost') {
      const boostForce = event.intensity / 100
      s.economy = clamp(s.economy + 15 * boostForce)
      s.populationPressure = clamp((conditions.populationPressure || 50) + 10 * boostForce)
    }
  }

  return s
}

/**
 * Kosten einer Massnahme berechnen (abhaengig von Intensitaet).
 * Hoehere Intensitaet = ueberproportional teurer.
 */
export function computeCost(control: keyof Controls, intensity: number): number {
  const baseCosts: Record<keyof Controls, number> = {
    straightening: 25,
    levees: 20,
    dredging: 15,
    floodplainRelease: 10,
    renaturation: 30,
    irrigation: 18,
  }
  const base = baseCosts[control]
  // Kosten steigen quadratisch: cost(50) = ~50% des Maximums, cost(100) = 100%
  return Math.round(base * Math.pow(intensity / 100, 1.5))
}

/**
 * Gesamtkosten aller aktiven Massnahmen berechnen.
 */
export function computeTotalCost(controls: Controls): number {
  let total = 0
  for (const key of Object.keys(controls) as (keyof Controls)[]) {
    if (controls[key] > 0) {
      total += computeCost(key, controls[key])
    }
  }
  return total
}

/**
 * Score berechnen (0–100 pro Bereich + Gesamtscore).
 */
export function computeScore(
  state: State,
  weights: { safety: number; ecology: number; agriculture: number; economy: number }
): ScoreBreakdown {
  // Sicherheit: niedrige Hochwasser + niedrige Erosion
  const safety = clamp(100 - (state.floodLocal * 0.4 + state.floodDownstream * 0.35 + state.erosion * 0.25))

  // Oekologie: hohe Biodiversitaet + hoher Grundwasserspiegel
  const ecology = clamp(state.biodiversity * 0.6 + state.groundwater * 0.4)

  // Landwirtschaft: hohe Bodenfruchtbarkeit + genug Flaeche + genug Wasser
  const agriculture = clamp(state.soilFertility * 0.5 + state.usableLand * 0.3 + state.groundwater * 0.2)

  // Wirtschaft: direkt
  const economy = state.economy

  const total = clamp(
    safety * weights.safety +
    ecology * weights.ecology +
    agriculture * weights.agriculture +
    economy * weights.economy
  )

  return { safety, ecology, agriculture, economy, total }
}

/**
 * Win/Lose-Bedingungen pruefen.
 */
export function checkWinLose(
  state: State,
  score: ScoreBreakdown,
  level: LevelDefinition
): 'win' | 'lose' | 'playing' {
  // Lose-Bedingungen
  if (level.loseConditions) {
    if (level.loseConditions.maxFloodLocal !== undefined && state.floodLocal > level.loseConditions.maxFloodLocal) return 'lose'
    if (level.loseConditions.maxFloodDownstream !== undefined && state.floodDownstream > level.loseConditions.maxFloodDownstream) return 'lose'
    if (level.loseConditions.minGroundwater !== undefined && state.groundwater < level.loseConditions.minGroundwater) return 'lose'
  }

  // Win-Bedingungen (nur am Ende relevant, nicht pro Runde)
  return 'playing'
}

/**
 * Am Ende des Spiels pruefen ob Win-Bedingungen erfuellt sind.
 */
export function checkFinalWin(
  score: ScoreBreakdown,
  level: LevelDefinition
): boolean {
  const wc = level.winConditions
  if (wc.minScore !== undefined && score.total < wc.minScore) return false
  if (wc.targetScores) {
    for (const [key, target] of Object.entries(wc.targetScores)) {
      if (score[key as keyof ScoreBreakdown] < (target as number)) return false
    }
  }
  return true
}

// === Level-Definitionen ===

export const LEVELS: LevelDefinition[] = [
  {
    id: 'L1',
    title: 'Fluss und Siedlung',
    description: 'Eine kleine Siedlung liegt an einem Fluss und ist regelmäßig von Hochwasser betroffen. Finde einen Weg, die Bewohner zu schützen!',
    durationTargetMinutes: 10,
    rounds: 5,
    initialState: {
      floodLocal: 60, floodDownstream: 40, erosion: 30,
      soilFertility: 60, biodiversity: 70, groundwater: 55,
      usableLand: 40, economy: 40
    },
    conditions: { rainfall: 60, extremeWeather: 30, slope: 40, populationPressure: 30, budget: 120 },
    allowedControls: ['levees', 'floodplainRelease'],
    controlLimits: { levees: 60, floodplainRelease: 60 },
    scoreWeights: { safety: 0.5, ecology: 0.2, agriculture: 0.15, economy: 0.15 },
    winConditions: { minScore: 60 },
    loseConditions: { maxFloodLocal: 85 },
  },
  {
    id: 'L2',
    title: 'Fruchtbares Tal',
    description: 'Ein Tal lebt von fruchtbaren Böden durch regelmäßige Überschwemmungen. Wie nutzt du das Wasser, ohne alles zu riskieren?',
    durationTargetMinutes: 20,
    rounds: 7,
    initialState: {
      floodLocal: 55, floodDownstream: 35, erosion: 35,
      soilFertility: 75, biodiversity: 65, groundwater: 60,
      usableLand: 45, economy: 50
    },
    conditions: { rainfall: 65, extremeWeather: 40, slope: 35, populationPressure: 40, budget: 150 },
    allowedControls: ['levees', 'floodplainRelease', 'irrigation'],
    scoreWeights: { safety: 0.25, ecology: 0.2, agriculture: 0.4, economy: 0.15 },
    winConditions: { targetScores: { agriculture: 65, safety: 50 } },
  },
  {
    id: 'L3',
    title: 'Der gezähmte Fluss',
    description: 'Der Fluss soll kontrolliert werden, um Städte und Industrie zu schützen. Doch die Natur schlägt zurück!',
    durationTargetMinutes: 25,
    rounds: 8,
    initialState: {
      floodLocal: 50, floodDownstream: 45, erosion: 40,
      soilFertility: 55, biodiversity: 50, groundwater: 50,
      usableLand: 55, economy: 60
    },
    conditions: { rainfall: 60, extremeWeather: 45, slope: 50, populationPressure: 70, budget: 180 },
    allowedControls: ['levees', 'straightening', 'dredging'],
    scoreWeights: { safety: 0.4, ecology: 0.1, agriculture: 0.2, economy: 0.3 },
    events: [{ round: 4, type: 'flood_event', intensity: 70 }],
    winConditions: { minScore: 65 },
  },
  {
    id: 'L4',
    title: 'Fluss im Gleichgewicht',
    description: 'Finde eine Balance zwischen Sicherheit, Natur und Nutzung. Alle Ziele zählen gleich!',
    durationTargetMinutes: 30,
    rounds: 10,
    initialState: {
      floodLocal: 55, floodDownstream: 50, erosion: 45,
      soilFertility: 60, biodiversity: 60, groundwater: 50,
      usableLand: 50, economy: 55
    },
    conditions: { rainfall: 60, extremeWeather: 50, slope: 45, populationPressure: 60, budget: 180 },
    allowedControls: ['levees', 'straightening', 'floodplainRelease', 'renaturation', 'irrigation'],
    scoreWeights: { safety: 0.25, ecology: 0.25, agriculture: 0.25, economy: 0.25 },
    winConditions: { minScore: 70 },
  },
  {
    id: 'L5',
    title: 'Nildelta',
    description: 'Die jährlichen Überschwemmungen bringen fruchtbare Böden — aber auch Risiken. Schützt du die Ernte oder die Natur?',
    durationTargetMinutes: 35,
    rounds: 10,
    initialState: {
      floodLocal: 65, floodDownstream: 40, erosion: 30,
      soilFertility: 85, biodiversity: 70, groundwater: 65,
      usableLand: 50, economy: 60
    },
    conditions: { rainfall: 40, extremeWeather: 20, slope: 20, populationPressure: 70, budget: 160 },
    allowedControls: ['levees', 'irrigation', 'floodplainRelease'],
    scoreWeights: { safety: 0.2, ecology: 0.2, agriculture: 0.45, economy: 0.15 },
    winConditions: { targetScores: { agriculture: 75 } },
    loseConditions: { minGroundwater: 25 },
  },
]

/** Massnahmen-Metadaten fuer UI */
export const CONTROL_META: Record<keyof Controls, { name: string; emoji: string; description: string }> = {
  straightening:     { name: 'Flussbegradigung',  emoji: '📏', description: 'Den Fluss gerade ziehen — mehr Fläche, aber die Natur leidet.' },
  levees:            { name: 'Deiche bauen',       emoji: '🧱', description: 'Schutz vor Hochwasser — aber das Wasser muss irgendwohin.' },
  dredging:          { name: 'Ausbaggern',         emoji: '⛏️', description: 'Den Fluss tiefer machen — gut für Schiffe, schlecht für Ökosysteme.' },
  floodplainRelease: { name: 'Auen freigeben',     emoji: '🌊', description: 'Dem Fluss Raum geben — weniger Hochwasser, aber weniger Fläche.' },
  renaturation:      { name: 'Renaturierung',      emoji: '🌿', description: 'Die Natur zurückbringen — gut für alles außer die Wirtschaft.' },
  irrigation:        { name: 'Bewässerung',        emoji: '💧', description: 'Felder bewässern — mehr Ertrag, aber das Grundwasser sinkt.' },
}

/** Zustandsparameter-Metadaten fuer UI */
export const STATE_META: Record<keyof State, { name: string; emoji: string; goodDirection: 'low' | 'high' }> = {
  floodLocal:      { name: 'Hochwasser (lokal)',    emoji: '🌊', goodDirection: 'low' },
  floodDownstream: { name: 'Hochwasser (flussab.)', emoji: '🌊', goodDirection: 'low' },
  erosion:         { name: 'Erosion',               emoji: '🏜️', goodDirection: 'low' },
  soilFertility:   { name: 'Bodenfruchtbarkeit',    emoji: '🌱', goodDirection: 'high' },
  biodiversity:    { name: 'Biodiversität',         emoji: '🦎', goodDirection: 'high' },
  groundwater:     { name: 'Grundwasser',           emoji: '💧', goodDirection: 'high' },
  usableLand:      { name: 'Nutzbare Fläche',       emoji: '🏘️', goodDirection: 'high' },
  economy:         { name: 'Wirtschaft',            emoji: '💰', goodDirection: 'high' },
}
