/* global React */

const { useEffect, useRef } = React;

// Desktop-only circle that follows the cursor with a spring lag.
// Visible only when hovering the hero h1 or a project table row.
// mix-blend-mode: difference inverts whatever's underneath.
function CursorTrail() {
  const ref = useRef(null);

  useEffect(() => {
    if (window.matchMedia("(pointer: coarse)").matches) return;

    const el = ref.current;
    if (!el) return;

    let mouse = { x: -200, y: -200 };
    let pos   = { x: -200, y: -200 };
    let raf;

    const onMove = (e) => {
      mouse.x = e.clientX;
      mouse.y = e.clientY;
    };

    const tick = () => {
      pos.x += (mouse.x - pos.x) * 0.12;
      pos.y += (mouse.y - pos.y) * 0.12;
      el.style.transform = `translate(${pos.x}px, ${pos.y}px)`;
      raf = requestAnimationFrame(tick);
    };

    const ZONES = "h1, .proj-table";

    const show = (e) => {
      if (e.target.closest(ZONES)) {
        el.classList.add("visible");
        document.body.classList.add("cursor-none");
      }
    };
    const hide = (e) => {
      if (!e.target.closest(ZONES)) return;
      if (!e.relatedTarget || !e.relatedTarget.closest(ZONES)) {
        el.classList.remove("visible");
        document.body.classList.remove("cursor-none");
      }
    };

    const isProjectPage = () => /^#\/projects\//.test(window.location.hash);

    const onHash = () => {
      if (isProjectPage()) {
        el.classList.remove("visible");
        document.body.classList.remove("cursor-none");
      }
    };

    document.addEventListener("mousemove", onMove);
    document.addEventListener("mouseover",  show);
    document.addEventListener("mouseout",   hide);
    window.addEventListener("hashchange",   onHash);
    raf = requestAnimationFrame(tick);

    return () => {
      document.removeEventListener("mousemove", onMove);
      document.removeEventListener("mouseover",  show);
      document.removeEventListener("mouseout",   hide);
      window.removeEventListener("hashchange",   onHash);
      cancelAnimationFrame(raf);
    };
  }, []);

  return <div ref={ref} className="cursor-trail" aria-hidden="true" />;
}

Object.assign(window, { CursorTrail });
