/**
 * SIM-09: Energiemix-Simulator — Canvas Renderer
 *
 * Visualisiert:
 * - Donut-Diagramm des aktuellen Mixes
 * - Drei Tachos: CO₂, Kosten, Versorgungssicherheit
 * - Score-Anzeige in der Mitte
 * - Animierte Energie-Icons (Wind dreht, Sonne strahlt)
 *
 * Stil: Skandinavisch mit subtiler Bewegung
 */

import { EnergiemixSimulation, ENERGY_SOURCES, computeMixResult } from './logic'

export class EnergiemixRenderer {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D
  private sim: EnergiemixSimulation
  private W = 0
  private H = 0
  private t = 0
  private animId = 0

  private col = {
    bg: '#fafaf8',
    text: '#1a1a1a',
    muted: '#6a6a6a',
    line: '#e0ddd6',
  }

  constructor(container: HTMLElement, sim: EnergiemixSimulation) {
    this.sim = sim
    this.canvas = document.createElement('canvas')
    this.canvas.style.cssText = 'width:100%;height:100%;display:block;border-radius:12px;background:#fafaf8;'
    container.appendChild(this.canvas)
    const ctx = this.canvas.getContext('2d')
    if (!ctx) throw new Error('Canvas not supported')
    this.ctx = ctx
    this.resize()
    window.addEventListener('resize', () => this.resize())
  }

  private resize(): void {
    const rect = this.canvas.parentElement!.getBoundingClientRect()
    const dpr = window.devicePixelRatio || 1
    this.W = rect.width
    this.H = Math.min(rect.width * 0.7, 540)
    this.canvas.width = this.W * dpr
    this.canvas.height = this.H * dpr
    this.canvas.style.height = this.H + 'px'
    this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
  }

  start(): void {
    const loop = () => {
      this.t += 0.016
      this.draw()
      this.animId = requestAnimationFrame(loop)
    }
    loop()
  }

  stop(): void {
    cancelAnimationFrame(this.animId)
  }

  private draw(): void {
    const { ctx, W, H } = this
    ctx.clearRect(0, 0, W, H)

    const result = this.sim.compute()
    const mix: Record<string, number> = {}
    for (const src of ENERGY_SOURCES) mix[src.id] = this.sim.getVariable(src.id)

    // ===== LEFT: Donut Chart =====
    const donutCx = W * 0.28
    const donutCy = H * 0.45
    const donutR = Math.min(W * 0.18, 95)
    const innerR = donutR * 0.6

    let startAngle = -Math.PI / 2
    const total = Object.values(mix).reduce((a, b) => a + b, 0) || 1

    for (const src of ENERGY_SOURCES) {
      const share = (mix[src.id] || 0) / total
      if (share <= 0) continue
      const angle = share * Math.PI * 2

      ctx.fillStyle = src.color
      ctx.beginPath()
      ctx.moveTo(donutCx, donutCy)
      ctx.arc(donutCx, donutCy, donutR, startAngle, startAngle + angle)
      ctx.closePath()
      ctx.fill()

      startAngle += angle
    }

    // Inner hole (donut)
    ctx.fillStyle = this.col.bg
    ctx.beginPath()
    ctx.arc(donutCx, donutCy, innerR, 0, Math.PI * 2)
    ctx.fill()

    // Score in center
    ctx.fillStyle = this.col.text
    ctx.font = 'bold 28px Inter, sans-serif'
    ctx.textAlign = 'center'
    ctx.textBaseline = 'middle'
    ctx.fillText(`${result.score}`, donutCx, donutCy - 4)
    ctx.font = '10px Inter, sans-serif'
    ctx.fillStyle = this.col.muted
    ctx.fillText('Score', donutCx, donutCy + 14)

    // Donut title
    ctx.font = 'bold 13px Inter, sans-serif'
    ctx.fillStyle = this.col.text
    ctx.fillText('Energiemix', donutCx, donutCy - donutR - 18)

    // Rating below donut
    ctx.font = 'bold 11px Inter, sans-serif'
    ctx.fillStyle = result.score >= 65 ? '#5a8a5e' : result.score >= 50 ? '#c4a35a' : '#c0503c'
    ctx.fillText(result.rating, donutCx, donutCy + donutR + 18)

    // ===== RIGHT: Three Gauges =====
    const gx = W * 0.62
    const gw = W * 0.32
    const gaugeH = H * 0.22

    // CO₂ gauge
    this.drawGauge(ctx, gx, H * 0.12, gw, gaugeH,
      'CO₂-Ausstoß', `${result.totalCO2} t/GWh`,
      result.totalCO2, 0, 800, 'reverse', '#c0503c'
    )

    // Cost gauge
    this.drawGauge(ctx, gx, H * 0.4, gw, gaugeH,
      'Kosten', `${result.totalCost} €/MWh`,
      result.totalCost, 30, 100, 'reverse', '#c4a35a'
    )

    // Reliability gauge
    this.drawGauge(ctx, gx, H * 0.68, gw, gaugeH,
      'Versorgungssicherheit', `${(result.totalReliability * 100).toFixed(0)}%`,
      result.totalReliability * 100, 0, 100, 'normal', '#5a8a5e'
    )

    // Renewable share at bottom
    ctx.font = 'bold 11px Inter, sans-serif'
    ctx.fillStyle = this.col.text
    ctx.textAlign = 'center'
    ctx.fillText(`Erneuerbare: ${result.renewableShare}%`, donutCx, H - 18)

    // Animated icons around the donut
    this.drawAnimatedIcons(ctx, donutCx, donutCy, donutR + 30, mix)
  }

