/**
 * SIM-10: Lieferketten-Planer*in — Was kostet dein T-Shirt?
 *
 * Die Anwender*in ist Einkaufsleiter*in einer Modemarke in Wien. Alle 3
 * Monate (1 Tick) wird eine Charge T-Shirts (5.000 Stück) bestellt. Pro
 * Bestellung wählst du:
 *
 *   1. Wo die BAUMWOLLE herkommt
 *   2. Wo die T-Shirts GENÄHT werden
 *   3. Wie sie nach WIEN transportiert werden
 *
 * Die Wahl beeinflusst drei Werte, die alle gleichzeitig stimmen müssen:
 *
 *   💰 Budget — Verkauf − Einkauf − Transport (12 €/Stück Marktpreis)
 *   🌫 CO₂-Fußabdruck — Durchschnitt pro Stück, langfristig sichtbar
 *   ⚖️ Ethik-Score — Arbeitsbedingungen am Standort (0-10)
 *
 * Kernbotschaft: Es gibt KEINEN Königsweg. Billigster Stoff = oft schlechte
 * Arbeitsbedingungen. Schnellster Weg = höchster CO₂-Ausstoß. Du musst
 * abwägen — und Lehrer*innen können die Konfiguration für ihre Klasse anpassen.
 *
 * Konfiguration durch die Lehrperson (3 Parameter):
 *
 *   - startMoney      Startbudget (Default: 800 Mio €)
 *   - enabledOptions  Welche Standorte/Transporte sind verfügbar?
 *   - enabledEvents   Welche Welt-Ereignisse können auftreten?
 *
 * Die Defaults entsprechen dem mittleren Schwierigkeitsgrad.
 */

import { GameEngine, type GameMeta } from '@core/game-engine'

const META: GameMeta = {
  id: 'sim-10',
  title: 'Lieferketten-Planer*in',
  description: 'Bestelle T-Shirts aus aller Welt — und finde heraus, was sie wirklich kosten.',
  msPerTick: 6000, // 6 Sekunden = 3 Monate (1 Tick) — gibt Zeit zum Nachdenken
  tickUnit: 'Quartal',
  maxTicks: 20,    // 20 Quartale = 5 Jahre
  tutorialSteps: 4,
}

const START_YEAR = 2025

// === STANDORTE ===

export interface CottonSource {
  id: string
  name: string
  country: string        // Land
  emoji: string
  flag: string           // Flag-Emoji
  /** Welt-Karte: x/y in Prozent (0-100) */
  pos: { x: number; y: number }
  /** Preis pro T-Shirt (€) — Rohstoff-Anteil */
  pricePerShirt: number
  /** CO₂-Footprint Baumwoll-Anbau (kg/Stück) */
  co2PerShirt: number
  /** Wasser-Bedarf in L/Stück (zur Anzeige, nicht spielmechanisch) */
  waterPerShirt: number
  /** Arbeits-Score 0-10 (Bauern-Einkommen, Pestizid-Schutz, Kinderarbeit) */
  ethicsScore: number
  description: string
}

export const COTTON_SOURCES: CottonSource[] = [
  {
    id: 'india',
    name: 'Bauer-Kollektiv Indien',
    country: 'Indien',
    emoji: '🌾', flag: '🇮🇳',
    pos: { x: 67, y: 50 },
    pricePerShirt: 2.20,
    co2PerShirt: 1.8,
    waterPerShirt: 2700,
    ethicsScore: 4,
    description: 'Größter Baumwoll-Produzent der Welt. Sehr günstig, aber viel Wasser, oft niedrige Löhne.',
  },
  {
    id: 'usa',
    name: 'Großfarm Texas',
    country: 'USA',
    emoji: '🌾', flag: '🇺🇸',
    pos: { x: 18, y: 42 },
    pricePerShirt: 3.40,
    co2PerShirt: 2.6,
    waterPerShirt: 1900,
    ethicsScore: 7,
    description: 'Industrielle Produktion. Maschinen und viel Pestizid, dafür gute Löhne und Sicherheit.',
  },
  {
    id: 'turkey',
    name: 'Genossenschaft Türkei',
    country: 'Türkei',
    emoji: '🌾', flag: '🇹🇷',
    pos: { x: 56, y: 41 },
    pricePerShirt: 3.10,
    co2PerShirt: 1.5,
    waterPerShirt: 2200,
    ethicsScore: 6,
    description: 'Mittlere Größe, näher an Europa. Solides Gleichgewicht.',
  },
  {
    id: 'egypt',
    name: 'Bio-Baumwolle Ägypten',
    country: 'Ägypten',
    emoji: '🌿', flag: '🇪🇬',
    pos: { x: 55, y: 47 },
    pricePerShirt: 4.80,
    co2PerShirt: 0.9,
    waterPerShirt: 2500,
    ethicsScore: 9,
    description: 'Hochwertige Bio-Baumwolle. Faire Löhne, weniger Pestizid — aber teuer.',
  },
]

