'use client';

import { motion, AnimatePresence, type Variants, type Transition } from 'framer-motion';
import { usePathname } from 'next/navigation';
import { type ReactNode } from 'react';

const defaultTransition: Transition = {
  duration: 0.4,
  ease: [0.16, 1, 0.3, 1],
};

export const fadeInVariants: Variants = {
  initial: {
    opacity: 0,
  },
  enter: {
    opacity: 1,
    transition: defaultTransition,
  },
  exit: {
    opacity: 0,
    transition: { ...defaultTransition, duration: 0.2 },
  },
};

export const slideUpVariants: Variants = {
  initial: {
    opacity: 0,
    y: 20,
  },
  enter: {
    opacity: 1,
    y: 0,
    transition: defaultTransition,
  },
  exit: {
    opacity: 0,
    y: -20,
    transition: { ...defaultTransition, duration: 0.2 },
  },
};

export const slideRightVariants: Variants = {
  initial: {
    opacity: 0,
    x: -20,
  },
  enter: {
    opacity: 1,
    x: 0,
    transition: defaultTransition,
  },
  exit: {
    opacity: 0,
    x: 20,
    transition: { ...defaultTransition, duration: 0.2 },
  },
};

export const scaleVariants: Variants = {
  initial: {
    opacity: 0,
    scale: 0.98,
  },
  enter: {
    opacity: 1,
    scale: 1,
    transition: defaultTransition,
  },
  exit: {
    opacity: 0,
    scale: 1.02,
    transition: { ...defaultTransition, duration: 0.2 },
  },
};

export const inkRevealPageVariants: Variants = {
  initial: {
    opacity: 0,
    clipPath: 'circle(0% at 50% 50%)',
  },
  enter: {
    opacity: 1,
    clipPath: 'circle(100% at 50% 50%)',
    transition: {
      duration: 0.8,
      ease: [0.16, 1, 0.3, 1],
    },
  },
  exit: {
    opacity: 0,
    clipPath: 'circle(0% at 50% 50%)',
    transition: {
      duration: 0.4,
      ease: [0.16, 1, 0.3, 1],
    },
  },
};

export const curtainVariants: Variants = {
  initial: {
    opacity: 0,
    y: '100%',
  },
  enter: {
    opacity: 1,
    y: 0,
    transition: {
      duration: 0.6,
      ease: [0.16, 1, 0.3, 1],
    },
  },
  exit: {
    opacity: 0,
    y: '-100%',
    transition: {
      duration: 0.4,
      ease: [0.16, 1, 0.3, 1],
    },
  },
};

interface PageTransitionProps {
  children: ReactNode;
  variants?: Variants;
  className?: string;
}

export function PageTransition({
  children,
  variants = fadeInVariants,
  className = '',
}: PageTransitionProps) {
  const pathname = usePathname();

  return (
    <AnimatePresence mode="wait">
      <motion.div
        key={pathname}
        initial="initial"
        animate="enter"
        exit="exit"
        variants={variants}
        className={className}
      >
        {children}
      </motion.div>
    </AnimatePresence>
  );
}

interface FadeTransitionProps {
  children: ReactNode;
  className?: string;
}

export function FadeTransition({ children, className = '' }: FadeTransitionProps) {
  return (
    <PageTransition variants={fadeInVariants} className={className}>
      {children}
    </PageTransition>
  );
}

interface SlideUpTransitionProps {
  children: ReactNode;
  className?: string;
}

export function SlideUpTransition({ children, className = '' }: SlideUpTransitionProps) {
  return (
    <PageTransition variants={slideUpVariants} className={className}>
      {children}
    </PageTransition>
  );
}

interface InkRevealTransitionProps {
  children: ReactNode;
  className?: string;
}

export function InkRevealTransition({ children, className = '' }: InkRevealTransitionProps) {
  return (
    <PageTransition variants={inkRevealPageVariants} className={className}>
      {children}
    </PageTransition>
  );
}

interface SectionTransitionProps {
  children: ReactNode;
  className?: string;
  delay?: number;
}

export function SectionTransition({ children, className = '', delay = 0 }: SectionTransitionProps) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 30 }}
      whileInView={{ opacity: 1, y: 0 }}
      viewport={{ once: true, amount: 0.2 }}
      transition={{
        duration: 0.6,
        delay,
        ease: [0.16, 1, 0.3, 1],
      }}
      className={className}
    >
      {children}
    </motion.div>
  );
}

interface StaggerChildrenProps {
  children: ReactNode;
  className?: string;
  staggerDelay?: number;
}

