/* global React, window, requestAnimationFrame, cancelAnimationFrame */
const { useRef: useRefCD, useEffect: useEffectCD } = React;

/* Grade de pontos sobre o ink que reage ao mouse: os pontos perto do cursor
   crescem, clareiam e se afastam levemente. Canvas vanilla, leve. */
function ContactDots({ tone }) {
  const ref = useRefCD(null);

  useEffectCD(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const rgb = tone === 'ink' ? '20,20,20' : '246,244,239';
    const base = tone === 'ink' ? 0.28 : 0.14;
    const gain = tone === 'ink' ? 0.6 : 0.74;
    let W = 0, H = 0, raf = 0;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    const target = { x: -9999, y: -9999 };
    const mouse = { x: -9999, y: -9999 };

    const resize = () => {
      const r = canvas.getBoundingClientRect();
      W = r.width; H = r.height;
      canvas.width = Math.round(W * dpr);
      canvas.height = Math.round(H * dpr);
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    };

    const draw = () => {
      ctx.clearRect(0, 0, W, H);
      mouse.x += (target.x - mouse.x) * 0.16;
      mouse.y += (target.y - mouse.y) * 0.16;
      const N = 13;
      const step = Math.min(W, H) / N;
      if (step > 0) {
        const cols = Math.max(1, Math.floor(W / step));
        const rows = Math.max(1, Math.floor(H / step));
        const offx = (W - (cols - 1) * step) / 2;
        const offy = (H - (rows - 1) * step) / 2;
        const R = Math.max(110, step * 4.5);
        for (let j = 0; j < rows; j++) {
          for (let i = 0; i < cols; i++) {
            const x = offx + i * step;
            const y = offy + j * step;
            const dx = x - mouse.x, dy = y - mouse.y;
            const d = Math.sqrt(dx * dx + dy * dy);
            let g = 0, push = 0;
            if (d < R) { const t = 1 - d / R; g = t * t; push = g * 16; }
            const ang = Math.atan2(dy, dx);
            const px = x + Math.cos(ang) * push;
            const py = y + Math.sin(ang) * push;
            ctx.beginPath();
            ctx.arc(px, py, 1.2 + g * 2.6, 0, 6.2831853);
            ctx.fillStyle = 'rgba(' + rgb + ',' + (base + g * gain) + ')';
            ctx.fill();
          }
        }
      }
      raf = requestAnimationFrame(draw);
    };

    const onMove = (e) => {
      const r = canvas.getBoundingClientRect();
      target.x = e.clientX - r.left;
      target.y = e.clientY - r.top;
    };
    const onLeave = () => { target.x = -9999; target.y = -9999; };

    resize();
    raf = requestAnimationFrame(draw);
    window.addEventListener('mousemove', onMove);
    window.addEventListener('blur', onLeave);
    window.addEventListener('resize', resize);
    let ro = null;
    if ('ResizeObserver' in window) { ro = new ResizeObserver(resize); ro.observe(canvas); }
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('blur', onLeave);
      window.removeEventListener('resize', resize);
      if (ro) ro.disconnect();
    };
  }, [tone]);

  return <canvas ref={ref} className="contact-dots" aria-hidden="true" />;
}

window.ContactDots = ContactDots;