export interface Factory {
  id: string
  name: string
  country: string
  emoji: string
  flag: string
  pos: { x: number; y: number }
  /** Verarbeitungskosten pro T-Shirt (€) */
  pricePerShirt: number
  /** CO₂ in der Produktion (Strom + Färben) */
  co2PerShirt: number
  /** Arbeits-Score 0-10 (Sicherheit, Lohn, Stunden) */
  ethicsScore: number
  description: string
}

export const FACTORIES: Factory[] = [
  {
    id: 'bangladesh',
    name: 'Mega-Näherei Dhaka',
    country: 'Bangladesch',
    emoji: '🏭', flag: '🇧🇩',
    pos: { x: 70, y: 50 },
    pricePerShirt: 0.80,
    co2PerShirt: 1.4,
    ethicsScore: 3,
    description: 'Sehr billig. Schwache Arbeitsbedingungen, lange Stunden, niedrige Löhne.',
  },
  {
    id: 'vietnam',
    name: 'Industrie-Park Vietnam',
    country: 'Vietnam',
    emoji: '🏭', flag: '🇻🇳',
    pos: { x: 78, y: 54 },
    pricePerShirt: 1.10,
    co2PerShirt: 1.6,
    ethicsScore: 5,
    description: 'Mittlere Preise, mittlere Bedingungen. Solider Standard.',
  },
  {
    id: 'turkey-fab',
    name: 'Familien-Manufaktur Türkei',
    country: 'Türkei',
    emoji: '🏭', flag: '🇹🇷',
    pos: { x: 56, y: 41 },
    pricePerShirt: 1.80,
    co2PerShirt: 1.0,
    ethicsScore: 7,
    description: 'Kleinere Betriebe, kürzere Wege nach Europa, bessere Bedingungen.',
  },
  {
    id: 'portugal',
    name: 'Öko-Manufaktur Portugal',
    country: 'Portugal',
    emoji: '🏭', flag: '🇵🇹',
    pos: { x: 42, y: 39 },
    pricePerShirt: 3.20,
    co2PerShirt: 0.5,
    ethicsScore: 9,
    description: 'EU-Standards: Mindestlohn, Sicherheit, grüner Strom. Aber deutlich teurer.',
  },
]

// === ZIEL: WIEN ===
export const VIENNA = { x: 49, y: 38 }

// === TRANSPORT ===

export interface TransportMode {
  id: 'ship' | 'truck' | 'plane'
  name: string
  emoji: string
  /** Kosten pro 1000 km pro Stück (€) */
  costPer1000km: number
  /** CO₂ pro 1000 km pro Stück (kg) */
  co2Per1000km: number
  /** Lieferzeit in Tagen pro 1000 km */
  daysPer1000km: number
  description: string
}

export const TRANSPORT_MODES: TransportMode[] = [
  {
    id: 'ship',
    name: 'Containerschiff',
    emoji: '🚢',
    costPer1000km: 0.06,
    co2Per1000km: 0.10,
    daysPer1000km: 4.0,
    description: 'Sehr günstig und sehr klimafreundlich pro Stück. Aber langsam — und nicht überall hin.',
  },
  {
    id: 'truck',
    name: 'LKW',
    emoji: '🚛',
    costPer1000km: 0.18,
    co2Per1000km: 0.65,
    daysPer1000km: 1.5,
    description: 'Schneller als Schiff. Mittlere Kosten, hohe CO₂-Last.',
  },
  {
    id: 'plane',
    name: 'Frachtflugzeug',
    emoji: '✈️',
    costPer1000km: 1.20,
    co2Per1000km: 2.40,
    daysPer1000km: 0.3,
    description: 'Über Nacht da. Teuer und mit Abstand der größte CO₂-Ausstoß.',
  },
]

