// Shared hooks for reveal-on-scroll and counter animation.
const { useEffect, useRef, useState } = React;

function useReveal(opts = {}) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const obs = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            setShown(true);
            obs.disconnect();
          }
        });
      },
      { threshold: opts.threshold ?? 0.15 }
    );
    obs.observe(el);
    return () => obs.disconnect();
  }, []);
  return [ref, shown];
}

function useCountUp(target, { duration = 1800, start = 0, decimals = 0, when = true } = {}) {
  const [val, setVal] = useState(start);
  useEffect(() => {
    if (!when) return;
    const t0 = performance.now();
    let raf;
    const tick = (t) => {
      const p = Math.min(1, (t - t0) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      const v = start + (target - start) * eased;
      setVal(v);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [when, target, duration, start]);
  return decimals === 0 ? Math.round(val) : Number(val.toFixed(decimals));
}

function formatNumberFR(n) {
  return new Intl.NumberFormat('fr-FR').format(n);
}

Object.assign(window, { useReveal, useCountUp, formatNumberFR });
