// Activa Soluciones — CountUp
// Anima un número desde 0 hasta el valor objetivo cuando entra al viewport.
// Soporta prefijos/sufijos: "+38%", "S/240M", "90d", "42".

const CountUp = ({ value, duration = 1700, className = '' }) => {
  const ref = React.useRef(null);
  const startedRef = React.useRef(false);

  // Parse prefix / number / suffix from the value string
  const match = String(value).match(/^([^\d.\-+]*)([\-+]?\d+(?:\.\d+)?)(.*)$/);
  const prefix = match ? match[1] : '';
  const numStr = match ? match[2] : null;
  const suffix = match ? match[3] : '';
  const target = numStr !== null ? parseFloat(numStr) : null;
  const sign = numStr && numStr.trim().startsWith('+') ? '+' : (numStr && numStr.trim().startsWith('-') ? '-' : '');
  const isInteger = numStr !== null && !numStr.includes('.');

  const [display, setDisplay] = React.useState(
    target !== null ? `${prefix}${sign}0${suffix}` : value
  );

  React.useEffect(() => {
    if (target === null) { setDisplay(value); return; }
    const node = ref.current;
    if (!node) return;

    const animate = () => {
      const start = performance.now();
      const absTarget = Math.abs(target);
      const tick = (now) => {
        const t = Math.min((now - start) / duration, 1);
        // ease-out-cubic — matches --ease-rise feel
        const eased = 1 - Math.pow(1 - t, 3);
        const current = absTarget * eased;
        const num = isInteger ? Math.round(current).toString() : current.toFixed(1);
        setDisplay(`${prefix}${sign}${num}${suffix}`);
        if (t < 1) requestAnimationFrame(tick);
      };
      requestAnimationFrame(tick);
    };

    const io = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting && !startedRef.current) {
          startedRef.current = true;
          animate();
          io.disconnect();
        }
      });
    }, { threshold: 0.35 });
    io.observe(node);
    return () => io.disconnect();
  }, [value]);

  return <span ref={ref} className={className}>{display}</span>;
};
