import { useEffect, useRef } from 'react'

interface Ember {
  x: number
  y: number
  vx: number
  vy: number
  r: number
  life: number
  maxLife: number
  drift: number
}

export default function CandleCanvas() {
  const canvasRef = useRef<HTMLCanvasElement | null>(null)

  useEffect(() => {
    const canvas = canvasRef.current
    if (!canvas) return
    const ctx = canvas.getContext('2d')
    if (!ctx) return

    const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches

    let w = 0
    let h = 0
    let dpr = 1
    let raf = 0
    const embers: Ember[] = []

    const resize = () => {
      dpr = Math.min(window.devicePixelRatio || 1, 2)
      w = window.innerWidth
      h = window.innerHeight
      canvas.width = Math.round(w * dpr)
      canvas.height = Math.round(h * dpr)
      canvas.style.width = `${w}px`
      canvas.style.height = `${h}px`
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
    }
    resize()
    window.addEventListener('resize', resize)

    const rand = (a: number, b: number) => a + Math.random() * (b - a)
    const cx = () => w / 2

    const flameBaseY = () => h * 0.9
    const flameH = () => 58 * Math.min(1, w / 900) + 22
    const flameW = () => flameH() * 0.52
    const flameTipY = () => flameBaseY() - flameH()

    const spawnEmber = () => {
      embers.push({
        x: cx() + rand(-flameW() * 0.5, flameW() * 0.5),
        y: flameTipY() + rand(0, 8),
        vx: rand(-0.3, 0.3),
        vy: rand(-0.75, -0.4),
        r: rand(0.7, 1.9),
        life: 0,
        maxLife: rand(240, 520),
        drift: rand(0, Math.PI * 2),
      })
    }

    const drawGlow = (t: number) => {
      const gx = cx()
      const gy = flameBaseY() - flameH() * 0.4
      const pulse = 0.5 + 0.5 * Math.sin(t * 0.0013)
      const radius = Math.max(w, h) * 0.5
      const glow = ctx.createRadialGradient(gx, gy, 10, gx, gy, radius)
      glow.addColorStop(0, `rgba(255, 168, 82, ${0.09 + 0.03 * pulse})`)
      glow.addColorStop(0.4, `rgba(200, 110, 45, ${0.035 + 0.015 * pulse})`)
      glow.addColorStop(1, 'rgba(0, 0, 0, 0)')
      ctx.fillStyle = glow
      ctx.fillRect(0, 0, w, h)
    }

    const drawWax = () => {
      const x = cx()
      const top = flameBaseY() + 10
      const bottom = h + 40
      const half = 20 * Math.min(1, w / 900) + 10
      const left = x - half
      const right = x + half

      const body = ctx.createLinearGradient(left, 0, right, 0)
      body.addColorStop(0, '#d9c9a4')
      body.addColorStop(0.5, '#f2e6c8')
      body.addColorStop(1, '#cbbb94')
      ctx.fillStyle = body

      ctx.beginPath()
      ctx.moveTo(left, top)
      ctx.lineTo(right, top)
      ctx.lineTo(right, bottom)
      ctx.lineTo(left, bottom)
      ctx.closePath()
      ctx.fill()

      const drop = ctx.createLinearGradient(left, 0, right, 0)
      drop.addColorStop(0, '#d9c9a4')
      drop.addColorStop(1, '#cbbb94')
      ctx.fillStyle = drop

      for (let i = 0; i < 3; i++) {
        const dx = left - 5 + i * 5
        const dy = top + 14 + i * 22
        const len = 26 + i * 9
        ctx.beginPath()
        ctx.moveTo(dx, dy - 12)
        ctx.quadraticCurveTo(dx + 4, dy, dx + 4, dy + len)
        ctx.quadraticCurveTo(dx + 4, dy + len + 7, dx, dy + len + 7)
        ctx.quadraticCurveTo(dx - 4, dy + len + 7, dx - 4, dy + len)
        ctx.quadraticCurveTo(dx - 4, dy, dx, dy - 12)
        ctx.closePath()
        ctx.fill()
      }

      const topEdge = ctx.createLinearGradient(0, top, 0, top + 10)
      topEdge.addColorStop(0, '#fdf3da')
      topEdge.addColorStop(1, 'rgba(253, 243, 218, 0)')
      ctx.fillStyle = topEdge
      ctx.fillRect(left, top - 2, half * 2, 10)

      ctx.strokeStyle = '#2b2017'
      ctx.lineWidth = 2.5
      ctx.lineCap = 'round'
      ctx.beginPath()
      ctx.moveTo(x, flameBaseY())
      ctx.lineTo(x, top)
      ctx.stroke()
    }

    const drawFlame = (t: number) => {
      const fh = flameH() * (1 + 0.09 * Math.sin(t * 0.011) + 0.045 * Math.sin(t * 0.031 + 1.7))
      const fw = flameW() * (1 + 0.08 * Math.sin(t * 0.017 + 0.6) + 0.04 * Math.sin(t * 0.043))
      const tipX = cx()
      const tipY = flameTipY() - (fh - flameH()) * 0.6
      const baseY = tipY + fh

      const outer = ctx.createRadialGradient(tipX, baseY - fh * 0.45, 2, tipX, baseY - fh * 0.5, fw * 2.2)
      outer.addColorStop(0, 'rgba(255, 244, 214, 0.95)')
      outer.addColorStop(0.35, 'rgba(255, 205, 120, 0.85)')
      outer.addColorStop(0.7, 'rgba(240, 140, 60, 0.45)')
      outer.addColorStop(1, 'rgba(240, 120, 40, 0)')

      ctx.save()
      ctx.translate(tipX, baseY)
      ctx.scale(1, -1)

      ctx.beginPath()
      ctx.moveTo(0, 0)
      ctx.quadraticCurveTo(fw * 0.75, fh * 0.15, fw * 0.34, fh * 0.72)
      ctx.quadraticCurveTo(fw * 0.12, fh * 0.97, 0, fh)
      ctx.quadraticCurveTo(-fw * 0.12, fh * 0.97, -fw * 0.34, fh * 0.72)
      ctx.quadraticCurveTo(-fw * 0.75, fh * 0.15, 0, 0)
      ctx.closePath()
      ctx.fillStyle = outer
      ctx.fill()

      const ih = fh * 0.42
      const iw = fw * 0.4
      ctx.beginPath()
      ctx.moveTo(0, fh * 0.16)
      ctx.quadraticCurveTo(iw * 0.7, fh * 0.16 + ih * 0.28, iw * 0.3, fh * 0.16 + ih * 0.82)
      ctx.quadraticCurveTo(iw * 0.1, fh * 0.16 + ih * 1.05, 0, fh * 0.16 + ih)
      ctx.quadraticCurveTo(-iw * 0.1, fh * 0.16 + ih * 1.05, -iw * 0.3, fh * 0.16 + ih * 0.82)
      ctx.quadraticCurveTo(-iw * 0.7, fh * 0.16 + ih * 0.28, 0, fh * 0.16)
      ctx.closePath()
      const inner = ctx.createRadialGradient(0, fh * 0.55, 1, 0, fh * 0.58, iw * 1.4)
      inner.addColorStop(0, 'rgba(255, 252, 240, 1)')
      inner.addColorStop(0.6, 'rgba(255, 226, 160, 0.9)')
      inner.addColorStop(1, 'rgba(255, 190, 90, 0)')
      ctx.fillStyle = inner
      ctx.fill()

      ctx.restore()
    }

    const drawEmbers = () => {
      ctx.globalCompositeOperation = 'lighter'
      for (let i = embers.length - 1; i >= 0; i--) {
        const e = embers[i]
        e.life += 1
        e.x += e.vx + Math.sin(e.life * 0.02 + e.drift) * 0.3
        e.y += e.vy
        if (e.life >= e.maxLife || e.y < -30) {
          embers.splice(i, 1)
          continue
        }
        const alpha = Math.max(0, 1 - e.life / e.maxLife)
        const grad = ctx.createRadialGradient(e.x, e.y, 0, e.x, e.y, e.r * 3.2)
        grad.addColorStop(0, `rgba(255, 214, 140, ${alpha})`)
        grad.addColorStop(0.5, `rgba(240, 150, 70, ${alpha * 0.6})`)
        grad.addColorStop(1, 'rgba(240, 120, 40, 0)')
        ctx.fillStyle = grad
        ctx.beginPath()
        ctx.arc(e.x, e.y, e.r * 3.2, 0, Math.PI * 2)
        ctx.fill()
      }
      ctx.globalCompositeOperation = 'source-over'
    }

    const draw = (t: number) => {
      ctx.clearRect(0, 0, w, h)
      drawGlow(t)
      drawWax()
      drawFlame(t)
      if (!reduced) {
        if (embers.length < 70 && Math.random() < 0.14) spawnEmber()
        drawEmbers()
      }
    }

    const loop = (t: number) => {
      draw(t)
      raf = requestAnimationFrame(loop)
    }

    if (reduced) {
      draw(0)
    } else {
      raf = requestAnimationFrame(loop)
    }

    return () => {
      cancelAnimationFrame(raf)
      window.removeEventListener('resize', resize)
    }
  }, [])

  return <canvas ref={canvasRef} className="candle-canvas" aria-hidden="true" />
}