// hero-canvas.jsx
// Cinematic ambient motion for the Project Silk hero.
// Stand-in for the AI-generated hero video. Establishes the mood:
// deep navy depths, silk-like horizontal ribbons of cool light,
// slow-rising copper embers, breathing radial glows.
//
// Tokens: --rich-black #18181B, --deep-navy #1E3A5F, --light-blue #60A5FA, --copper #B45309

function HeroCanvas({ intensity = 'full' }) {
  const ref = React.useRef(null);
  const rafRef = React.useRef(0);

  React.useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const dpr = Math.min(window.devicePixelRatio || 1, 2);

    let w = 0, h = 0;
    const resize = () => {
      const rect = canvas.getBoundingClientRect();
      w = rect.width;
      h = rect.height;
      canvas.width = w * dpr;
      canvas.height = h * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    };
    resize();
    const ro = new ResizeObserver(resize);
    ro.observe(canvas);

    // Intensity scalars
    const scale = intensity === 'off' ? 0
                : intensity === 'subtle' ? 0.5
                : 1;

    // Ribbons (silk threads of cool light, slow horizontal drift)
    const ribbonCount = Math.round(14 * scale);
    const ribbons = Array.from({ length: ribbonCount }, () => ({
      y: Math.random(),
      x: -0.3 - Math.random() * 0.5,
      len: 0.25 + Math.random() * 0.55,
      thickness: 0.6 + Math.random() * 1.6,
      speed: 0.00018 + Math.random() * 0.00038,
      hueShift: -10 + Math.random() * 20,
      opacity: 0.05 + Math.random() * 0.18,
      phase: Math.random() * Math.PI * 2,
    }));

    // Embers (slow rising copper sparks)
    const emberCount = Math.round(28 * scale);
    const embers = Array.from({ length: emberCount }, () => ({
      x: Math.random(),
      y: 1 + Math.random() * 0.2,
      r: 0.4 + Math.random() * 1.4,
      speed: 0.00012 + Math.random() * 0.0003,
      sway: 0.0006 + Math.random() * 0.001,
      phase: Math.random() * Math.PI * 2,
      maxLife: 8000 + Math.random() * 12000,
      birth: -Math.random() * 12000,
    }));

    // Breathing radial glows (the deepest layer; sets the "stage")
    const glows = [
      { x: 0.18, y: 0.35, r: 0.45, color: 'rgba(30, 58, 95, 0.55)', period: 9000, phase: 0 },
      { x: 0.82, y: 0.6, r: 0.5, color: 'rgba(96, 165, 250, 0.18)', period: 11000, phase: 1.2 },
      { x: 0.55, y: 0.85, r: 0.35, color: 'rgba(180, 83, 9, 0.14)', period: 13000, phase: 2.6 },
    ];

    let t0 = performance.now();
    let lastFrame = t0;

    const draw = (now) => {
      const t = now - t0;
      const dt = now - lastFrame;
      lastFrame = now;

      // Base wash: deep radial from upper-left, with a darker floor
      ctx.fillStyle = '#0E1A2E';
      ctx.fillRect(0, 0, w, h);

      // Underglow: faint horizon
      const horizon = ctx.createRadialGradient(w * 0.5, h * 1.05, 0, w * 0.5, h * 1.05, h * 1.2);
      horizon.addColorStop(0, 'rgba(30, 58, 95, 0.6)');
      horizon.addColorStop(1, 'rgba(20, 22, 30, 0)');
      ctx.fillStyle = horizon;
      ctx.fillRect(0, 0, w, h);

      // Stage glows (breathing)
      glows.forEach(g => {
        const breath = 0.7 + 0.3 * Math.sin((t / g.period) * Math.PI * 2 + g.phase);
        const cx = g.x * w;
        const cy = g.y * h;
        const rad = g.r * Math.max(w, h) * breath;
        const grad = ctx.createRadialGradient(cx, cy, 0, cx, cy, rad);
        grad.addColorStop(0, g.color);
        grad.addColorStop(1, 'rgba(0,0,0,0)');
        ctx.fillStyle = grad;
        ctx.beginPath();
        ctx.arc(cx, cy, rad, 0, Math.PI * 2);
        ctx.fill();
      });

      // Ribbons
      ctx.globalCompositeOperation = 'screen';
      ribbons.forEach(r => {
        r.x += r.speed * dt;
        if (r.x > 1.3) {
          r.x = -0.4 - Math.random() * 0.4;
          r.y = Math.random();
          r.len = 0.25 + Math.random() * 0.55;
          r.opacity = 0.05 + Math.random() * 0.18;
        }
        const yWave = r.y + Math.sin((t / 4000) + r.phase) * 0.012;
        const sx = r.x * w;
        const sy = yWave * h;
        const ex = (r.x + r.len) * w;
        const grad = ctx.createLinearGradient(sx, 0, ex, 0);
        const hue = 210 + r.hueShift;
        grad.addColorStop(0, `hsla(${hue}, 85%, 70%, 0)`);
        grad.addColorStop(0.5, `hsla(${hue}, 85%, 72%, ${r.opacity})`);
        grad.addColorStop(1, `hsla(${hue}, 85%, 70%, 0)`);
        ctx.fillStyle = grad;
        ctx.fillRect(sx, sy, ex - sx, r.thickness);
      });
      ctx.globalCompositeOperation = 'source-over';

      // Embers
      embers.forEach(e => {
        const life = (t + e.birth) % e.maxLife;
        const lifeFrac = life / e.maxLife;
        if (lifeFrac < 0) return;
        const yy = (e.y - lifeFrac * 1.2) * h + Math.sin((t / 1800) + e.phase) * 12;
        const xx = e.x * w + Math.sin((t / 3200) + e.phase) * 20;
        const fade = lifeFrac < 0.1 ? lifeFrac / 0.1
                   : lifeFrac > 0.7 ? 1 - (lifeFrac - 0.7) / 0.3
                   : 1;
        const alpha = 0.55 * fade;
        ctx.fillStyle = `rgba(217, 119, 6, ${alpha})`;
        ctx.beginPath();
        ctx.arc(xx, yy, e.r, 0, Math.PI * 2);
        ctx.fill();
        // hot core
        ctx.fillStyle = `rgba(252, 211, 77, ${alpha * 0.6})`;
        ctx.beginPath();
        ctx.arc(xx, yy, e.r * 0.4, 0, Math.PI * 2);
        ctx.fill();
      });

      // Soft grain (very subtle, no rAF cost — sample sparsely)
      ctx.fillStyle = 'rgba(255,255,255,0.012)';
      for (let i = 0; i < 30; i++) {
        const gx = Math.random() * w;
        const gy = Math.random() * h;
        ctx.fillRect(gx, gy, 1, 1);
      }

      // Vignette
      const vign = ctx.createRadialGradient(w/2, h/2, Math.min(w, h) * 0.4, w/2, h/2, Math.max(w, h) * 0.8);
      vign.addColorStop(0, 'rgba(0,0,0,0)');
      vign.addColorStop(1, 'rgba(0,0,0,0.65)');
      ctx.fillStyle = vign;
      ctx.fillRect(0, 0, w, h);

      rafRef.current = requestAnimationFrame(draw);
    };

    if (intensity !== 'off') {
      rafRef.current = requestAnimationFrame(draw);
    } else {
      // single static paint
      draw(t0);
      cancelAnimationFrame(rafRef.current);
    }

    return () => {
      cancelAnimationFrame(rafRef.current);
      ro.disconnect();
    };
  }, [intensity]);

  return (
    <canvas
      ref={ref}
      id="hero-canvas"
      style={{
        position: 'absolute',
        inset: 0,
        width: '100%',
        height: '100%',
        display: 'block',
      }}
    />
  );
}

Object.assign(window, { HeroCanvas });
