/* eslint-disable react/prop-types */
/**
 * Reveal · wrapper para animaciones de entrada al hacer scroll.
 *
 * Props:
 *   delay        ms antes de animar
 *   distance     px de translateY (default 24)
 *   threshold    0..1 intersection threshold (default 0.15)
 *   once         (default true) animar una sola vez
 *
 * Respeta prefers-reduced-motion (no-op).
 */

const { useEffect: uE_Rv, useRef: uR_Rv, useState: uS_Rv } = React;

function Reveal({
  children,
  delay = 0,
  distance = 24,
  threshold = 0.15,
  once = true,
  as = 'div',
  style = {},
  ...rest
}) {
  const ref = uR_Rv(null);
  const [show, setShow] = uS_Rv(false);

  uE_Rv(() => {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
      setShow(true);
      return;
    }
    if (!ref.current) return;
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) {
        setShow(true);
        if (once) obs.disconnect();
      } else if (!once) {
        setShow(false);
      }
    }, { threshold });
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, []);

  const Comp = as;
  return (
    <Comp
      ref={ref}
      style={{
        opacity: show ? 1 : 0,
        transform: show ? 'translate3d(0,0,0)' : `translate3d(0, ${distance}px, 0)`,
        transition: `opacity 800ms cubic-bezier(0.16, 1, 0.3, 1) ${delay}ms, transform 800ms cubic-bezier(0.16, 1, 0.3, 1) ${delay}ms`,
        willChange: 'opacity, transform',
        ...style,
      }}
      {...rest}
    >
      {children}
    </Comp>
  );
}

window.Reveal = Reveal;
