// Kinetic scroll engine — beams that assemble as you scroll.
// Production build: ascend flow only (per v2 baked defaults).

const useScrollY = () => {
  const [y, setY] = React.useState(0);
  React.useEffect(() => {
    const onS = () => setY(window.scrollY);
    onS();
    window.addEventListener("scroll", onS, { passive: true });
    return () => window.removeEventListener("scroll", onS);
  }, []);
  return y;
};

const useEnter = (ref, { start = 0.95, end = 0.55 } = {}) => {
  const [p, setP] = React.useState(0);
  React.useEffect(() => {
    const onS = () => {
      if (!ref.current) return;
      const r = ref.current.getBoundingClientRect();
      const vh = window.innerHeight;
      const ratio = r.top / vh;
      const v = (start - ratio) / (start - end);
      setP(Math.max(0, Math.min(1, v)));
    };
    onS();
    window.addEventListener("scroll", onS, { passive: true });
    window.addEventListener("resize", onS);
    return () => {
      window.removeEventListener("scroll", onS);
      window.removeEventListener("resize", onS);
    };
  }, [start, end]);
  return p;
};

const easeOut = (x) => 1 - Math.pow(1 - Math.max(0, Math.min(1, x)), 3);

const JoinReveal = ({ children, delay = 0, as = "div", style = {}, ...rest }) => {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);

  React.useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            setTimeout(() => setShown(true), delay);
            io.disconnect();
          }
        });
      },
      { threshold: 0.12, rootMargin: "0px 0px -8% 0px" }
    );
    io.observe(ref.current);
    return () => io.disconnect();
  }, [delay]);

  const transform = shown ? "translate(0,0) scale(1)" : "translateY(20px)";
  const dur = "700ms";

  const Tag = as;
  return (
    <Tag
      ref={ref}
      style={{
        opacity: shown ? 1 : 0,
        transform,
        transformOrigin: "center",
        transition: `opacity ${dur} cubic-bezier(.22,1,.36,1), transform ${dur} cubic-bezier(.22,1,.36,1)`,
        ...style,
      }}
      {...rest}
    >
      {children}
    </Tag>
  );
};

// Fixed left-rail timeline; shu marker travels with scroll.
const ScrollProgressRail = () => {
  const [p, setP] = React.useState(0);
  React.useEffect(() => {
    const onS = () => {
      const max = document.documentElement.scrollHeight - window.innerHeight;
      setP(max > 0 ? window.scrollY / max : 0);
    };
    onS();
    window.addEventListener("scroll", onS, { passive: true });
    window.addEventListener("resize", onS);
    return () => {
      window.removeEventListener("scroll", onS);
      window.removeEventListener("resize", onS);
    };
  }, []);

  return (
    <div style={{
      position: "fixed",
      left: "16px",
      top: "0",
      bottom: "0",
      width: "1px",
      background: "rgba(26,22,19,0.06)",
      zIndex: 50,
      pointerEvents: "none",
    }}>
      <div style={{
        position: "absolute",
        top: 0,
        left: 0,
        right: 0,
        height: `${p * 100}%`,
        background: "#1B2845",
        transition: "none",
      }} />
      <div style={{
        position: "absolute",
        top: `${p * 100}%`,
        left: "-4px",
        width: "9px",
        height: "9px",
        background: "#B04A3A",
        transform: "translateY(-50%)",
        transition: "top 80ms linear",
      }} />
    </div>
  );
};

Object.assign(window, {
  useScrollY, useEnter, easeOut, JoinReveal, ScrollProgressRail,
});
