'use client';

import { motion } from 'framer-motion';
import { cn } from '@/lib/utils';
import {
  revealVariants,
  fadeVariants,
  slideLeftVariants,
  slideRightVariants,
  staggerContainer,
  viewportOnce,
} from '@/lib/animations';
import type { Variants } from 'framer-motion';

type RevealVariant = 'fadeUp' | 'fadeIn' | 'slideLeft' | 'slideRight';

interface ScrollRevealProps {
  children: React.ReactNode;
  className?: string;
  variant?: RevealVariant;
  delay?: number;
  stagger?: boolean;
}

const variantMap: Record<RevealVariant, Variants> = {
  fadeUp: revealVariants,
  fadeIn: fadeVariants,
  slideLeft: slideLeftVariants,
  slideRight: slideRightVariants,
};

export default function ScrollReveal({
  children,
  className,
  variant = 'fadeUp',
  delay,
  stagger = false,
}: ScrollRevealProps) {
  if (stagger) {
    return (
      <motion.div
        variants={staggerContainer}
        initial="hidden"
        whileInView="visible"
        viewport={viewportOnce}
        className={cn(className)}
      >
        {children}
      </motion.div>
    );
  }

  const selectedVariants = variantMap[variant];

  // If a delay is provided, override the transition on the visible state
  const resolvedVariants: Variants = delay
    ? {
        ...selectedVariants,
        visible: {
          ...(selectedVariants.visible as object),
          transition: {
            ...((selectedVariants.visible as { transition?: object }).transition ?? {}),
            delay,
          },
        },
      }
    : selectedVariants;

  return (
    <motion.div
      variants={resolvedVariants}
      initial="hidden"
      whileInView="visible"
      viewport={viewportOnce}
      className={cn(className)}
    >
      {children}
    </motion.div>
  );
}

export type { ScrollRevealProps, RevealVariant };
