/* Site-wide micro-interaction layer: custom cursor, scroll progress, magnetic buttons,
   card tilt, ripple clicks, count-up numbers. All opt out under prefers-reduced-motion. */
const NO_MOTION = () => typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

function CursorHalo() {
  const dot = React.useRef(null), ring = React.useRef(null);
  React.useEffect(() => {
    if (NO_MOTION() || window.matchMedia('(pointer: coarse)').matches) return;
    let x = innerWidth / 2, y = innerHeight / 2, rx = x, ry = y, raf = 0;
    const move = (e) => { x = e.clientX; y = e.clientY; };
    const over = (e) => {
      const hit = e.target.closest('a,button,[data-cursor="grow"]');
      if (ring.current) ring.current.toggleAttribute('data-grow', !!hit);
    };
    const loop = () => {
      raf = requestAnimationFrame(loop);
      rx += (x - rx) * 0.16; ry += (y - ry) * 0.16;
      if (dot.current) dot.current.style.transform = 'translate3d(' + x + 'px,' + y + 'px,0)';
      if (ring.current) ring.current.style.transform = 'translate3d(' + rx + 'px,' + ry + 'px,0)';
    };
    loop();
    window.addEventListener('pointermove', move, { passive: true });
    window.addEventListener('pointerover', over, { passive: true });
    document.documentElement.setAttribute('data-cursor-on', '');
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('pointermove', move);
      window.removeEventListener('pointerover', over);
      document.documentElement.removeAttribute('data-cursor-on');
    };
  }, []);
  return (<>
    <span className="zx-cursor__dot" ref={dot} aria-hidden="true" />
    <span className="zx-cursor__ring" ref={ring} aria-hidden="true" />
  </>);
}

function ScrollProgress() {
  const bar = React.useRef(null);
  React.useEffect(() => {
    const on = () => {
      const max = document.documentElement.scrollHeight - innerHeight;
      if (bar.current) bar.current.style.transform = 'scaleX(' + (max > 0 ? scrollY / max : 0) + ')';
    };
    on();
    window.addEventListener('scroll', on, { passive: true });
    window.addEventListener('resize', on);
    return () => { window.removeEventListener('scroll', on); window.removeEventListener('resize', on); };
  }, []);
  return <span className="zx-progress" ref={bar} aria-hidden="true" />;
}

/* magnetic pull + ripple on every button, tilt on [data-tilt] — delegated, so it
   also covers nodes rendered later */
function useSiteInteractions() {
  React.useEffect(() => {
    if (NO_MOTION()) return;
    const onMove = (e) => {
      const mag = e.target.closest('[data-magnetic]');
      if (mag) {
        const r = mag.getBoundingClientRect();
        mag.style.transform = 'translate(' + (e.clientX - r.left - r.width / 2) * 0.14 + 'px,' + (e.clientY - r.top - r.height / 2) * 0.2 + 'px)';
      }
      const tilt = e.target.closest('[data-tilt]');
      if (tilt) {
        const r = tilt.getBoundingClientRect();
        const nx = (e.clientX - r.left) / r.width - 0.5, ny = (e.clientY - r.top) / r.height - 0.5;
        tilt.style.transform = 'perspective(900px) rotateY(' + nx * 7 + 'deg) rotateX(' + -ny * 7 + 'deg) translateZ(0)';
        tilt.style.setProperty('--mx', (nx * 100 + 50) + '%');
        tilt.style.setProperty('--my', (ny * 100 + 50) + '%');
      }
    };
    const onOut = (e) => {
      const n = e.target.closest('[data-magnetic],[data-tilt]');
      if (n) n.style.transform = '';
    };
    const onDown = (e) => {
      const b = e.target.closest('button,.zx-btn,[data-ripple]');
      if (!b) return;
      const r = b.getBoundingClientRect();
      const s = document.createElement('span');
      s.className = 'zx-ripple';
      s.style.left = (e.clientX - r.left) + 'px';
      s.style.top = (e.clientY - r.top) + 'px';
      if (getComputedStyle(b).position === 'static') b.style.position = 'relative';
      b.appendChild(s);
      setTimeout(() => s.remove(), 620);
    };
    document.addEventListener('pointermove', onMove);
    document.addEventListener('pointerout', onOut);
    document.addEventListener('pointerdown', onDown);
    return () => {
      document.removeEventListener('pointermove', onMove);
      document.removeEventListener('pointerout', onOut);
      document.removeEventListener('pointerdown', onDown);
    };
  }, []);
}

function CountUp({ value, suffix = '', prefix = '', duration = 1400 }) {
  const [n, setN] = React.useState(0);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (NO_MOTION()) { setN(value); return; }
    const io = new IntersectionObserver(([e]) => {
      if (!e.isIntersecting) return;
      io.disconnect();
      const t0 = performance.now();
      const step = (t) => {
        const p = Math.min((t - t0) / duration, 1);
        setN(Math.round(value * (1 - Math.pow(1 - p, 3))));
        if (p < 1) requestAnimationFrame(step);
      };
      requestAnimationFrame(step);
    }, { threshold: 0.4 });
    if (ref.current) io.observe(ref.current);
    return () => io.disconnect();
  }, [value, duration]);
  return <span ref={ref}>{prefix}{n.toLocaleString('en-IN')}{suffix}</span>;
}
Object.assign(window, { CursorHalo, ScrollProgress, useSiteInteractions, CountUp });