  private drawGauge(
    ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number,
    label: string, valueText: string,
    value: number, min: number, max: number,
    direction: 'normal' | 'reverse',
    color: string
  ): void {
    // Label
    ctx.fillStyle = this.col.muted
    ctx.font = 'bold 10px Inter, sans-serif'
    ctx.textAlign = 'left'
    ctx.fillText(label.toUpperCase(), x, y)

    // Value
    ctx.fillStyle = this.col.text
    ctx.font = 'bold 18px Inter, sans-serif'
    ctx.fillText(valueText, x, y + 22)

    // Bar background
    const barY = y + 32
    const barH = 8
    ctx.fillStyle = '#e8e5dc'
    ctx.beginPath()
    ctx.roundRect(x, barY, w, barH, 4)
    ctx.fill()

    // Bar fill
    const ratio = Math.max(0, Math.min(1, (value - min) / (max - min)))
    const fillRatio = direction === 'reverse' ? 1 - ratio : ratio
    const fillW = w * Math.max(0, Math.min(1, fillRatio))

    ctx.fillStyle = color
    ctx.beginPath()
    ctx.roundRect(x, barY, fillW, barH, 4)
    ctx.fill()

    // Min/max labels
    ctx.font = '9px Inter, sans-serif'
    ctx.fillStyle = this.col.muted
    ctx.textAlign = 'left'
    ctx.fillText(direction === 'reverse' ? 'Schlecht' : `${min}`, x, barY + 22)
    ctx.textAlign = 'right'
    ctx.fillText(direction === 'reverse' ? 'Gut' : `${max}`, x + w, barY + 22)
  }

  private drawAnimatedIcons(ctx: CanvasRenderingContext2D, cx: number, cy: number, r: number, mix: Record<string, number>): void {
    let i = 0
    for (const src of ENERGY_SOURCES) {
      const share = mix[src.id] || 0
      if (share <= 0) { i++; continue }

      const angle = (i / ENERGY_SOURCES.length) * Math.PI * 2 - Math.PI / 2
      const x = cx + Math.cos(angle) * r
      const y = cy + Math.sin(angle) * r

      // Background circle
      ctx.fillStyle = src.color
      ctx.globalAlpha = 0.15
      ctx.beginPath()
      ctx.arc(x, y, 14, 0, Math.PI * 2)
      ctx.fill()
      ctx.globalAlpha = 1

      // Icon (emoji)
      ctx.font = '14px sans-serif'
      ctx.textAlign = 'center'
      ctx.textBaseline = 'middle'
      ctx.fillText(src.emoji, x, y + 1)

      // Share label
      ctx.fillStyle = this.col.text
      ctx.font = 'bold 9px Inter, sans-serif'
      ctx.fillText(`${share}%`, x, y + 22)

      i++
    }
    ctx.textBaseline = 'alphabetic'
  }
}
