/* global React, useT */

const useCountUp = (target, duration = 1800, start = 0) => {
  const [val, setVal] = React.useState(start);
  const [run, setRun] = React.useState(false);
  const ref = React.useRef(null);

  React.useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((entries) => {
      if (entries.some((e) => e.isIntersecting)) {
        setRun(true);
        io.disconnect();
      }
    }, { threshold: 0.3 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);

  React.useEffect(() => {
    if (!run) return;
    let raf, t0;
    const ease = (t) => 1 - Math.pow(1 - t, 3);
    const step = (ts) => {
      if (!t0) t0 = ts;
      const p = Math.min(1, (ts - t0) / duration);
      setVal(start + (target - start) * ease(p));
      if (p < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [run, target, duration, start]);

  return [val, ref];
};

function StatNum({ to, duration = 1800, format = true }) {
  const [val, ref] = useCountUp(to, duration);
  const rounded = Math.round(val);
  return <span ref={ref}>{format ? rounded.toLocaleString() : rounded}</span>;
}

function HeroStats() {
  const t = useT();
  return (
    <aside className="stats">
      <div className="stat">
        <div className="stat__value">€<StatNum to={500} duration={2400} /><sup>k+</sup></div>
        <div className="stat__label">{t("stats.starting_price")}</div>
      </div>
      <div className="stat">
        <div className="stat__value"><StatNum to={8} duration={2200} />%</div>
        <div className="stat__label">{t("stats.yield")}</div>
      </div>
      <div className="stat">
        <div className="stat__value"><StatNum to={100} duration={2400} /></div>
        <div className="stat__label">{t("stats.units")}</div>
      </div>
      <div className="stat">
        <div className="stat__value">Q2 <StatNum to={2029} duration={2800} format={false} /></div>
        <div className="stat__label">{t("stats.delivery")}</div>
      </div>
    </aside>
  );
}

Object.assign(window, { useCountUp, StatNum, HeroStats });
