// Ambient canvas — drifting translucent green lines
// Noise-field driven bezier curves, slow & calm, zero visual noise.

function AmbientCanvas() {
  const canvasRef = React.useRef(null);
  const rafRef = React.useRef(0);
  const stateRef = React.useRef({ t: 0, lines: [], dpr: 1, w: 0, h: 0, paused: false });

  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d", { alpha: true });

    // Respect reduced motion.
    const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduce) return;

    const isMobile = window.innerWidth < 768;
    const lineCount = isMobile ? 7 : 14;

    const resize = () => {
      const dpr = Math.min(window.devicePixelRatio || 1, 2);
      const w = window.innerWidth;
      const h = window.innerHeight;
      canvas.width = w * dpr;
      canvas.height = h * dpr;
      canvas.style.width = w + "px";
      canvas.style.height = h + "px";
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      stateRef.current.w = w;
      stateRef.current.h = h;
      stateRef.current.dpr = dpr;
    };
    resize();
    window.addEventListener("resize", resize);

    // Build lines. Each has: base y, amplitude, freq, phase, speed.
    const lines = [];
    for (let i = 0; i < lineCount; i++) {
      lines.push({
        y: (i + 0.5) / lineCount,            // vertical anchor (0..1)
        amp: 30 + Math.random() * 90,        // amplitude in px
        freq: 0.0015 + Math.random() * 0.002,
        phase: Math.random() * Math.PI * 2,
        speed: 0.00012 + Math.random() * 0.00025,
        thick: 0.7 + Math.random() * 0.4,
        alpha: 0.04 + Math.random() * 0.05,
      });
    }
    stateRef.current.lines = lines;

    // Pause when tab hidden
    const onVis = () => {
      stateRef.current.paused = document.hidden;
    };
    document.addEventListener("visibilitychange", onVis);

    const tick = (ts) => {
      if (stateRef.current.paused) {
        rafRef.current = requestAnimationFrame(tick);
        return;
      }
      const { w, h } = stateRef.current;
      ctx.clearRect(0, 0, w, h);

      for (let i = 0; i < lines.length; i++) {
        const L = lines[i];
        L.phase += L.speed * 16;

        ctx.beginPath();
        const anchorY = L.y * h;

        const steps = 60;
        for (let s = 0; s <= steps; s++) {
          const x = (s / steps) * w;
          const nx = x * L.freq + L.phase;
          const ny = Math.sin(nx) * L.amp
                   + Math.sin(nx * 0.45 + L.phase * 0.6) * (L.amp * 0.35);
          const y = anchorY + ny;
          if (s === 0) ctx.moveTo(x, y);
          else ctx.lineTo(x, y);
        }

        ctx.strokeStyle = `rgba(168, 242, 108, ${L.alpha})`;
        ctx.lineWidth = L.thick;
        ctx.lineCap = "round";
        ctx.stroke();
      }

      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);

    return () => {
      cancelAnimationFrame(rafRef.current);
      window.removeEventListener("resize", resize);
      document.removeEventListener("visibilitychange", onVis);
    };
  }, []);

  return <canvas ref={canvasRef} id="ambient" aria-hidden="true" />;
}

window.AmbientCanvas = AmbientCanvas;
