// SR SOFT — Animation utilities: cursor spotlight, aurora bg,
// magnetic buttons, animated counter, tech marquee, hero parallax,
// method timeline progress.

const { useEffect, useRef, useState } = React;

// ── Global cursor spotlight (subtle radial glow follows pointer) ──
function CursorSpot() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let tx = window.innerWidth / 2, ty = window.innerHeight / 2;
    let cx = tx, cy = ty;
    let raf;
    const onMove = (e) => { tx = e.clientX; ty = e.clientY; };
    const tick = () => {
      cx += (tx - cx) * 0.12;
      cy += (ty - cy) * 0.12;
      el.style.transform = `translate3d(${cx}px, ${cy}px, 0)`;
      raf = requestAnimationFrame(tick);
    };
    window.addEventListener("pointermove", onMove, { passive: true });
    tick();
    return () => { window.removeEventListener("pointermove", onMove); cancelAnimationFrame(raf); };
  }, []);
  return <div className="cursor-spot" ref={ref}></div>;
}

// ── Aurora background ───────────────────────────────────────────
function Aurora() { return <div className="aurora" aria-hidden="true"></div>; }

// ── Magnetic button — attracts toward cursor ────────────────────
function useMagnetic(ref, strength = 0.35) {
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let raf, tx = 0, ty = 0, cx = 0, cy = 0;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      tx = (e.clientX - (r.left + r.width / 2)) * strength;
      ty = (e.clientY - (r.top + r.height / 2)) * strength;
    };
    const onLeave = () => { tx = 0; ty = 0; };
    const tick = () => {
      cx += (tx - cx) * 0.18;
      cy += (ty - cy) * 0.18;
      el.style.transform = `translate3d(${cx}px, ${cy}px, 0)`;
      raf = requestAnimationFrame(tick);
    };
    el.addEventListener("pointermove", onMove);
    el.addEventListener("pointerleave", onLeave);
    tick();
    return () => {
      el.removeEventListener("pointermove", onMove);
      el.removeEventListener("pointerleave", onLeave);
      cancelAnimationFrame(raf);
    };
  }, [ref, strength]);
}

function MagneticBtn({ href, children, className = "btn", style }) {
  const ref = useRef(null);
  useMagnetic(ref, 0.25);
  return (
    <a ref={ref} href={href} className={className} style={style}>
      {children}
    </a>
  );
}

// ── Animated counter (counts up when scrolled into view) ────────
function AnimatedCounter({ to, suffix = "", prefix = "", duration = 1600, decimals = 0 }) {
  const ref = useRef(null);
  const [v, setV] = useState(0);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          const start = performance.now();
          const tick = (t) => {
            const k = Math.min(1, (t - start) / duration);
            const eased = 1 - Math.pow(1 - k, 3);
            setV(to * eased);
            if (k < 1) requestAnimationFrame(tick);
          };
          requestAnimationFrame(tick);
          io.unobserve(el);
        }
      });
    }, { threshold: 0.4 });
    io.observe(el);
    return () => io.disconnect();
  }, [to, duration]);
  const fmt = decimals > 0 ? v.toFixed(decimals) : Math.round(v).toLocaleString("it-IT");
  return <span ref={ref}>{prefix}{fmt}{suffix}</span>;
}

// ── Tech marquee (infinite horizontal scroll) ───────────────────
function TechMarquee({ items }) {
  const doubled = [...items, ...items];
  return (
    <div className="marquee" aria-hidden="true">
      <div className="marquee-track">
        {doubled.map((it, i) => (
          <React.Fragment key={i}>
            <span className="marquee-item">
              <TechIcon item={it} size={18} />
              <span>{it.n}</span>
            </span>
            <span className="marquee-divider">·</span>
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

// ── Pointer parallax tilt for hero visual ───────────────────────
function usePointerParallax(ref, depth = 12) {
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let raf, tx = 0, ty = 0, cx = 0, cy = 0;
    const layers = el.querySelectorAll("[data-depth]");
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      tx = ((e.clientX - (r.left + r.width / 2)) / r.width) * 2;
      ty = ((e.clientY - (r.top + r.height / 2)) / r.height) * 2;
    };
    const onLeave = () => { tx = 0; ty = 0; };
    const tick = () => {
      cx += (tx - cx) * 0.08;
      cy += (ty - cy) * 0.08;
      layers.forEach((l) => {
        const d = parseFloat(l.dataset.depth || "1");
        l.style.transform = `translate3d(${cx * depth * d}px, ${cy * depth * d}px, 0) rotateY(${cx * d * 1.2}deg) rotateX(${-cy * d * 1.2}deg)`;
      });
      raf = requestAnimationFrame(tick);
    };
    el.addEventListener("pointermove", onMove);
    el.addEventListener("pointerleave", onLeave);
    tick();
    return () => {
      el.removeEventListener("pointermove", onMove);
      el.removeEventListener("pointerleave", onLeave);
      cancelAnimationFrame(raf);
    };
  }, [ref, depth]);
}

// ── Method timeline scroll progress ─────────────────────────────
function useMethodProgress() {
  useEffect(() => {
    const rail = document.querySelector(".method-process");
    if (!rail) return;

    const update = () => {
      const nodes = rail.querySelectorAll(".method-node");
      const total = nodes.length;
      const vh = window.innerHeight;

      if (window.innerWidth >= 861) {
        // ── Desktop: single horizontal progress line ──
        const r = rail.getBoundingClientRect();
        const start = vh * 0.85;
        const end   = vh * 0.25;
        const visibleLen = r.height + (start - end);
        const traveled = start - r.top;
        const p = Math.max(0, Math.min(1, traveled / visibleLen));
        rail.style.setProperty("--method-progress", `${p * 100}%`);
        nodes.forEach((node, i) => {
          node.classList.toggle("active", p >= i / total);
        });
      } else {
        // ── Mobile: vertical timeline, per-node line fill ──
        const triggerY = vh * 0.62;
        nodes.forEach((node, i) => {
          const r = node.getBoundingClientRect();
          node.classList.toggle("active", r.top < triggerY);
          if (i < total - 1) {
            const nextR = nodes[i + 1].getBoundingClientRect();
            const fill = Math.max(0, Math.min(1,
              (triggerY - r.top) / (nextR.top - r.top)
            ));
            node.style.setProperty("--line-fill", `${fill * 100}%`);
          }
        });
      }
    };

    update();
    window.addEventListener("scroll", update, { passive: true });
    window.addEventListener("resize", update);
    return () => {
      window.removeEventListener("scroll", update);
      window.removeEventListener("resize", update);
    };
  }, []);
}

// Export
Object.assign(window, {
  CursorSpot, Aurora, MagneticBtn, AnimatedCounter, TechMarquee,
  usePointerParallax, useMethodProgress
});
