import React, { useState, useEffect, useRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';

interface TypewriterEffectProps {
  /**
   * Text or array of texts to display in typewriter effect
   */
  text: string | string[];
  /**
   * Typing speed in milliseconds per character
   */
  typingSpeed?: number;
  /**
   * Deleting speed in milliseconds per character
   */
  deletingSpeed?: number;
  /**
   * Delay before starting to delete text in milliseconds
   */
  delayBeforeDelete?: number;
  /**
   * Delay before typing the next text in milliseconds
   */
  delayBeforeTyping?: number;
  /**
   * Whether to loop through the texts indefinitely
   */
  loop?: boolean;
  /**
   * CSS class name for the cursor
   */
  cursorClassName?: string;
  /**
   * CSS class name for the text container
   */
  className?: string;
  /**
   * Whether to show the cursor
   */
  showCursor?: boolean;
}

/**
 * TypewriterEffect component that creates a typewriter animation effect
 * for a single text or cycles through an array of texts
 */
const TypewriterEffect: React.FC<TypewriterEffectProps> = ({
  text,
  typingSpeed = 100,
  deletingSpeed = 50,
  delayBeforeDelete = 2000,
  delayBeforeTyping = 700,
  loop = true,
  cursorClassName = 'text-primary',
  className = '',
  showCursor = true,
}) => {
  // Convert single string to array for consistent handling
  const textArray = Array.isArray(text) ? text : [text];
  const [currentTextIndex, setCurrentTextIndex] = useState(0);
  const [displayedText, setDisplayedText] = useState('');
  const [isTyping, setIsTyping] = useState(true);
  const [isDeleting, setIsDeleting] = useState(false);
  const [isPaused, setIsPaused] = useState(false);
  
  // Use a ref to track if component is mounted
  const isMounted = useRef(true);

  useEffect(() => {
    // Cleanup function to prevent state updates after unmount
    return () => {
      isMounted.current = false;
    };
  }, []);

  useEffect(() => {
    if (!isMounted.current) return;
    
    const currentFullText = textArray[currentTextIndex];
    
    // Handle typing state
    if (isTyping && !isPaused) {
      if (displayedText.length < currentFullText.length) {
        // Continue typing
        const timeoutId = setTimeout(() => {
          if (isMounted.current) {
            setDisplayedText(currentFullText.substring(0, displayedText.length + 1));
          }
        }, typingSpeed);
        return () => clearTimeout(timeoutId);
      } else {
        // Finished typing, pause before deleting
        setIsTyping(false);
        setIsPaused(true);
        const timeoutId = setTimeout(() => {
          if (isMounted.current) {
            setIsPaused(false);
            setIsDeleting(true);
          }
        }, delayBeforeDelete);
        return () => clearTimeout(timeoutId);
      }
    }
    
    // Handle deleting state
    if (isDeleting && !isPaused) {
      if (displayedText.length > 0) {
        // Continue deleting
        const timeoutId = setTimeout(() => {
          if (isMounted.current) {
            setDisplayedText(displayedText.substring(0, displayedText.length - 1));
          }
        }, deletingSpeed);
        return () => clearTimeout(timeoutId);
      } else {
        // Finished deleting, move to next text
        setIsDeleting(false);
        setIsPaused(true);
        
        const timeoutId = setTimeout(() => {
          if (isMounted.current) {
            // 无条件进入下一个文本，确保循环总是继续
            const nextIndex = (currentTextIndex + 1) % textArray.length;
            setCurrentTextIndex(nextIndex);
            setIsPaused(false);
            setIsTyping(true);
          }
        }, delayBeforeTyping);
        return () => clearTimeout(timeoutId);
      }
    }
  }, [displayedText, isTyping, isDeleting, isPaused, currentTextIndex, textArray, typingSpeed, deletingSpeed, delayBeforeDelete, delayBeforeTyping]);

  return (
    <span className={`${className} relative`}>
      {/* 直接显示文本，不使用 AnimatePresence 包装整个文本 */}
      <span className="font-medium">
        {displayedText}
      </span>
      {showCursor && (
        <motion.span
          className={`${cursorClassName} font-bold text-xl ml-1`}
          animate={{ opacity: [1, 0, 1] }}
          transition={{ 
            opacity: { duration: 0.8, repeat: Infinity, repeatType: 'loop' }
          }}
        >
          |
        </motion.span>
      )}
    </span>
  );
};

export default TypewriterEffect;