// Vereinfachte Distanztabelle (km, Luftlinie / Schiff je nach Ausrichtung)
// Wir verwenden für ALLE Transportmodi denselben Wert — vereinfacht didaktisch.
const DIST_KM: Record<string, Record<string, number>> = {
  india:  { bangladesh: 1700, vietnam: 2700, 'turkey-fab': 4400, portugal: 8000 },
  usa:    { bangladesh: 13000, vietnam: 13500, 'turkey-fab': 9500, portugal: 7800 },
  turkey: { bangladesh: 4500, vietnam: 7800, 'turkey-fab': 0, portugal: 3200 },
  egypt:  { bangladesh: 5800, vietnam: 8200, 'turkey-fab': 1100, portugal: 3700 },
}
const DIST_TO_VIENNA: Record<string, number> = {
  bangladesh: 7000,
  vietnam: 9000,
  'turkey-fab': 1600,
  portugal: 2200,
}

/** Eine konkret bestellte Charge */
export interface Order {
  cottonId: string
  factoryId: string
  transport1: TransportMode['id']    // Baumwolle → Näherei
  transport2: TransportMode['id']    // Näherei → Wien
}

// === KONFIGURATION ===

/**
 * Lehrer-Konfiguration. Drei Parameter, die ein*e Lehrperson später
 * über ein Dashboard setzen kann (URL-Parameter heute, UI später).
 *
 * Defaults entsprechen dem mittleren Schwierigkeitsgrad.
 */
export interface SimConfig {
  /** Startbudget in Mio € */
  startMoney: number
  /** IDs der zugelassenen Cotton-Sources / Factories / Transport-Modi */
  enabledOptions: {
    cotton: string[]
    factory: string[]
    transport: TransportMode['id'][]
  }
  /** IDs der zugelassenen Welt-Ereignisse */
  enabledEvents: string[]
}

export const DEFAULT_CONFIG: SimConfig = {
  startMoney: 800,
  enabledOptions: {
    cotton:    ['india', 'usa', 'turkey', 'egypt'],
    factory:   ['bangladesh', 'vietnam', 'turkey-fab', 'portugal'],
    transport: ['ship', 'truck', 'plane'],
  },
  enabledEvents: ['drought-india', 'wage-bangladesh', 'suez', 'eu-co2-tax', 'consumer-pressure'],
}

/** Spiel-Mechanik */
const SHIRTS_PER_ORDER = 5000
const MARKET_PRICE = 12.0  // €/Stück, was du für ein T-Shirt bekommst
const CO2_GOAL_KG = 6.0     // unter 6 kg CO₂/Stück = klimaziel
const ETHICS_GOAL = 5.0     // ≥ 5 = ethik-ziel

interface OrderHistory {
  tick: number
  cottonId: string
  factoryId: string
  transport1: TransportMode['id']
  transport2: TransportMode['id']
  shirts: number
  costPerShirt: number
  co2PerShirt: number
  ethicsScore: number
  profit: number
}

export class LieferkettenGame extends GameEngine {
  private config: SimConfig
  private history: OrderHistory[] = []
  /** Zeitlich verschobene Welt-Ereignisse — können Werte mutieren */
  private activeEffects: Record<string, number> = {}
  /** Bisher gefeuerte Events */
  private firedEvents = new Set<string>()

  constructor(config: Partial<SimConfig> = {}) {
    super(META)
    this.config = {
      ...DEFAULT_CONFIG,
      ...config,
      enabledOptions: { ...DEFAULT_CONFIG.enabledOptions, ...(config.enabledOptions || {}) },
    }
    this.setupResources()
    this.setupGoals()
    this.setupTutorial()
  }

  getConfig(): SimConfig {
    return this.config
  }

  getHistory(): OrderHistory[] {
    return this.history
  }

  getCurrentYear(): number {
    return START_YEAR + Math.floor(this.tick / 4)
  }

