// 85runtime — Hero animated background
// Geometric shapes that subtly drift, scale, and connect

const HeroCanvas = () => {
  const canvasRef = React.useRef(null);

  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let raf;
    let w, h, dpr;

    const resize = () => {
      dpr = Math.min(window.devicePixelRatio || 1, 2);
      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();
    window.addEventListener('resize', resize);

    // Read accent from CSS
    const getAccent = () => getComputedStyle(document.documentElement).getPropertyValue('--accent').trim() || '#2347ff';
    const getInk = () => getComputedStyle(document.documentElement).getPropertyValue('--ink').trim() || '#0a0a0a';

    const N = 28;
    const nodes = Array.from({ length: N }).map((_, i) => ({
      x: Math.random(),
      y: Math.random(),
      vx: (Math.random() - 0.5) * 0.0006,
      vy: (Math.random() - 0.5) * 0.0006,
      r: 1.5 + Math.random() * 2.5,
      phase: Math.random() * Math.PI * 2,
    }));

    let t0 = performance.now();
    const tick = (t) => {
      const dt = (t - t0) / 1000; t0 = t;
      ctx.clearRect(0, 0, w, h);

      const accent = getAccent();
      const ink = getInk();

      // Update nodes
      for (const n of nodes) {
        n.x += n.vx * dt * 60;
        n.y += n.vy * dt * 60;
        if (n.x < 0 || n.x > 1) n.vx *= -1;
        if (n.y < 0 || n.y > 1) n.vy *= -1;
        n.phase += dt * 0.6;
      }

      // Draw connecting lines
      for (let i = 0; i < N; i++) {
        for (let j = i + 1; j < N; j++) {
          const a = nodes[i], b = nodes[j];
          const dx = (a.x - b.x) * w;
          const dy = (a.y - b.y) * h;
          const d = Math.sqrt(dx * dx + dy * dy);
          const max = 220;
          if (d < max) {
            const op = (1 - d / max) * 0.18;
            ctx.strokeStyle = ink;
            ctx.globalAlpha = op;
            ctx.lineWidth = 0.6;
            ctx.beginPath();
            ctx.moveTo(a.x * w, a.y * h);
            ctx.lineTo(b.x * w, b.y * h);
            ctx.stroke();
          }
        }
      }

      // Draw nodes
      ctx.globalAlpha = 1;
      for (const n of nodes) {
        const x = n.x * w, y = n.y * h;
        const pulse = 0.8 + Math.sin(n.phase) * 0.3;
        ctx.fillStyle = ink;
        ctx.beginPath();
        ctx.arc(x, y, n.r * pulse, 0, Math.PI * 2);
        ctx.fill();
      }

      // Big drifting square
      const sqT = (t / 8000) % 1;
      const sqX = w * 0.15 + Math.sin(t / 6000) * 40;
      const sqY = h * 0.5 + Math.cos(t / 7000) * 60;
      const sqSize = 240 + Math.sin(t / 4000) * 30;
      ctx.save();
      ctx.translate(sqX, sqY);
      ctx.rotate(t / 18000);
      ctx.strokeStyle = accent;
      ctx.globalAlpha = 0.5;
      ctx.lineWidth = 1.2;
      ctx.strokeRect(-sqSize / 2, -sqSize / 2, sqSize, sqSize);
      ctx.globalAlpha = 0.18;
      ctx.strokeRect(-sqSize / 2 - 14, -sqSize / 2 - 14, sqSize + 28, sqSize + 28);
      ctx.restore();

      // Big circle
      const cX = w * 0.82 + Math.cos(t / 5500) * 30;
      const cY = h * 0.4 + Math.sin(t / 6500) * 50;
      const cR = 180 + Math.sin(t / 3500) * 20;
      ctx.strokeStyle = ink;
      ctx.globalAlpha = 0.18;
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.arc(cX, cY, cR, 0, Math.PI * 2);
      ctx.stroke();
      ctx.globalAlpha = 0.08;
      ctx.beginPath();
      ctx.arc(cX, cY, cR + 24, 0, Math.PI * 2);
      ctx.stroke();

      ctx.globalAlpha = 1;
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);

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

  return <canvas ref={canvasRef} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }} />;
};

window.HeroCanvas = HeroCanvas;
