"use client";

/**
 * In-view reveal. Fades + lifts content when it scrolls into view (once).
 * - Motion `whileInView` with a viewport margin so it triggers slightly early.
 * - `stagger` cascades direct children via Motion variants.
 * - Honors prefers-reduced-motion (renders fully visible, no transform).
 */
import { motion, type Variants } from "motion/react";
import { useReducedMotion } from "motion/react";

type Props = {
  children: React.ReactNode;
  className?: string;
  delay?: number;
  y?: number;
  stagger?: number;
  as?: "div" | "section" | "ul" | "ol" | "li" | "p" | "figure" | "header";
};

export default function Reveal({
  children,
  className,
  delay = 0,
  y = 26,
  stagger,
  as = "div",
}: Props) {
  const reduce = useReducedMotion();
  const MotionTag = motion[as] as typeof motion.div;

  if (stagger) {
    const parent: Variants = {
      hidden: {},
      show: { transition: { staggerChildren: reduce ? 0 : stagger, delayChildren: delay } },
    };
    return (
      <MotionTag
        className={className}
        variants={parent}
        initial="hidden"
        whileInView="show"
        viewport={{ once: true, margin: "0px 0px -12% 0px" }}
      >
        {children}
      </MotionTag>
    );
  }

  return (
    <MotionTag
      className={className}
      initial={reduce ? { opacity: 1 } : { opacity: 0, y }}
      whileInView={{ opacity: 1, y: 0 }}
      viewport={{ once: true, margin: "0px 0px -12% 0px" }}
      transition={{ duration: 0.7, delay: delay / 1000, ease: [0.16, 1, 0.3, 1] }}
    >
      {children}
    </MotionTag>
  );
}

/** A child item that participates in a parent <Reveal stagger>. */
export function RevealItem({
  children,
  className,
  y = 22,
  as = "div",
}: {
  children: React.ReactNode;
  className?: string;
  y?: number;
  as?: "div" | "li" | "p";
}) {
  const reduce = useReducedMotion();
  const MotionTag = motion[as] as typeof motion.div;
  const item: Variants = {
    hidden: reduce ? { opacity: 1 } : { opacity: 0, y },
    show: { opacity: 1, y: 0, transition: { duration: 0.65, ease: [0.16, 1, 0.3, 1] } },
  };
  return (
    <MotionTag className={className} variants={item}>
      {children}
    </MotionTag>
  );
}