  private setupResources(): void {
    this.addResource({
      id: 'budget',
      name: 'Budget',
      icon: '💰',
      initial: this.config.startMoney,
      unit: 'Mio €',
      format: (v) => `${Math.round(v)} Mio €`,
    })
    this.addResource({
      id: 'co2_avg',
      name: 'Ø CO₂ pro Shirt',
      icon: '🌫',
      initial: 0,
      unit: 'kg',
      format: (v) => `${v.toFixed(1)} kg`,
    })
    this.addResource({
      id: 'ethics_avg',
      name: 'Ø Ethik-Score',
      icon: '⚖️',
      initial: 0,
      unit: 'von 10',
      format: (v) => `${v.toFixed(1)} / 10`,
    })
    this.addResource({
      id: 'shirts_total',
      name: 'Verkaufte Shirts',
      icon: '👕',
      initial: 0,
      unit: 'Stück',
      format: (v) => `${Math.round(v).toLocaleString('de-AT')}`,
    })
  }

  private setupGoals(): void {
    this.addGoal({
      id: 'survive',
      title: 'Bis Quartal 20 überleben',
      description: 'Halte dein Budget über 0 Mio € durchgehend.',
      check: (g) => (g as LieferkettenGame).tick >= 20,
      progress: (g) => Math.min(100, ((g as LieferkettenGame).tick / 20) * 100),
      required: true,
    })
    this.addGoal({
      id: 'co2',
      title: `Ø CO₂ unter ${CO2_GOAL_KG} kg/Shirt`,
      description: 'Nachhaltige Lieferketten — der Klima-Fußabdruck deiner Modemarke.',
      check: (g) => {
        const v = g.getResource('co2_avg')
        return v > 0 && v < CO2_GOAL_KG
      },
      progress: (g) => {
        const v = g.getResource('co2_avg')
        if (v === 0) return 0
        return Math.max(0, Math.min(100, (1 - (v - 4) / 6) * 100))
      },
      required: true,
    })
    this.addGoal({
      id: 'ethics',
      title: `Ø Ethik-Score über ${ETHICS_GOAL}`,
      description: 'Faire Arbeitsbedingungen entlang der ganzen Lieferkette.',
      check: (g) => g.getResource('ethics_avg') >= ETHICS_GOAL,
      progress: (g) => Math.max(0, Math.min(100, (g.getResource('ethics_avg') / 10) * 100)),
      required: true,
    })
    this.addGoal({
      id: 'budget',
      title: 'Nicht pleite gehen',
      description: 'Halte ein positives Budget bis zum Spielende.',
      check: (g) => g.getResource('budget') > 0,
      required: true,
    })
  }

  private setupTutorial(): void {
    this.setTutorial([
      {
        triggerTick: 0,
        title: 'Willkommen, Einkaufsleiter*in!',
        text: 'Du leitest den Einkauf einer kleinen Modemarke in Wien. Alle 3 Monate (=1 Quartal) musst du eine neue Charge T-Shirts bestellen.\n\nEine Charge sind 5.000 Stück. Du verkaufst sie für 12 € pro Stück — das macht 60.000 € Umsatz pro Charge.\n\nAber: Dein Gewinn hängt davon ab, was du für die Produktion bezahlst.',
        unlocks: ['budget-display'],
      },
      {
        triggerTick: 0,
        title: 'Drei Stufen der Lieferkette',
        text: 'Jede Bestellung hat 3 Entscheidungen:\n\n🌾 BAUMWOLLE — Wo wird sie angebaut? (4 Länder)\n🏭 NÄHEREI — Wo wird das Shirt genäht? (4 Länder)\n🚢 TRANSPORT — Wie kommt es nach Wien? (Schiff/LKW/Flugzeug)\n\nEs gibt also 4 × 4 × 3 × 3 = 144 mögliche Lieferketten. Welche ist die beste? Es kommt darauf an, was DU willst.',
        unlocks: ['order-form'],
      },
      {
        triggerTick: 0,
        title: 'Drei Werte zählen',
        text: 'Du hast 3 Hauptziele — alle gleichzeitig:\n\n💰 BUDGET — bleibe profitabel\n🌫 CO₂ — der durchschnittliche Klimaabdruck pro Shirt soll unter 6 kg bleiben\n⚖️ ETHIK — der Ø-Wert für Arbeitsbedingungen soll über 5 von 10 liegen\n\nDie drei stehen oft im Widerspruch. Du musst abwägen — wie im echten Leben.',
        unlocks: ['goals'],
      },
      {
        triggerTick: 0,
        title: 'Bereit?',
        text: 'Im Verlauf der Simulation passieren Welt-Ereignisse: Dürren, Lohnerhöhungen, Suezkanal-Stau, Klimazölle. Sie verändern die Werte einzelner Standorte.\n\nDu hast 20 Quartale (= 5 Jahre) Zeit. Klick eine Bestellung zusammen und drücke „Bestellen".\n\nLos geht\'s! 🚢',
        unlocks: ['controls'],
      },
    ])
  }

