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

const TRAIL_COUNT = 14;

/**
 * AnsarTech custom cursor: dot + ring + fading chain-trail + optional mono label.
 * - Dot tracks 1:1
 * - Ring lerps softly toward cursor
 * - Trail is a chain of dots, each lerping toward the dot in front of it
 */
function Cursor() {
  const dotRef = useRef(null);
  const ringRef = useRef(null);
  const labelRef = useRef(null);
  const trailRefs = useRef([]);
  const trailPos = useRef([]);

  useEffect(() => {
    // Touch device — bail
    if (window.matchMedia("(hover: none) and (pointer: coarse)").matches) return;

    const dot = dotRef.current;
    const ring = ringRef.current;
    const label = labelRef.current;

    const target = { x: window.innerWidth / 2, y: window.innerHeight / 2 };
    const pos = { x: target.x, y: target.y };

    // Initialize trail positions to current cursor location
    trailPos.current = Array.from({ length: TRAIL_COUNT }, () => ({ x: target.x, y: target.y }));

    let raf = 0;
    let isInteractive = false;

    function onMove(e) {
      target.x = e.clientX;
      target.y = e.clientY;
      dot.style.transform = `translate3d(${e.clientX}px, ${e.clientY}px, 0) translate(-50%, -50%)`;
      label.style.transform = `translate3d(${e.clientX}px, ${e.clientY + 32}px, 0) translate(-50%, -50%)`;

      const el = document.elementFromPoint(e.clientX, e.clientY);
      const interactive = el && el.closest('a, button, [data-clickable], input, textarea, .at-build-row, .at-faq-row, .at-case-featured, .at-case-mini, .at-int-chip, .at-testi-card');
      isInteractive = !!interactive;

      // Detect surface tone under cursor so we can invert colors on light sections
      const onLight = el && el.closest('.at-cases, .at-process, .at-testi, .at-final, .pg-section--light, .cs-body, .cs-testi, .embed-card, .ct-min-card');
      document.body.classList.toggle('cursor-on-light', !!onLight);
      document.body.classList.toggle('cursor-on-red', false);

      if (interactive) {
        const isText = interactive.matches('input, textarea');
        ring.classList.toggle('is-text', isText);
        ring.classList.toggle('is-hover', !isText);
        dot.classList.toggle('is-hover', !isText);

        const node = el.closest('[data-cursor-label]');
        if (node) {
          label.textContent = node.getAttribute('data-cursor-label');
          label.classList.add('is-visible');
        } else {
          label.classList.remove('is-visible');
        }
      } else {
        ring.classList.remove('is-hover', 'is-text');
        dot.classList.remove('is-hover');
        label.classList.remove('is-visible');
      }

      // Toggle trail color
      trailRefs.current.forEach((tEl) => {
        if (!tEl) return;
        tEl.classList.toggle('is-hover', isInteractive);
      });
    }

    function tick() {
      // Ring softly lerps toward cursor
      pos.x += (target.x - pos.x) * 0.18;
      pos.y += (target.y - pos.y) * 0.18;
      ring.style.transform = `translate3d(${pos.x}px, ${pos.y}px, 0) translate(-50%, -50%)`;

      // Trail chain — each segment chases the one in front (target → trail[0] → trail[1] → ...)
      const tp = trailPos.current;
      for (let i = 0; i < TRAIL_COUNT; i++) {
        const prev = i === 0 ? target : tp[i - 1];
        // Slightly looser lerp the further down the chain — gives the tail its sweep
        const factor = Math.max(0.18, 0.42 - i * 0.012);
        tp[i].x += (prev.x - tp[i].x) * factor;
        tp[i].y += (prev.y - tp[i].y) * factor;
        const el = trailRefs.current[i];
        if (el) el.style.transform = `translate3d(${tp[i].x}px, ${tp[i].y}px, 0) translate(-50%, -50%)`;
      }
      raf = requestAnimationFrame(tick);
    }

    window.addEventListener('mousemove', onMove);
    raf = requestAnimationFrame(tick);

    window.addEventListener('mouseleave', () => {
      dot.style.opacity = '0';
      ring.style.opacity = '0';
      trailRefs.current.forEach((el) => { if (el) el.style.opacity = '0'; });
    });
    window.addEventListener('mouseenter', () => {
      dot.style.opacity = '1';
      ring.style.opacity = '1';
      trailRefs.current.forEach((el, i) => {
        if (el) el.style.opacity = '';
      });
    });

    return () => {
      window.removeEventListener('mousemove', onMove);
      cancelAnimationFrame(raf);
    };
  }, []);

  // Build the trail dots — each gets its own size + opacity from its index
  const trailDots = [];
  for (let i = 0; i < TRAIL_COUNT; i++) {
    const t = i / (TRAIL_COUNT - 1); // 0 → 1
    const size = 6 - t * 4.5;        // 6px head → ~1.5px tail
    const op = 0.55 * (1 - t);       // 0.55 → 0
    trailDots.push(
      <div
        key={i}
        ref={(el) => (trailRefs.current[i] = el)}
        className="at-cursor-trail"
        style={{
          width:  `${size}px`,
          height: `${size}px`,
          opacity: op,
        }}
        aria-hidden="true"
      />
    );
  }

  return (
    <>
      {trailDots}
      <div ref={ringRef} className="at-cursor-ring" aria-hidden="true"></div>
      <div ref={dotRef} className="at-cursor-dot" aria-hidden="true"></div>
      <div ref={labelRef} className="at-cursor-label" aria-hidden="true"></div>
    </>
  );
}

window.Cursor = Cursor;
