/* global React */

const useCountUp = (target, opts = {}) => {
  const { duration = 1800, decimals = 0, start = 0 } = opts;
  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) => entries.forEach((e) => e.isIntersecting && setRun(true)),
      { 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, decimals = 0, prefix = "", suffix = "", duration = 1800, format = true }) {
  const [val, ref] = useCountUp(to, { duration, decimals });
  const rounded = Math.round(val);
  const display = decimals === 0
    ? (format ? rounded.toLocaleString() : String(rounded))
    : val.toFixed(decimals);
  return <span ref={ref}>{prefix}{display}{suffix}</span>;
}

function HeroStats() {
  return (
    <aside className="stats">
      <div className="stat">
        <div className="stat__value">€<StatNum to={500} duration={2400} /><sup>k+</sup></div>
        <div className="stat__label">Starting from</div>
      </div>
      <div className="stat">
        <div className="stat__value"><StatNum to={8} duration={2200} />%</div>
        <div className="stat__label">Projected ROI</div>
      </div>
      <div className="stat">
        <div className="stat__value"><StatNum to={100} duration={2400} /></div>
        <div className="stat__label">Private residences</div>
      </div>
      <div className="stat">
        <div className="stat__value">Q2 <StatNum to={2029} duration={2800} format={false} /></div>
        <div className="stat__label">Estimated delivery</div>
      </div>
    </aside>
  );
}

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