/* Scroll-reveal helpers — IntersectionObserver-based */

function useReveal(opts = {}) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
      el.classList.add('in');
      return;
    }
    const io = new IntersectionObserver(
      entries => {
        entries.forEach(e => {
          if (e.isIntersecting) {
            // Stagger via dataset.delay (ms)
            const d = parseInt(el.dataset.delay || '0', 10);
            if (d) {
              setTimeout(() => el.classList.add('in'), d);
            } else {
              el.classList.add('in');
            }
            io.unobserve(el);
          }
        });
      },
      { threshold: opts.threshold ?? 0.15, rootMargin: opts.rootMargin ?? '0px 0px -8% 0px' }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return ref;
}

/* <Reveal>: a div that fades + slides in on first intersection.
   variant: 'up' (default) | 'fade' | 'left' | 'right' | 'scale' */
function Reveal({
  as: Tag = 'div',
  variant = 'up',
  delay = 0,
  className = '',
  children,
  ...rest
}) {
  const ref = useReveal();
  const vClass = variant === 'up' ? '' : ' r-' + variant;
  return (
    <Tag
      ref={ref}
      data-delay={delay}
      className={`reveal${vClass} ${className}`}
      {...rest}
    >
      {children}
    </Tag>
  );
}

/* Hook: parallax y offset based on scroll. Returns css transform string. */
function useScrollParallax(speed = 0.15) {
  const [y, setY] = React.useState(0);
  React.useEffect(() => {
    let raf = null;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        setY(window.scrollY * speed);
        raf = null;
      });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, [speed]);
  return y;
}

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