"use client";

import { motion, type Variants } from "framer-motion";
import { cn } from "@/shared/utils";

interface AnimatedContainerProps {
  children: React.ReactNode;
  className?: string;
  animation?: "fade-up" | "fade-scale" | "slide-left" | "none";
  stagger?: boolean;
  delay?: number;
}

const fadeUp: Variants = {
  hidden: { opacity: 0, y: 16 },
  visible: { opacity: 1, y: 0, transition: { duration: 0.3, ease: "easeOut" } },
};

const fadeUpSmall: Variants = {
  hidden: { opacity: 0, y: 12 },
  visible: { opacity: 1, y: 0, transition: { duration: 0.2, ease: "easeOut" } },
};

const fadeUpFast: Variants = {
  hidden: { opacity: 0, y: 16 },
  visible: { opacity: 1, y: 0, transition: { duration: 0.2, ease: "easeOut" } },
};

const fadeScale: Variants = {
  hidden: { opacity: 0, scale: 0.95 },
  visible: { opacity: 1, scale: 1, transition: { duration: 0.2, ease: "easeOut" } },
};

const slideLeft: Variants = {
  hidden: { opacity: 0, x: -24 },
  visible: { opacity: 1, x: 0, transition: { duration: 0.3, ease: "easeOut" } },
};

const slideLeftSmall: Variants = {
  hidden: { opacity: 0, x: -8 },
  visible: { opacity: 1, x: 0, transition: { duration: 0.2, ease: "easeOut" } },
};

const noneVariant: Variants = {
  hidden: {},
  visible: {},
};

/** Stagger container — wrap children that use item variants */
function staggerContainer(staggerSeconds = 0.05): Variants {
  return {
    hidden: {},
    visible: { transition: { staggerChildren: staggerSeconds } },
  };
}

/**
 * Re-exported variant objects for direct use with motion components.
 * Prefer these over defining local variants in each file.
 */
export const motionVariants = {
  fadeUp,
  fadeUpSmall,
  fadeUpFast,
  fadeScale,
  slideLeft,
  slideLeftSmall,
  staggerContainer,
} as const;

const variantMap = {
  "fade-up": fadeUp,
  "fade-scale": fadeScale,
  "slide-left": slideLeft,
  none: noneVariant,
} as const;

export function AnimatedContainer({
  children,
  className,
  animation = "fade-up",
  stagger = false,
  delay = 0,
}: AnimatedContainerProps) {
  const variants = variantMap[animation];

  return (
    <motion.div
      className={cn(className)}
      initial="hidden"
      animate="visible"
      variants={variants}
      transition={
        stagger ? { staggerChildren: 0.1, delayChildren: delay / 1000 } : { delay: delay / 1000 }
      }
    >
      {children}
    </motion.div>
  );
}