  /**
   * Simuliere eine Bestellung (vom Spieler ausgelöst). Wendet sofort die
   * Effekte an und schreibt einen History-Eintrag.
   */
  placeOrder(order: Order): boolean {
    const cotton = COTTON_SOURCES.find(c => c.id === order.cottonId)
    const factory = FACTORIES.find(f => f.id === order.factoryId)
    const t1 = TRANSPORT_MODES.find(t => t.id === order.transport1)
    const t2 = TRANSPORT_MODES.find(t => t.id === order.transport2)
    if (!cotton || !factory || !t1 || !t2) return false

    // Welt-Effekte anwenden
    const cottonPrice = cotton.pricePerShirt * (1 + (this.activeEffects[`cotton-${cotton.id}-price`] || 0))
    const factoryPrice = factory.pricePerShirt * (1 + (this.activeEffects[`factory-${factory.id}-price`] || 0))
    const cottonCO2 = cotton.co2PerShirt
    const factoryCO2 = factory.co2PerShirt
    const cottonEthics = cotton.ethicsScore + (this.activeEffects[`cotton-${cotton.id}-ethics`] || 0)
    const factoryEthics = factory.ethicsScore + (this.activeEffects[`factory-${factory.id}-ethics`] || 0)

    // Distanzen
    const dist1 = (DIST_KM[cotton.id]?.[factory.id] ?? 5000) / 1000
    const dist2 = (DIST_TO_VIENNA[factory.id] ?? 3000) / 1000

    // Transportkosten und CO₂
    const t1Cost = t1.costPer1000km * dist1 * (1 + (this.activeEffects[`transport-${t1.id}-cost`] || 0))
    const t2Cost = t2.costPer1000km * dist2 * (1 + (this.activeEffects[`transport-${t2.id}-cost`] || 0))
    const t1CO2 = t1.co2Per1000km * dist1
    const t2CO2 = t2.co2Per1000km * dist2

    // Pro-Stück-Werte
    const costPerShirt = cottonPrice + factoryPrice + t1Cost + t2Cost
    const co2PerShirt = cottonCO2 + factoryCO2 + t1CO2 + t2CO2
    // Gewichteter Ethik-Mittelwert (Cotton 50 %, Factory 50 %)
    const ethicsScore = (cottonEthics + factoryEthics) / 2

    // Wirtschaft: Verkauf − Einkauf − Transport (bezogen auf 5000 Stück)
    // Wir rechnen in Tausend €, dann zu Mio € → /1000
    const totalRevenue = SHIRTS_PER_ORDER * MARKET_PRICE / 1000      // k€
    const totalCost    = SHIRTS_PER_ORDER * costPerShirt / 1000      // k€
    const profitKEur   = totalRevenue - totalCost
    const profitMio    = profitKEur / 1000                            // Mio €
    this.changeResource('budget', profitMio)

    // Durchschnittliche CO₂- und Ethik-Werte aktualisieren (gewichteter Mittelwert)
    const oldShirts = this.getResource('shirts_total')
    const newShirts = oldShirts + SHIRTS_PER_ORDER
    const oldCO2avg = this.getResource('co2_avg')
    const newCO2avg = oldShirts === 0
      ? co2PerShirt
      : (oldCO2avg * oldShirts + co2PerShirt * SHIRTS_PER_ORDER) / newShirts
    const oldEthAvg = this.getResource('ethics_avg')
    const newEthAvg = oldShirts === 0
      ? ethicsScore
      : (oldEthAvg * oldShirts + ethicsScore * SHIRTS_PER_ORDER) / newShirts

    this.setResource('co2_avg', newCO2avg)
    this.setResource('ethics_avg', newEthAvg)
    this.setResource('shirts_total', newShirts)

    // History
    this.history.push({
      tick: this.tick,
      cottonId: cotton.id,
      factoryId: factory.id,
      transport1: t1.id,
      transport2: t2.id,
      shirts: SHIRTS_PER_ORDER,
      costPerShirt,
      co2PerShirt,
      ethicsScore,
      profit: profitMio,
    })

    // Event für die Anzeige
    const profitStr = profitMio >= 0 ? `+${profitMio.toFixed(1)}` : profitMio.toFixed(1)
    this.addEvent(
      'order-' + this.tick + '-' + this.history.length,
      `${cotton.flag}→${factory.flag} ${t1.emoji}${t2.emoji} · ${profitStr} Mio € · ${co2PerShirt.toFixed(1)} kg CO₂ · Ethik ${ethicsScore.toFixed(0)}/10`,
      profitMio >= 0 ? 'success' : 'warning',
    )

    this.notify()
    return true
  }

