/* ============================================================
   AR — MouseField.jsx
   Campo de partículas ciano/azul que reage ao cursor
   (inspiração Antigravity). Leve, no fundo, sem competir com
   texto/botões. A REAÇÃO AO MOUSE funciona em qualquer desktop
   com ponteiro fino (mover o mouse é ação do usuário). A deriva
   automática/cintilação respeita "reduzir movimento". Em
   touch/telas pequenas, desenha um campo estático.
   Renderiza um canvas absoluto — colocar em pai position:relative.
   ============================================================ */

const MouseField = ({ density = 1 }) => {
  const canvasRef = React.useRef(null);

  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    if (window.innerWidth < 860) return; // pula em telas pequenas (perf + foco)

    const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const fine = window.matchMedia('(pointer: fine)').matches;
    const ambient = !reduce;        // deriva/cintilação automática
    const animate = fine || ambient; // roda o loop se há mouse-fino OU movimento ambiente

    const ctx = canvas.getContext('2d');
    let w = 0, h = 0, dpr = Math.min(window.devicePixelRatio || 1, 2);
    let particles = [];
    let raf = 0;
    const mouse = { x: -9999, y: -9999, tx: -9999, ty: -9999, active: false };

    const palette = [
      'rgba(0,212,255,',  // ciano
      'rgba(61,139,255,', // azul
      'rgba(0,94,255,',   // azul profundo
      'rgba(125,176,255,',// azul claro
    ];

    const resize = () => {
      const parent = canvas.parentElement;
      w = parent.clientWidth; h = parent.clientHeight;
      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);
      build();
      if (!animate) drawStatic();
    };

    const build = () => {
      const count = Math.round((w * h) / 14000 * density);
      particles = [];
      for (let i = 0; i < count; i++) {
        const ang = Math.random() * Math.PI * 2;
        particles.push({
          x: Math.random() * w,
          y: Math.random() * h,
          len: 4 + Math.random() * 7,
          rot: ang,
          vx: (Math.random() - 0.5) * 0.13,
          vy: (Math.random() - 0.5) * 0.13,
          baseA: 0.09 + Math.random() * 0.15,
          a: 0,
          color: palette[(Math.random() * palette.length) | 0],
          tw: Math.random() * Math.PI * 2,
        });
      }
    };

    const drawDash = (p, a, rot, extra) => {
      const hx = Math.cos(rot) * p.len * 0.5, hy = Math.sin(rot) * p.len * 0.5;
      ctx.strokeStyle = p.color + a.toFixed(3) + ')';
      ctx.lineWidth = 1.2 + extra * 1.1;
      ctx.beginPath();
      ctx.moveTo(p.x - hx, p.y - hy);
      ctx.lineTo(p.x + hx, p.y + hy);
      ctx.stroke();
    };

    const drawStatic = () => {
      ctx.clearRect(0, 0, w, h);
      ctx.lineCap = 'round';
      for (const p of particles) drawDash(p, p.baseA, p.rot, 0);
    };

    const onMove = (e) => {
      const r = canvas.getBoundingClientRect();
      const x = e.clientX - r.left, y = e.clientY - r.top;
      // só ativa quando o cursor está sobre a área do hero
      if (x < -40 || y < -40 || x > w + 40 || y > h + 40) { mouse.active = false; return; }
      mouse.tx = x; mouse.ty = y; mouse.active = true;
      if (mouse.x < -1000) { mouse.x = x; mouse.y = y; }
    };
    const onLeave = () => { mouse.active = false; };

    const R = 165; // raio de influência (maior → efeito mais perceptível)
    const tick = () => {
      ctx.clearRect(0, 0, w, h);
      ctx.lineCap = 'round';

      // suaviza o seguimento do cursor
      mouse.x += (mouse.tx - mouse.x) * 0.18;
      mouse.y += (mouse.ty - mouse.y) * 0.18;

      // aura suave seguindo o cursor (deixa o efeito inconfundível)
      if (mouse.active) {
        const g = ctx.createRadialGradient(mouse.x, mouse.y, 0, mouse.x, mouse.y, R);
        g.addColorStop(0, 'rgba(0,212,255,0.10)');
        g.addColorStop(0.6, 'rgba(0,94,255,0.045)');
        g.addColorStop(1, 'rgba(0,94,255,0)');
        ctx.fillStyle = g;
        ctx.beginPath();
        ctx.arc(mouse.x, mouse.y, R, 0, Math.PI * 2);
        ctx.fill();
      }

      for (const p of particles) {
        if (ambient) {
          p.x += p.vx; p.y += p.vy;
          if (p.x < -10) p.x = w + 10; if (p.x > w + 10) p.x = -10;
          if (p.y < -10) p.y = h + 10; if (p.y > h + 10) p.y = -10;
          p.tw += 0.018;
        }
        let a = p.baseA + (ambient ? Math.sin(p.tw) * 0.04 : 0);
        let extra = 0;
        let rot = p.rot;

        if (mouse.active) {
          const dx = p.x - mouse.x, dy = p.y - mouse.y;
          const dist = Math.hypot(dx, dy);
          if (dist < R) {
            const f = 1 - dist / R;
            extra = f * 0.6;                    // brilho perto do cursor
            const push = f * f * 1.4;           // repulsão gentil
            p.x += (dx / (dist || 1)) * push;
            p.y += (dy / (dist || 1)) * push;
            rot = Math.atan2(dy, dx) * 0.4 + p.rot * 0.6;
          }
        }
        a = Math.min(0.85, a + extra);
        p.a = a;

        drawDash(p, a, rot, extra);

        if (extra > 0.16) {
          ctx.fillStyle = p.color + (extra * 0.5).toFixed(3) + ')';
          ctx.beginPath();
          ctx.arc(p.x, p.y, 1.3 + extra * 2.4, 0, Math.PI * 2);
          ctx.fill();
        }
      }

      // fios conectivos perto do cursor
      if (mouse.active) {
        for (let i = 0; i < particles.length; i++) {
          const p = particles[i];
          const dm = Math.hypot(p.x - mouse.x, p.y - mouse.y);
          if (dm > R) continue;
          for (let j = i + 1; j < particles.length; j++) {
            const q = particles[j];
            const d = Math.hypot(p.x - q.x, p.y - q.y);
            if (d < 70) {
              const dq = Math.hypot(q.x - mouse.x, q.y - mouse.y);
              if (dq > R) continue;
              const o = (1 - d / 70) * (1 - dm / R) * 0.3;
              ctx.strokeStyle = 'rgba(0,212,255,' + o.toFixed(3) + ')';
              ctx.lineWidth = 0.8;
              ctx.beginPath(); ctx.moveTo(p.x, p.y); ctx.lineTo(q.x, q.y); ctx.stroke();
            }
          }
        }
      }

      raf = requestAnimationFrame(tick);
    };

    resize();
    window.addEventListener('resize', resize);

    if (animate) {
      raf = requestAnimationFrame(tick);
      if (fine) {
        window.addEventListener('mousemove', onMove, { passive: true });
        document.addEventListener('mouseleave', onLeave);
      }
    }

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('resize', resize);
      window.removeEventListener('mousemove', onMove);
      document.removeEventListener('mouseleave', onLeave);
    };
  }, [density]);

  // máscara: afina partículas sobre a coluna de texto (inferior-esquerda)
  const mask = 'radial-gradient(120% 130% at 72% 26%, #000 38%, rgba(0,0,0,0.5) 70%, transparent 100%)';

  return (
    <canvas ref={canvasRef} aria-hidden="true" style={{
      position: 'absolute', inset: 0, width: '100%', height: '100%',
      pointerEvents: 'none', zIndex: 0, opacity: 0.9,
      WebkitMaskImage: mask, maskImage: mask,
    }} />
  );
};

window.MouseField = MouseField;
