import { Children, isValidElement, type ReactNode } from "react";
import { motion, useReducedMotion, type Variants } from "framer-motion";
import Box from "@mui/material/Box";
import type { SxProps, Theme } from "@mui/material/styles";

const MotionBox = motion.create(Box);

const container: Variants = {
  hidden: {},
  show: { transition: { staggerChildren: 0.06, delayChildren: 0.04 } },
};

const itemVariant: Variants = {
  hidden: { opacity: 0, y: 16 },
  show: {
    opacity: 1,
    y: 0,
    transition: { duration: 0.45, ease: [0.16, 1, 0.3, 1] },
  },
};

/**
 * Consistent page entrance. Use as a page's OUTERMOST wrapper (in place of the
 * page's root `<Box>`): each top-level child rises + fades in, staggered, so the
 * whole page comes in the same way everywhere — no element appears instantly.
 * Wrapping each child in a block `motion.div` is layout-safe for the vertical
 * section stacks our pages use (header → filters → card/table); nested grids/
 * flex inside a section are untouched. Honors prefers-reduced-motion.
 */
export default function PageEnter({
  children,
  sx,
}: {
  children: ReactNode;
  sx?: SxProps<Theme>;
}) {
  const reduce = useReducedMotion();
  if (reduce) return <Box sx={sx}>{children}</Box>;

  return (
    <MotionBox variants={container} initial="hidden" animate="show" sx={sx}>
      {Children.map(children, (child) =>
        isValidElement(child) ? (
          <motion.div variants={itemVariant}>{child}</motion.div>
        ) : (
          child
        ),
      )}
    </MotionBox>
  );
}
