// ChamberCanvas — bubble-chamber-inspired particle track hero for Catálogo.
// Charged particles curve through a magnetic field, leaving glowing arc traces.
// A pool of arcs draws, holds, and fades continuously — canvas stays dense.

function WaveInterference() {
  const ref = React.useRef(null);

  React.useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    // Cap DPR at 1.5 — biggest single performance win on retina screens
    const dpr = Math.min(window.devicePixelRatio || 1, 1.5);
    let w = 0, h = 0, raf = null;
    let paused = document.hidden;
    let prevTime = null;

    const PALETTE = [
      [0,   229, 255],  // cyan
      [45,  111, 247],  // electric blue
      [107, 63,  255],  // violet
      [255, 45,  157],  // magenta
      [80,  180, 255],  // sky blue
    ];

    const POOL_SIZE  = 11;
    const TRACE_DUR  = 2400; // ms to trace the arc
    const HOLD_DUR   = 500;
    const FADE_DUR   = 1000;
    const ARC_LIFE   = TRACE_DUR + HOLD_DUR + FADE_DUR;

    let tracks = [];

    function newTrack(staggerT) {
      const col   = PALETTE[Math.floor(Math.random() * PALETTE.length)];
      const R     = Math.min(w, h) * (0.11 + Math.random() * 0.28);
      const cx    = w * (0.10 + Math.random() * 0.80);
      const cy    = h * (0.10 + Math.random() * 0.80);
      const start = Math.random() * Math.PI * 2;
      const sweep = Math.PI * (0.9 + Math.random() * 1.3); // ~0.9π to 2.2π
      const dir   = Math.random() < 0.5 ? 1 : -1;
      const lw    = 0.65 + Math.random() * 0.90;
      return { cx, cy, R, start, sweep, dir, color: col, lw, t: staggerT || 0 };
    }

    function resize() {
      const rect = canvas.getBoundingClientRect();
      w = rect.width; h = rect.height;
      canvas.width  = w * dpr;
      canvas.height = h * dpr;
      ctx.scale(dpr, dpr);
      // Re-seed the pool with staggered start times
      tracks = Array.from({ length: POOL_SIZE }, (_, i) => {
        const track = newTrack(0);
        track.t = (i / POOL_SIZE) * ARC_LIFE;
        return track;
      });
    }
    resize();
    const ro = new ResizeObserver(resize);
    ro.observe(canvas);

    // Pause when scrolled off-screen
    const observer = new IntersectionObserver(
      ([e]) => { if (!e.isIntersecting && !paused) paused = true; else if (e.isIntersecting && paused) { paused = document.hidden; if (!paused && !raf) tick(0); } },
      { threshold: 0.01 }
    );
    observer.observe(canvas);

    function checkPaused() {
      const should = document.hidden;
      if (!paused && should) paused = true;
      else if (paused && !should) { paused = false; if (!raf) tick(0); }
    }
    document.addEventListener("visibilitychange", checkPaused);

    function tick(now) {
      if (paused) { raf = null; return; }
      const dt = prevTime !== null ? Math.min(now - prevTime, 40) : 16;
      prevTime = now;

      ctx.clearRect(0, 0, w, h);

      // Background
      ctx.fillStyle = "rgba(4,6,12,1)";
      ctx.fillRect(0, 0, w, h);

      // Subtle diffuse centre glow — gives depth to the dark canvas
      const cg = ctx.createRadialGradient(w * 0.5, h * 0.5, 0, w * 0.5, h * 0.5, Math.max(w, h) * 0.65);
      cg.addColorStop(0,   "rgba(20,30,70,0.55)");
      cg.addColorStop(0.5, "rgba(8,12,30,0.35)");
      cg.addColorStop(1,   "rgba(4,6,12,0)");
      ctx.fillStyle = cg;
      ctx.fillRect(0, 0, w, h);

      // Very faint crosshair grid lines (oscilloscope nod)
      ctx.strokeStyle = "rgba(45,111,247,0.04)";
      ctx.lineWidth = 0.5;
      ctx.setLineDash([4, 16]);
      ctx.beginPath(); ctx.moveTo(w * 0.5, 0);  ctx.lineTo(w * 0.5, h); ctx.stroke();
      ctx.beginPath(); ctx.moveTo(0, h * 0.5);  ctx.lineTo(w, h * 0.5); ctx.stroke();
      ctx.setLineDash([]);

      ctx.lineCap = "round";

      // Draw & advance tracks
      tracks.forEach(tr => {
        tr.t += dt;
        if (tr.t >= ARC_LIFE) {
          // Recycle
          Object.assign(tr, newTrack(0));
          return;
        }

        // Alpha envelope
        let alpha;
        const drawFrac = Math.min(1, tr.t / TRACE_DUR);
        if (tr.t < TRACE_DUR)       alpha = 0.35 + drawFrac * 0.55;
        else if (tr.t < TRACE_DUR + HOLD_DUR) alpha = 0.90;
        else {
          const f = (tr.t - TRACE_DUR - HOLD_DUR) / FADE_DUR;
          alpha = 0.90 * (1 - f);
        }
        alpha = Math.max(0, alpha);

        const [r, g, b] = tr.color;
        const sweepNow = drawFrac * tr.sweep;
        const endAngle = tr.start + tr.dir * sweepNow;

        // Main arc
        ctx.strokeStyle = `rgba(${r},${g},${b},${(alpha * 0.60).toFixed(3)})`;
        ctx.lineWidth = tr.lw;
        ctx.beginPath();
        ctx.arc(tr.cx, tr.cy, tr.R, tr.start, endAngle, tr.dir < 0);
        ctx.stroke();

        // Brighter inner arc (core of the track)
        ctx.strokeStyle = `rgba(${Math.min(255,r+50)},${Math.min(255,g+50)},${Math.min(255,b+30)},${(alpha * 0.28).toFixed(3)})`;
        ctx.lineWidth = tr.lw * 0.35;
        ctx.beginPath();
        ctx.arc(tr.cx, tr.cy, tr.R, tr.start, endAngle, tr.dir < 0);
        ctx.stroke();

        // Glowing tip (only while drawing)
        if (drawFrac < 1 && alpha > 0.05) {
          const tx = tr.cx + tr.R * Math.cos(endAngle);
          const ty = tr.cy + tr.R * Math.sin(endAngle);
          ctx.fillStyle = `rgba(${Math.min(255,r+80)},${Math.min(255,g+80)},255,${alpha.toFixed(3)})`;
          ctx.shadowColor = `rgba(${r},${g},${b},0.8)`;
          ctx.shadowBlur = 10;
          ctx.beginPath();
          ctx.arc(tx, ty, 2.8, 0, Math.PI * 2);
          ctx.fill();
          ctx.shadowBlur = 0;
        }
      });

      raf = requestAnimationFrame(tick);
    }
    tick(0);

    return () => {
      if (raf) cancelAnimationFrame(raf);
      ro.disconnect();
      observer.disconnect();
      document.removeEventListener("visibilitychange", checkPaused);
    };
  }, []);

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

window.WaveInterference = WaveInterference;
