// FinalCTA.jsx — closing ask on a single pastel card.
function FinalCTA({ onBookCall }) {
  const sectionRef = React.useRef(null);
  const cardRef = React.useRef(null);
  const btnRef = React.useRef(null);
  const playedRef = React.useRef(false);

  React.useEffect(() => {
    const section = sectionRef.current;
    if (!section) return undefined;

    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const gsap = window.gsap;
    const card = section.querySelector(".zg-final-card");
    const turntable = section.querySelector(".zg-turntable");

    const play = () => {
      if (playedRef.current) return;
      playedRef.current = true;

      if (reduced || !gsap || !card) {
        section.classList.add("zg-final-cta--revealed");
        return;
      }

      gsap
        .timeline({ defaults: { ease: "power3.out" } })
        .from(card, { opacity: 0, y: 48, rotate: -6, scale: 0.94, duration: 0.95 })
        .from(
          turntable,
          { opacity: 0, scale: 0.7, rotate: -36, x: 60, duration: 0.85, ease: "back.out(1.6)" },
          "-=0.6"
        )
        .from(
          card.querySelectorAll("#zg-final-title, .zg-final-sub, .zg-btn"),
          { opacity: 0, y: 18, stagger: 0.08, duration: 0.55 },
          "-=0.7"
        )
        .add(() => section.classList.add("zg-final-cta--revealed"));
    };

    const io = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          play();
          io.disconnect();
        }
      },
      { threshold: 0.35 }
    );

    io.observe(section);
    return () => io.disconnect();
  }, []);

  React.useEffect(() => {
    const card = cardRef.current;
    const btn = btnRef.current;
    if (!card) return undefined;

    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const hover = window.matchMedia("(hover: hover)").matches;
    if (reduced || !hover) return undefined;

    let raf = 0;
    let targetX = 0;
    let targetY = 0;
    let magnetX = 0;
    let magnetY = 0;
    let currentX = 0;
    let currentY = 0;
    let currentMx = 0;
    let currentMy = 0;
    let active = false;

    const paint = () => {
      raf = 0;
      currentX += (targetX - currentX) * 0.12;
      currentY += (targetY - currentY) * 0.12;
      currentMx += (magnetX - currentMx) * 0.18;
      currentMy += (magnetY - currentMy) * 0.18;
      card.style.setProperty("--tilt-x", `${currentX.toFixed(2)}deg`);
      card.style.setProperty("--tilt-y", `${currentY.toFixed(2)}deg`);
      if (btn) {
        btn.style.setProperty("--magnet-x", `${currentMx.toFixed(2)}px`);
        btn.style.setProperty("--magnet-y", `${currentMy.toFixed(2)}px`);
      }
      if (
        active ||
        Math.abs(currentX - targetX) > 0.05 ||
        Math.abs(currentY - targetY) > 0.05 ||
        Math.abs(currentMx - magnetX) > 0.2 ||
        Math.abs(currentMy - magnetY) > 0.2
      ) {
        raf = requestAnimationFrame(paint);
      }
    };

    const queue = () => {
      if (!raf) raf = requestAnimationFrame(paint);
    };

    const onMove = (event) => {
      const rect = card.getBoundingClientRect();
      const nx = (event.clientX - rect.left) / rect.width;
      const ny = (event.clientY - rect.top) / rect.height;
      const tiltMax = 6;
      targetY = (nx - 0.5) * tiltMax * 2;
      targetX = (0.5 - ny) * tiltMax * 2;
      active = true;

      if (btn) {
        const bRect = btn.getBoundingClientRect();
        const bCenterX = bRect.left + bRect.width / 2;
        const bCenterY = bRect.top + bRect.height / 2;
        const dx = event.clientX - bCenterX;
        const dy = event.clientY - bCenterY;
        const distance = Math.hypot(dx, dy);
        const radius = 220;
        if (distance < radius) {
          const pull = 1 - distance / radius;
          magnetX = dx * 0.22 * pull;
          magnetY = dy * 0.22 * pull;
        } else {
          magnetX = 0;
          magnetY = 0;
        }
      }
      queue();
    };

    const onLeave = () => {
      targetX = 0;
      targetY = 0;
      magnetX = 0;
      magnetY = 0;
      active = false;
      queue();
    };

    card.addEventListener("pointermove", onMove);
    card.addEventListener("pointerleave", onLeave);

    return () => {
      card.removeEventListener("pointermove", onMove);
      card.removeEventListener("pointerleave", onLeave);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  return (
    <section
      ref={sectionRef}
      className="zg-final-cta"
      aria-labelledby="zg-final-title"
    >
      <div className="zg-container">
        <div className="zg-final-card" ref={cardRef}>
          <div className="zg-final-particles" aria-hidden="true">
            <span /><span /><span /><span /><span /><span /><span /><span />
          </div>
          <h2 id="zg-final-title" className="zg-h2">
            Tell us about <span className="zg-highlight">the work</span>.
          </h2>
          <p className="zg-body-lg zg-final-sub">
            Thirty minutes. Show us one workflow. We&apos;ll tell you if it&apos;s
            worth building.
          </p>
          <button type="button" className="zg-btn" onClick={onBookCall} ref={btnRef}>
            Book a call <span className="plus">+</span>
          </button>

          <TurntableDecor className="zg-turntable--feature" />
        </div>
      </div>
    </section>
  );
}

window.FinalCTA = FinalCTA;
