/* Animated particle field — connected dots with gentle drift.
 * Uses canvas for perf. Tuned for amber/gold theme over light or dark bg.
 */
const ParticleField = ({ density = 1, color = "amber", className = "", parallax = 0 }) => {
  const canvasRef = React.useRef(null);
  const stateRef = React.useRef({ pts: [], w: 0, h: 0, raf: 0, mx: 0, my: 0, sy: 0 });

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

    const resize = () => {
      const rect = canvas.getBoundingClientRect();
      stateRef.current.w = rect.width;
      stateRef.current.h = rect.height;
      canvas.width = rect.width * dpr;
      canvas.height = rect.height * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      seed();
    };

    const seed = () => {
      const { w, h } = stateRef.current;
      const count = Math.round((w * h) / 14000 * density);
      stateRef.current.pts = Array.from({ length: count }, () => ({
        x: Math.random() * w,
        y: Math.random() * h,
        vx: (Math.random() - 0.5) * 0.18,
        vy: (Math.random() - 0.5) * 0.18,
        r: Math.random() * 1.4 + 0.4,
        o: Math.random() * 0.6 + 0.3,
      }));
    };

    const colors = {
      amber: { dot: "255, 184, 77", line: "245, 166, 35" },
      ink:   { dot: "11, 11, 12",  line: "11, 11, 12" },
    };
    const C = colors[color] || colors.amber;

    const tick = () => {
      const s = stateRef.current;
      ctx.clearRect(0, 0, s.w, s.h);

      // mouse interaction radius
      const mx = s.mx, my = s.my;
      const linkDist = 130;

      for (let i = 0; i < s.pts.length; i++) {
        const p = s.pts[i];
        p.x += p.vx;
        p.y += p.vy;
        if (p.x < -10) p.x = s.w + 10;
        if (p.x > s.w + 10) p.x = -10;
        if (p.y < -10) p.y = s.h + 10;
        if (p.y > s.h + 10) p.y = -10;

        // mouse repel
        if (mx && my) {
          const dx = p.x - mx, dy = p.y - my;
          const d2 = dx * dx + dy * dy;
          if (d2 < 9000) {
            const f = (9000 - d2) / 9000 * 0.6;
            p.x += (dx / Math.sqrt(d2 || 1)) * f;
            p.y += (dy / Math.sqrt(d2 || 1)) * f;
          }
        }

        // dot
        ctx.beginPath();
        ctx.fillStyle = `rgba(${C.dot}, ${p.o})`;
        ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
        ctx.fill();

        // links to nearby
        for (let j = i + 1; j < s.pts.length; j++) {
          const q = s.pts[j];
          const dx = p.x - q.x, dy = p.y - q.y;
          const d2 = dx * dx + dy * dy;
          if (d2 < linkDist * linkDist) {
            const a = (1 - d2 / (linkDist * linkDist)) * 0.35;
            ctx.strokeStyle = `rgba(${C.line}, ${a})`;
            ctx.lineWidth = 0.6;
            ctx.beginPath();
            ctx.moveTo(p.x, p.y);
            ctx.lineTo(q.x, q.y);
            ctx.stroke();
          }
        }
      }

      s.raf = requestAnimationFrame(tick);
    };

    const onMove = (e) => {
      const r = canvas.getBoundingClientRect();
      stateRef.current.mx = e.clientX - r.left;
      stateRef.current.my = e.clientY - r.top;
    };
    const onLeave = () => { stateRef.current.mx = 0; stateRef.current.my = 0; };

    resize();
    window.addEventListener("resize", resize);
    canvas.addEventListener("mousemove", onMove);
    canvas.addEventListener("mouseleave", onLeave);
    stateRef.current.raf = requestAnimationFrame(tick);

    return () => {
      cancelAnimationFrame(stateRef.current.raf);
      window.removeEventListener("resize", resize);
      canvas.removeEventListener("mousemove", onMove);
      canvas.removeEventListener("mouseleave", onLeave);
    };
  }, [density, color]);

  return (
    <canvas
      ref={canvasRef}
      className={`particle-field ${className}`}
      aria-hidden="true"
      style={{ width: "100%", height: "100%", display: "block", pointerEvents: "auto" }}
    />
  );
};

window.ParticleField = ParticleField;
