/* Shared primitives for MIRAI landing */

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// IntersectionObserver-driven fade-up
function useReveal(threshold = 0.15) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    if (shown) return;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            setShown(true);
            io.disconnect();
          }
        });
      },
      { threshold, rootMargin: "0px 0px -10% 0px" }
    );
    io.observe(ref.current);
    return () => io.disconnect();
  }, [threshold, shown]);
  return [ref, shown];
}

function Reveal({ children, delay = 0, as: As = "div", className = "", style = {}, ...rest }) {
  const [ref, shown] = useReveal();
  return (
    <As
      ref={ref}
      className={`fade-up ${shown ? "is-in" : ""} ${className}`}
      style={{ transitionDelay: shown ? `${delay}ms` : "0ms", ...style }}
      {...rest}
    >
      {children}
    </As>
  );
}

// Animated counter that runs once when visible
function Counter({ to, suffix = "", prefix = "", duration = 1600, decimals = 0 }) {
  const ref = useRef(null);
  const [val, setVal] = useState(0);
  const [started, setStarted] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting && !started) {
          setStarted(true);
          io.disconnect();
        }
      });
    }, { threshold: 0.4 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [started]);
  useEffect(() => {
    if (!started) return;
    let raf;
    const start = performance.now();
    const tick = (t) => {
      const p = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setVal(to * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [started, to, duration]);
  const display = decimals > 0 ? val.toFixed(decimals) : Math.round(val).toLocaleString("es-AR");
  return <span ref={ref}>{prefix}{display}{suffix}</span>;
}

// Tiny hash-based router. Returns "/", "/proyectos", "/sobre-nosotros", "/contacto", ...
function parseHash(hash) {
  if (!hash) return "/";
  const h = hash.replace(/^#/, "");
  if (h === "" || h === "/" || h === "top") return "/";
  if (h.startsWith("/")) return h;
  return "/";
}
function useRoute() {
  const [route, setRoute] = useState(() => parseHash(window.location.hash));
  useEffect(() => {
    const onHash = () => {
      setRoute(parseHash(window.location.hash));
      window.scrollTo({ top: 0, behavior: "auto" });
    };
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);
  return route;
}

Object.assign(window, { useReveal, Reveal, Counter, useRoute });
