import { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'motion/react';

interface HandwrittenTextProps {
  text: string;
  className?: string;
  style?: React.CSSProperties;
  speed?: number; // Characters per second
  startDelay?: number; // Delay before animation starts (ms)
  onComplete?: () => void;
  autoStart?: boolean;
}

export function HandwrittenText({ 
  text, 
  className = "", 
  style = {}, 
  speed = 8, 
  startDelay = 0,
  onComplete,
  autoStart = true
}: HandwrittenTextProps) {
  const [displayedText, setDisplayedText] = useState('');
  const [currentIndex, setCurrentIndex] = useState(0);
  const [isWriting, setIsWriting] = useState(false);
  const [showCursor, setShowCursor] = useState(false);

  // Split text into characters, preserving line breaks
  const characters = text.split('');

  useEffect(() => {
    if (!autoStart) return;

    const startTimer = setTimeout(() => {
      setIsWriting(true);
      setShowCursor(true);
    }, startDelay);

    return () => clearTimeout(startTimer);
  }, [autoStart, startDelay]);

  useEffect(() => {
    if (!isWriting || currentIndex >= characters.length) {
      if (currentIndex >= characters.length) {
        // Hide cursor after a delay
        const cursorTimer = setTimeout(() => {
          setShowCursor(false);
          setIsWriting(false);
          onComplete?.();
        }, 800);
        return () => clearTimeout(cursorTimer);
      }
      return;
    }

    const char = characters[currentIndex];
    const baseDelay = 1000 / speed;
    
    // Variable delays for more natural writing
    let delay = baseDelay;
    
    if (char === ' ') {
      delay = baseDelay * 0.5; // Spaces are quicker
    } else if (char === '\n') {
      delay = baseDelay * 2; // Line breaks take longer
    } else if (['.', '!', '?'].includes(char)) {
      delay = baseDelay * 1.5; // Punctuation takes a bit longer
    } else if ([',', ';', ':'].includes(char)) {
      delay = baseDelay * 1.2;
    } else {
      // Add some randomness to letter timing
      delay = baseDelay * (0.8 + Math.random() * 0.4);
    }

    const timer = setTimeout(() => {
      setDisplayedText(prev => prev + char);
      setCurrentIndex(prev => prev + 1);
    }, delay);

    return () => clearTimeout(timer);
  }, [isWriting, currentIndex, characters, speed, onComplete]);

  // Reset function for external control
  const reset = () => {
    setDisplayedText('');
    setCurrentIndex(0);
    setIsWriting(false);
    setShowCursor(false);
  };

  const start = () => {
    reset();
    setTimeout(() => {
      setIsWriting(true);
      setShowCursor(true);
    }, startDelay);
  };

  // Expose control methods
  useEffect(() => {
    if (typeof window !== 'undefined') {
      (window as any).handwrittenTextControls = { reset, start };
    }
  }, []);

  return (
    <div className={`relative w-fit h-fit inline-block ${className}`} style={style}>
      {/* Main text with character-by-character animation */}
      <motion.div
        className="relative"
        style={{ whiteSpace: 'pre-line' }}
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        transition={{ duration: 0.3 }}
      >
        {displayedText.split('').map((char, index) => (
          <motion.span
            key={`${index}-${char}`}
            initial={{ 
              opacity: 0, 
              scale: 0.8,
              y: 2
            }}
            animate={{ 
              opacity: 1, 
              scale: 1,
              y: 0
            }}
            transition={{
              duration: 0.2,
              ease: "easeOut",
              delay: 0
            }}
            style={{
              display: char === '\n' ? 'block' : 'inline',
              width: char === '\n' ? '100%' : 'auto',
              height: char === '\n' ? '0' : 'auto'
            }}
          >
            {char === '\n' ? '' : char}
          </motion.span>
        ))}
        
        {/* Writing cursor/pen effect */}
        <AnimatePresence>
          {showCursor && (
            <motion.span
              className="inline-block"
              initial={{ opacity: 0, scale: 0 }}
              animate={{ 
                opacity: [0.3, 1, 0.3],
                scale: [0.8, 1.1, 0.8],
                rotate: [0, 2, -2, 0]
              }}
              exit={{ opacity: 0, scale: 0 }}
              transition={{
                opacity: {
                  duration: 0.8,
                  repeat: Infinity,
                  ease: "easeInOut"
                },
                scale: {
                  duration: 0.8,
                  repeat: Infinity,
                  ease: "easeInOut"
                },
                rotate: {
                  duration: 1.2,
                  repeat: Infinity,
                  ease: "easeInOut"
                }
              }}
              style={{
                color: 'rgba(85, 70, 50, 0.6)',
                marginLeft: '1px'
              }}
            >
              |
            </motion.span>
          )}
        </AnimatePresence>
      </motion.div>

      {/* Ink flow effect */}
      <motion.div
        className="absolute inset-0 pointer-events-none"
        style={{
          background: `
            radial-gradient(ellipse at 20% 30%, rgba(85, 70, 50, 0.05) 0%, transparent 60%),
            radial-gradient(ellipse at 80% 70%, rgba(101, 84, 63, 0.04) 0%, transparent 50%)
          `,
          filter: 'blur(2px)',
          borderRadius: '4px'
        }}
        initial={{ opacity: 0 }}
        animate={{ opacity: isWriting ? 0.3 : 0 }}
        transition={{ duration: 0.5 }}
      />
    </div>
  );
}

// Hook for controlling the animation externally
export function useHandwrittenText(autoStart = true) {
  const [isComplete, setIsComplete] = useState(false);
  
  const reset = () => {
    setIsComplete(false);
    if (typeof window !== 'undefined' && (window as any).handwrittenTextControls) {
      (window as any).handwrittenTextControls.reset();
    }
  };

  const start = () => {
    setIsComplete(false);
    if (typeof window !== 'undefined' && (window as any).handwrittenTextControls) {
      (window as any).handwrittenTextControls.start();
    }
  };

  return {
    isComplete,
    reset,
    start,
    onComplete: () => setIsComplete(true)
  };
}