export function StaggerChildren({ children, className = '', staggerDelay = 0.1 }: StaggerChildrenProps) {
  const containerVariants: Variants = {
    hidden: { opacity: 0 },
    visible: {
      opacity: 1,
      transition: {
        staggerChildren: staggerDelay,
        delayChildren: 0.1,
      },
    },
  };

  return (
    <motion.div
      initial="hidden"
      whileInView="visible"
      viewport={{ once: true, amount: 0.2 }}
      variants={containerVariants}
      className={className}
    >
      {children}
    </motion.div>
  );
}

interface AnimatedSectionProps {
  children: ReactNode;
  className?: string;
  animation?: 'fade' | 'slide' | 'scale' | 'ink';
  delay?: number;
}

export function AnimatedSection({
  children,
  className = '',
  animation = 'fade',
  delay = 0,
}: AnimatedSectionProps) {
  const getVariants = (): Variants => {
    switch (animation) {
      case 'slide':
        return {
          hidden: { opacity: 0, y: 40 },
          visible: {
            opacity: 1,
            y: 0,
            transition: {
              duration: 0.6,
              delay,
              ease: [0.16, 1, 0.3, 1],
            },
          },
        };
      case 'scale':
        return {
          hidden: { opacity: 0, scale: 0.95 },
          visible: {
            opacity: 1,
            scale: 1,
            transition: {
              duration: 0.6,
              delay,
              ease: [0.16, 1, 0.3, 1],
            },
          },
        };
      case 'ink':
        return {
          hidden: {
            opacity: 0,
            scale: 0.9,
            filter: 'blur(10px)',
          },
          visible: {
            opacity: 1,
            scale: 1,
            filter: 'blur(0px)',
            transition: {
              duration: 0.8,
              delay,
              ease: [0.16, 1, 0.3, 1],
            },
          },
        };
      default:
        return {
          hidden: { opacity: 0 },
          visible: {
            opacity: 1,
            transition: {
              duration: 0.6,
              delay,
              ease: [0.16, 1, 0.3, 1],
            },
          },
        };
    }
  };

  return (
    <motion.div
      initial="hidden"
      whileInView="visible"
      viewport={{ once: true, amount: 0.2 }}
      variants={getVariants()}
      className={className}
    >
      {children}
    </motion.div>
  );
}

interface LoadingTransitionProps {
  isLoading: boolean;
  children: ReactNode;
  loadingComponent?: ReactNode;
  className?: string;
}

export function LoadingTransition({
  isLoading,
  children,
  loadingComponent,
  className = '',
}: LoadingTransitionProps) {
  return (
    <AnimatePresence mode="wait">
      {isLoading ? (
        <motion.div
          key="loading"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{ duration: 0.2 }}
          className={className}
        >
          {loadingComponent || (
            <div className="flex items-center justify-center py-12">
              <motion.div
                animate={{ rotate: 360 }}
                transition={{ duration: 1, repeat: Infinity, ease: 'linear' }}
                className="w-8 h-8 border-2 border-[#C41E3A] border-t-transparent rounded-full"
              />
            </div>
          )}
        </motion.div>
      ) : (
        <motion.div
          key="content"
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          exit={{ opacity: 0, y: -20 }}
          transition={{ duration: 0.4, ease: [0.16, 1, 0.3, 1] }}
          className={className}
        >
          {children}
        </motion.div>
      )}
    </AnimatePresence>
  );
}

interface SkeletonLoaderProps {
  className?: string;
  animate?: boolean;
}

export function SkeletonLoader({ className = '', animate = true }: SkeletonLoaderProps) {
  return (
    <div
      className={`
        bg-[#F5F5F5] rounded-lg
        ${animate ? 'animate-pulse' : ''}
        ${className}
      `}
    />
  );
}

interface CardSkeletonProps {
  count?: number;
  className?: string;
}

export function CardSkeleton({ count = 1, className = '' }: CardSkeletonProps) {
  return (
    <div className={className}>
      {Array.from({ length: count }).map((_, index) => (
        <div key={index} className="bg-white border border-[#E5E5E5] rounded-xl p-6 space-y-4">
          <SkeletonLoader className="h-4 w-3/4" />
          <SkeletonLoader className="h-4 w-1/2" />
          <SkeletonLoader className="h-20 w-full" />
          <div className="flex gap-2">
            <SkeletonLoader className="h-8 w-20" />
            <SkeletonLoader className="h-8 w-20" />
          </div>
        </div>
      ))}
    </div>
  );
}
