/* global React, window */
const { useEffect, useRef } = React;

// Fixed full-viewport canvas. Draws dots on light-bg sections only.
// Dots near cursor are pushed outward + brighten + grow.
const DotGrid = () => {
  const canvasRef = useRef(null);
  const mouseRef = useRef({ x: -9999, y: -9999, active: false });
  const rafRef = useRef(null);
  const lightZonesRef = useRef([]);

  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    let dpr = Math.max(1, window.devicePixelRatio || 1);
    let w = 0, h = 0;

    const SPACING = 28;
    const BASE_R = 1.1;
    const HOVER_RADIUS = 140;
    const MAX_DISPLACE = 8;
    const MAX_SCALE = 3.2;

    // Selectors for sections that have light/bone background — these are where the dots should show.
    // Everything else (painpoint, gemstone, hero-dark, footer) stays clean.
    const LIGHT_SELECTOR = [
      "#faq",
    ].join(",");

    const measureLightZones = () => {
      const nodes = document.querySelectorAll(LIGHT_SELECTOR);
      const zones = [];
      nodes.forEach((n) => {
        const r = n.getBoundingClientRect();
        // store as document-space (pageY)
        zones.push({
          top: r.top + window.scrollY,
          bottom: r.bottom + window.scrollY,
          left: r.left + window.scrollX,
          right: r.right + window.scrollX,
        });
      });
      // Also include the hero split area if it's the light variant
      const hero = document.querySelector(".hero-wrap:not(.hero-dark)");
      if (hero) {
        const r = hero.getBoundingClientRect();
        zones.push({
          top: r.top + window.scrollY,
          bottom: r.bottom + window.scrollY,
          left: r.left + window.scrollX,
          right: r.right + window.scrollX,
        });
      }
      lightZonesRef.current = zones;
    };

    const resize = () => {
      dpr = Math.max(1, window.devicePixelRatio || 1);
      w = window.innerWidth;
      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);
      measureLightZones();
    };

    const onMove = (e) => {
      mouseRef.current.x = e.clientX;
      mouseRef.current.y = e.clientY;
      mouseRef.current.active = true;
    };
    const onLeave = () => { mouseRef.current.active = false; };
    const onScroll = () => { measureLightZones(); };

    const inLightZone = (docX, docY) => {
      const z = lightZonesRef.current;
      for (let i = 0; i < z.length; i++) {
        const r = z[i];
        if (docY >= r.top && docY <= r.bottom && docX >= r.left && docX <= r.right) return true;
      }
      return false;
    };

    const draw = () => {
      ctx.clearRect(0, 0, w, h);
      const mx = mouseRef.current.x;
      const my = mouseRef.current.y;
      const active = mouseRef.current.active;
      const scrollY = window.scrollY;
      const scrollX = window.scrollX;

      // Offset grid so it looks stable during scroll
      const startX = -((scrollX) % SPACING);
      const startY = -((scrollY) % SPACING);

      const hR = HOVER_RADIUS;
      const hR2 = hR * hR;

      for (let y = startY; y < h + SPACING; y += SPACING) {
        for (let x = startX; x < w + SPACING; x += SPACING) {
          const docX = x + scrollX;
          const docY = y + scrollY;
          if (!inLightZone(docX, docY)) continue;

          let px = x, py = y;
          let r = BASE_R;
          let alpha = 0.22;

          if (active) {
            const dx = x - mx;
            const dy = y - my;
            const d2 = dx * dx + dy * dy;
            if (d2 < hR2) {
              const d = Math.sqrt(d2) || 0.001;
              const t = 1 - d / hR; // 0..1
              const push = MAX_DISPLACE * t;
              px += (dx / d) * push;
              py += (dy / d) * push;
              r = BASE_R + (MAX_SCALE - BASE_R) * t;
              alpha = 0.22 + 0.65 * t;
            }
          }

          ctx.beginPath();
          ctx.arc(px, py, r, 0, Math.PI * 2);
          // dot color for light bg
          ctx.fillStyle = `rgba(22,22,22,${alpha})`;
          ctx.fill();
        }
      }

      rafRef.current = requestAnimationFrame(draw);
    };

    resize();
    window.addEventListener("resize", resize);
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseleave", onLeave);
    // remeasure after fonts/layout settle
    const t1 = setTimeout(measureLightZones, 400);
    const t2 = setTimeout(measureLightZones, 1200);
    rafRef.current = requestAnimationFrame(draw);

    return () => {
      cancelAnimationFrame(rafRef.current);
      window.removeEventListener("resize", resize);
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("mousemove", onMove);
      window.removeEventListener("mouseleave", onLeave);
      clearTimeout(t1); clearTimeout(t2);
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      aria-hidden="true"
      style={{
        position: "fixed",
        inset: 0,
        width: "100%",
        height: "100%",
        pointerEvents: "none",
        zIndex: 0,
      }}
    />
  );
};

window.DotGrid = DotGrid;
