// Shared hooks — useInView (one-shot intersection), animated <Counter>

const useInView = (options = {}) => {
  const ref = React.useRef(null);
  const [inView, setInView] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (typeof IntersectionObserver === "undefined") { setInView(true); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          setInView(true);
          io.disconnect();
        }
      });
    }, { threshold: 0.25, ...options });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return [ref, inView];
};

// Animated count-up. Parses a string like "26+", "+312%", "47M", "8×", "−41%", "#1"
// and animates the numeric portion while preserving the prefix/suffix.
const Counter = ({ value, duration = 1400, style, className }) => {
  const [ref, inView] = useInView({ threshold: 0.4 });

  // Split into prefix + number + suffix
  const match = String(value).match(/^([^\d.]*)([\d.]+)(.*)$/);
  if (!match) {
    return <span ref={ref} className={className} style={style}>{value}</span>;
  }
  const prefix = match[1];
  const targetStr = match[2];
  const suffix = match[3];
  const target = parseFloat(targetStr);
  const decimals = (targetStr.split(".")[1] || "").length;

  const [display, setDisplay] = React.useState(0);
  React.useEffect(() => {
    if (!inView) return;
    let raf;
    const start = performance.now();
    const tick = (now) => {
      const t = Math.min(1, (now - start) / duration);
      // ease-out cubic
      const eased = 1 - Math.pow(1 - t, 3);
      setDisplay(target * eased);
      if (t < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [inView, target, duration]);

  const formatted = decimals > 0
    ? display.toFixed(decimals)
    : Math.round(display).toString();

  return (
    <span ref={ref} className={className} style={style}>
      {prefix}{formatted}{suffix}
    </span>
  );
};

Object.assign(window, { useInView, Counter });