  protected simulateTick(): void {
    // Fixkosten pro Quartal (Marketing, Mieten, Lohn): 8 Mio €
    this.changeResource('budget', -8)

    // Welt-Ereignisse (Tick-basiert, einmalig)
    this.maybeFireEvent()
  }

  /** Welt-Ereignisse, die Standort-Werte verändern */
  private maybeFireEvent(): void {
    const enabled = new Set(this.config.enabledEvents)
    const fire = (id: string, body: () => void) => {
      if (!enabled.has(id) || this.firedEvents.has(id)) return
      this.firedEvents.add(id)
      body()
    }

    if (this.tick === 5) {
      fire('drought-india', () => {
        this.activeEffects['cotton-india-price'] = 0.40
        this.addEvent(
          'drought-india',
          '🌵 Trockenheit in Indien — Baumwoll-Preis +40 %.',
          'warning',
        )
      })
    }
    if (this.tick === 8) {
      fire('wage-bangladesh', () => {
        this.activeEffects['factory-bangladesh-price'] = 0.30
        this.activeEffects['factory-bangladesh-ethics'] = 2
        this.addEvent(
          'wage-bangladesh',
          '✊ Bangladesch erhöht den Mindestlohn — +30 % Preis, aber +2 Ethik.',
          'info',
        )
      })
    }
    if (this.tick === 11) {
      fire('suez', () => {
        this.activeEffects['transport-ship-cost'] = 0.50
        this.addEvent(
          'suez',
          '🚧 Schiffs-Stau im Suezkanal — Containerschiff +50 % Kosten.',
          'warning',
        )
      })
    }
    if (this.tick === 14) {
      fire('eu-co2-tax', () => {
        this.activeEffects['transport-plane-cost'] = 0.60
        this.activeEffects['transport-truck-cost'] = 0.30
        this.addEvent(
          'eu-co2-tax',
          '🇪🇺 EU-Klimazoll — Flug +60 %, LKW +30 %.',
          'warning',
        )
      })
    }
    if (this.tick === 17) {
      fire('consumer-pressure', () => {
        // Konsumenten verlangen Nachhaltigkeit — Bonus für Bio/EU
        this.activeEffects['cotton-egypt-price'] = -0.15
        this.activeEffects['factory-portugal-price'] = -0.15
        this.addEvent(
          'consumer-pressure',
          '📰 Kund*innen verlangen Nachhaltigkeit — Bio-Baumwolle und EU-Manufaktur −15 %.',
          'success',
        )
      })
    }
  }

  protected checkLossCondition(): boolean {
    return this.getResource('budget') < -100
  }

  protected serializeSubclass(): Record<string, unknown> {
    return {
      config: this.config,
      history: this.history,
      activeEffects: this.activeEffects,
      firedEvents: Array.from(this.firedEvents),
    }
  }

  protected deserializeSubclass(data: Record<string, unknown>): void {
    if (data.config) this.config = data.config as SimConfig
    if (Array.isArray(data.history)) this.history = data.history as OrderHistory[]
    if (data.activeEffects) this.activeEffects = data.activeEffects as Record<string, number>
    if (Array.isArray(data.firedEvents)) this.firedEvents = new Set(data.firedEvents as string[])
  }
}
