import { ReactNode, useEffect, useState } from 'react';

/**
 * Fade in animation wrapper
 */
export function FadeIn({
  children,
  delay = 0,
  duration = 300,
  className = '',
}: {
  children: ReactNode;
  delay?: number;
  duration?: number;
  className?: string;
}) {
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => setVisible(true), delay);
    return () => clearTimeout(timer);
  }, [delay]);

  return (
    <div
      className={className}
      style={{
        opacity: visible ? 1 : 0,
        transition: `opacity ${duration}ms ease-in-out`,
      }}
    >
      {children}
    </div>
  );
}

/**
 * Slide in from direction
 */
export function SlideIn({
  children,
  direction = 'left',
  delay = 0,
  duration = 300,
  distance = 20,
  className = '',
}: {
  children: ReactNode;
  direction?: 'left' | 'right' | 'up' | 'down';
  delay?: number;
  duration?: number;
  distance?: number;
  className?: string;
}) {
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => setVisible(true), delay);
    return () => clearTimeout(timer);
  }, [delay]);

  const transforms = {
    left: `translateX(${visible ? 0 : -distance}px)`,
    right: `translateX(${visible ? 0 : distance}px)`,
    up: `translateY(${visible ? 0 : -distance}px)`,
    down: `translateY(${visible ? 0 : distance}px)`,
  };

  return (
    <div
      className={className}
      style={{
        opacity: visible ? 1 : 0,
        transform: transforms[direction],
        transition: `all ${duration}ms ease-out`,
      }}
    >
      {children}
    </div>
  );
}

/**
 * Scale in animation
 */
export function ScaleIn({
  children,
  delay = 0,
  duration = 200,
  className = '',
}: {
  children: ReactNode;
  delay?: number;
  duration?: number;
  className?: string;
}) {
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => setVisible(true), delay);
    return () => clearTimeout(timer);
  }, [delay]);

  return (
    <div
      className={className}
      style={{
        opacity: visible ? 1 : 0,
        transform: `scale(${visible ? 1 : 0.95})`,
        transition: `all ${duration}ms ease-out`,
      }}
    >
      {children}
    </div>
  );
}

/**
 * Stagger children animations
 */
export function StaggerChildren({
  children,
  staggerDelay = 50,
  initialDelay = 0,
  className = '',
}: {
  children: ReactNode[];
  staggerDelay?: number;
  initialDelay?: number;
  className?: string;
}) {
  return (
    <div className={className}>
      {children.map((child, index) => (
        <FadeIn key={index} delay={initialDelay + index * staggerDelay}>
          {child}
        </FadeIn>
      ))}
    </div>
  );
}

/**
 * Pulse animation (for attention)
 */
export function Pulse({
  children,
  className = '',
}: {
  children: ReactNode;
  className?: string;
}) {
  return (
    <div className={`animate-pulse ${className}`}>
      {children}
    </div>
  );
}

/**
 * Bounce animation
 */
export function Bounce({
  children,
  className = '',
}: {
  children: ReactNode;
  className?: string;
}) {
  return (
    <div className={`animate-bounce ${className}`}>
      {children}
    </div>
  );
}

/**
 * Number counter animation
 */
export function CountUp({
  end,
  start = 0,
  duration = 1000,
  decimals = 0,
  prefix = '',
  suffix = '',
  className = '',
}: {
  end: number;
  start?: number;
  duration?: number;
  decimals?: number;
  prefix?: string;
  suffix?: string;
  className?: string;
}) {
  const [count, setCount] = useState(start);

  useEffect(() => {
    const startTime = Date.now();
    const diff = end - start;

    const animate = () => {
      const elapsed = Date.now() - startTime;
      const progress = Math.min(elapsed / duration, 1);

      // Ease out cubic
      const eased = 1 - Math.pow(1 - progress, 3);
      const current = start + diff * eased;

      setCount(current);

      if (progress < 1) {
        requestAnimationFrame(animate);
      }
    };

    requestAnimationFrame(animate);
  }, [end, start, duration]);

  return (
    <span className={className}>
      {prefix}
      {count.toFixed(decimals)}
      {suffix}
    </span>
  );
}

/**
 * Typing animation for text
 */
export function TypeWriter({
  text,
  speed = 50,
  delay = 0,
  className = '',
  onComplete,
}: {
  text: string;
  speed?: number;
  delay?: number;
  className?: string;
  onComplete?: () => void;
}) {
  const [displayed, setDisplayed] = useState('');

  useEffect(() => {
    let index = 0;
    const timer = setTimeout(() => {
      const interval = setInterval(() => {
        setDisplayed(text.slice(0, index + 1));
        index++;
        if (index >= text.length) {
          clearInterval(interval);
          onComplete?.();
        }
      }, speed);
      return () => clearInterval(interval);
    }, delay);
    return () => clearTimeout(timer);
  }, [text, speed, delay, onComplete]);

  return (
    <span className={className}>
      {displayed}
      <span className="animate-pulse">|</span>
    </span>
  );
}
