/* global React, ReactDOM */
const { useEffect, useRef, useState } = React;

// =====================================================
// Celebration: Riso-style confetti + ping when 100% done
// Uses canvas for confetti, Web Audio for ping.
// Only triggers ONCE per session per "fresh 100%" event.
// =====================================================
function Celebration({active, lang, onDismiss}) {
  const canvasRef = useRef(null);
  const rafRef = useRef(0);
  const [visible, setVisible] = useState(false);

  // Trigger
  useEffect(() => {
    if (!active) return;
    setVisible(true);

    // Play a soft ping (Web Audio — generated, no asset)
    try {
      const AC = window.AudioContext || window.webkitAudioContext;
      if (AC) {
        const ctx = new AC();
        const playTone = (freq, t0, dur=0.6, gain=0.18) => {
          const osc = ctx.createOscillator();
          const g = ctx.createGain();
          osc.type = 'sine';
          osc.frequency.value = freq;
          g.gain.setValueAtTime(0, ctx.currentTime + t0);
          g.gain.linearRampToValueAtTime(gain, ctx.currentTime + t0 + 0.02);
          g.gain.exponentialRampToValueAtTime(0.0001, ctx.currentTime + t0 + dur);
          osc.connect(g); g.connect(ctx.destination);
          osc.start(ctx.currentTime + t0);
          osc.stop(ctx.currentTime + t0 + dur + 0.02);
        };
        // Pleasant chord: C5, E5, G5
        playTone(523.25, 0.0, 0.7, 0.18);
        playTone(659.25, 0.08, 0.7, 0.15);
        playTone(783.99, 0.16, 0.9, 0.13);
        // Bell sparkle
        playTone(1046.5, 0.45, 0.5, 0.1);
      }
    } catch(e) { /* ignore */ }

    // Confetti burst
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const dpr = window.devicePixelRatio || 1;
    const resize = () => {
      canvas.width = window.innerWidth * dpr;
      canvas.height = window.innerHeight * dpr;
      canvas.style.width = window.innerWidth + 'px';
      canvas.style.height = window.innerHeight + 'px';
      ctx.setTransform(dpr,0,0,dpr,0,0);
    };
    resize();
    window.addEventListener('resize', resize);

    const W = () => window.innerWidth;
    const H = () => window.innerHeight;
    const COLORS = ['#ff5294', '#ffe600', '#2c5fff', '#1a1a1a', '#ff6b1f', '#16c79a', '#b478ff'];
    const SHAPES = ['rect', 'circle', 'ring', 'rect'];

    // Particles
    const particles = [];
    const launch = (originX, originY, count) => {
      for (let i = 0; i < count; i++) {
        const angle = -Math.PI/2 + (Math.random() - 0.5) * Math.PI * 0.85;
        const speed = 9 + Math.random() * 11;
        particles.push({
          x: originX, y: originY,
          vx: Math.cos(angle) * speed,
          vy: Math.sin(angle) * speed,
          g: 0.32 + Math.random() * 0.12,
          drag: 0.985,
          size: 6 + Math.random() * 8,
          color: COLORS[(Math.random()*COLORS.length)|0],
          shape: SHAPES[(Math.random()*SHAPES.length)|0],
          rot: Math.random() * Math.PI * 2,
          vr: (Math.random() - 0.5) * 0.35,
          life: 0,
          maxLife: 180 + Math.random() * 120,
        });
      }
    };

    // Two bursts from sides + one center
    launch(W()*0.18, H()*0.85, 90);
    launch(W()*0.82, H()*0.85, 90);
    setTimeout(() => launch(W()*0.5, H()*0.55, 60), 260);
    setTimeout(() => {
      launch(W()*0.3, H()*0.7, 50);
      launch(W()*0.7, H()*0.7, 50);
    }, 520);

    let t0 = performance.now();
    const tick = (t) => {
      ctx.clearRect(0, 0, W(), H());
      for (let i = particles.length - 1; i >= 0; i--) {
        const p = particles[i];
        p.vx *= p.drag;
        p.vy = p.vy * p.drag + p.g;
        p.x += p.vx;
        p.y += p.vy;
        p.rot += p.vr;
        p.life++;
        const fade = p.life > p.maxLife - 60 ? Math.max(0, (p.maxLife - p.life)/60) : 1;
        ctx.save();
        ctx.translate(p.x, p.y);
        ctx.rotate(p.rot);
        ctx.globalAlpha = fade;
        ctx.fillStyle = p.color;
        ctx.strokeStyle = p.color;
        if (p.shape === 'rect') {
          ctx.fillRect(-p.size/2, -p.size/3, p.size, p.size * 0.66);
        } else if (p.shape === 'circle') {
          ctx.beginPath();
          ctx.arc(0, 0, p.size/2, 0, Math.PI*2);
          ctx.fill();
        } else { // ring
          ctx.lineWidth = 2;
          ctx.beginPath();
          ctx.arc(0, 0, p.size/2, 0, Math.PI*2);
          ctx.stroke();
        }
        ctx.restore();
        if (p.y > H() + 40 || p.life > p.maxLife) particles.splice(i, 1);
      }
      if (particles.length > 0 && performance.now() - t0 < 8000) {
        rafRef.current = requestAnimationFrame(tick);
      } else {
        ctx.clearRect(0, 0, W(), H());
      }
    };
    rafRef.current = requestAnimationFrame(tick);

    return () => {
      cancelAnimationFrame(rafRef.current);
      window.removeEventListener('resize', resize);
    };
  }, [active]);

  if (!visible) return null;

  return (
    <div className="celebrate-overlay" onClick={() => { setVisible(false); onDismiss && onDismiss(); }}>
      <canvas ref={canvasRef} className="celebrate-canvas"/>
      <div className="celebrate-card" onClick={e => e.stopPropagation()}>
        <div className="celebrate-stamp">
          <span className="cs-y"/><span className="cs-p"/><span className="cs-b"/><span className="cs-k"/>
        </div>
        <div className="celebrate-tag">100% COMPLETE</div>
        <h2 className="celebrate-title">
          {lang === 'en' ? 'Beautifully done.' : 'お疲れさまでした！'}
        </h2>
        <p className="celebrate-sub">
          {lang === 'en'
            ? 'All checklists are clear. Your print run is finished — clean the drums, file the proof, and call it.'
            : '全チェックリストを完了しました。ドラムを清掃し、校正紙を保管して、片付けに入りましょう。'}
        </p>
        <button className="celebrate-btn" onClick={() => { setVisible(false); onDismiss && onDismiss(); }}>
          {lang === 'en' ? 'Close' : '閉じる'}
        </button>
      </div>
    </div>
  );
}

window.Celebration = Celebration;
