'use client';

import { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { XMarkIcon, ExclamationTriangleIcon, CheckCircleIcon, InformationCircleIcon } from '@heroicons/react/24/outline';

export type ErrorType = 'error' | 'warning' | 'success' | 'info';

interface ErrorNotificationProps {
  message: string;
  type?: ErrorType;
  duration?: number;
  onClose?: () => void;
}

export function ErrorNotification({ message, type = 'error', duration = 5000, onClose }: ErrorNotificationProps) {
  const [isVisible, setIsVisible] = useState(true);
  const [isHovered, setIsHovered] = useState(false);
  const [progress, setProgress] = useState(100);

  useEffect(() => {
    if (duration > 0 && !isHovered) {
      const startTime = Date.now();
      const timer = setInterval(() => {
        const elapsed = Date.now() - startTime;
        const remaining = Math.max(0, duration - elapsed);
        setProgress((remaining / duration) * 100);
        
        if (remaining === 0) {
          setIsVisible(false);
          onClose?.();
        }
      }, 50);
      
      return () => clearInterval(timer);
    }
  }, [duration, onClose, isHovered]);

  const handleClose = () => {
    setIsVisible(false);
    onClose?.();
  };

  const getIcon = () => {
    switch (type) {
      case 'error':
        return <ExclamationTriangleIcon className="w-5 h-5" />;
      case 'warning':
        return <ExclamationTriangleIcon className="w-5 h-5" />;
      case 'success':
        return <CheckCircleIcon className="w-5 h-5" />;
      case 'info':
        return <InformationCircleIcon className="w-5 h-5" />;
    }
  };

  const getStyles = () => {
    switch (type) {
      case 'error':
        return {
          bg: 'bg-red-50 dark:bg-red-900/20',
          border: 'border-red-200 dark:border-red-800',
          text: 'text-red-800 dark:text-red-200',
          icon: 'text-red-500',
          close: 'text-red-400 hover:text-red-600 dark:text-red-300 dark:hover:text-red-100',
          progress: 'bg-red-500'
        };
      case 'warning':
        return {
          bg: 'bg-yellow-50 dark:bg-yellow-900/20',
          border: 'border-yellow-200 dark:border-yellow-800',
          text: 'text-yellow-800 dark:text-yellow-200',
          icon: 'text-yellow-500',
          close: 'text-yellow-400 hover:text-yellow-600 dark:text-yellow-300 dark:hover:text-yellow-100',
          progress: 'bg-yellow-500'
        };
      case 'success':
        return {
          bg: 'bg-green-50 dark:bg-green-900/20',
          border: 'border-green-200 dark:border-green-800',
          text: 'text-green-800 dark:text-green-200',
          icon: 'text-green-500',
          close: 'text-green-400 hover:text-green-600 dark:text-green-300 dark:hover:text-green-100',
          progress: 'bg-green-500'
        };
      case 'info':
        return {
          bg: 'bg-blue-50 dark:bg-blue-900/20',
          border: 'border-blue-200 dark:border-blue-800',
          text: 'text-blue-800 dark:text-blue-200',
          icon: 'text-blue-500',
          close: 'text-blue-400 hover:text-blue-600 dark:text-blue-300 dark:hover:text-blue-100',
          progress: 'bg-blue-500'
        };
    }
  };

  const styles = getStyles();

  const getAnimationVariants = () => {
    switch (type) {
      case 'error':
        return {
          initial: { opacity: 0, x: 100, scale: 0.8, rotate: -5 },
          animate: { opacity: 1, x: 0, scale: 1, rotate: 0 },
          exit: { opacity: 0, x: 100, scale: 0.8, rotate: 5 },
        };
      case 'warning':
        return {
          initial: { opacity: 0, y: -20, scale: 0.9 },
          animate: { opacity: 1, y: 0, scale: 1 },
          exit: { opacity: 0, y: -20, scale: 0.9 },
        };
      case 'success':
        return {
          initial: { opacity: 0, scale: 0.5 },
          animate: { opacity: 1, scale: 1 },
          exit: { opacity: 0, scale: 0.5 },
        };
      case 'info':
        return {
          initial: { opacity: 0, x: -20, scale: 0.9 },
          animate: { opacity: 1, x: 0, scale: 1 },
          exit: { opacity: 0, x: -20, scale: 0.9 },
        };
    }
  };

  return (
    <AnimatePresence>
      {isVisible && (
        <motion.div
          {...getAnimationVariants()}
          transition={{ 
            duration: 0.4, 
            ease: 'easeOut',
            type: 'spring',
            stiffness: 300,
            damping: 20
          }}
          className={`fixed top-4 right-4 z-[9999] max-w-lg w-full ${styles.bg} ${styles.border} border rounded-xl shadow-2xl backdrop-blur-lg overflow-hidden`}
          onMouseEnter={() => setIsHovered(true)}
          onMouseLeave={() => setIsHovered(false)}
          whileHover={{ scale: 1.02, y: -2 }}
        >
          {/* Progress bar */}
          <div className="absolute bottom-0 left-0 h-1 bg-gray-200/50 dark:bg-gray-700/50 w-full">
            <motion.div
              className={`h-full ${styles.progress}`}
              initial={{ width: '100%' }}
              animate={{ width: `${progress}%` }}
              transition={{ duration: 0.1, ease: 'linear' }}
            />
          </div>
          
          <div className="flex items-start p-4">
            <motion.div 
              className={`flex-shrink-0 ${styles.icon} mr-3 mt-0.5`}
              animate={{ 
                scale: type === 'error' ? [1, 1.1, 1] : 1,
                rotate: type === 'warning' ? [0, -5, 5, 0] : 0
              }}
              transition={{ 
                duration: type === 'error' ? 0.5 : 0.3,
                repeat: type === 'error' ? Infinity : 0,
                repeatDelay: 2
              }}
            >
              {getIcon()}
            </motion.div>
            <div className="flex-1">
              <p className={`text-sm font-medium ${styles.text} leading-relaxed`}>
                {message}
              </p>
            </div>
            <motion.button
              onClick={handleClose}
              className={`flex-shrink-0 ml-3 ${styles.close} transition-all duration-200 p-1 rounded-full hover:bg-white/20 dark:hover:bg-black/20`}
              whileHover={{ scale: 1.1, rotate: 90 }}
              whileTap={{ scale: 0.9 }}
            >
              <XMarkIcon className="w-5 h-5" />
            </motion.button>
          </div>
        </motion.div>
      )}
    </AnimatePresence>
  );
}

// 增强的全局错误管理器
class ErrorManager {
  private static instance: ErrorManager;
  private listeners: Array<(notification: ErrorNotificationProps & { id: string }) => void> = [];
  private soundEnabled: boolean = true;

  static getInstance(): ErrorManager {
    if (!ErrorManager.instance) {
      ErrorManager.instance = new ErrorManager();
    }
    return ErrorManager.instance;
  }

  private playSound(type: ErrorType) {
    if (!this.soundEnabled) return;
    
    // 创建音频反馈
    const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();
    const oscillator = audioContext.createOscillator();
    const gainNode = audioContext.createGain();
    
    oscillator.connect(gainNode);
    gainNode.connect(audioContext.destination);
    
    const frequencies = {
      error: 300,
      warning: 400,
      success: 600,
      info: 500
    };
    
    oscillator.frequency.setValueAtTime(frequencies[type], audioContext.currentTime);
    oscillator.type = type === 'error' ? 'sawtooth' : 'sine';
    
    gainNode.gain.setValueAtTime(0.1, audioContext.currentTime);
    gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.3);
    
    oscillator.start(audioContext.currentTime);
    oscillator.stop(audioContext.currentTime + 0.3);
  }

  showError(message: string, duration?: number) {
    this.playSound('error');
    this.showNotification(message, 'error', duration);
  }

  showWarning(message: string, duration?: number) {
    this.playSound('warning');
    this.showNotification(message, 'warning', duration);
  }

  showSuccess(message: string, duration?: number) {
    this.playSound('success');
    this.showNotification(message, 'success', duration);
  }

  showInfo(message: string, duration?: number) {
    this.playSound('info');
    this.showNotification(message, 'info', duration);
  }

  private showNotification(message: string, type: ErrorType, duration?: number) {
    const notification = {
      id: Math.random().toString(36).substr(2, 9),
      message,
      type,
      duration: duration ?? (type === 'error' ? 5000 : 3000)
    };

    this.listeners.forEach(listener => listener(notification));
  }

  subscribe(listener: (notification: ErrorNotificationProps & { id: string }) => void) {
    this.listeners.push(listener);
    return () => {
      this.listeners = this.listeners.filter(l => l !== listener);
    };
  }

  setSoundEnabled(enabled: boolean) {
    this.soundEnabled = enabled;
  }
}

export const errorManager = ErrorManager.getInstance();

// 增强的错误提示容器组件
export function ErrorNotificationContainer() {
  const [notifications, setNotifications] = useState<Array<ErrorNotificationProps & { id: string }>>([]);
  const [soundEnabled, setSoundEnabled] = useState(true);

  useEffect(() => {
    const unsubscribe = errorManager.subscribe((notification) => {
      setNotifications(prev => [...prev, notification]);
    });

    return unsubscribe;
  }, []);

  useEffect(() => {
    errorManager.setSoundEnabled(soundEnabled);
  }, [soundEnabled]);

  const removeNotification = (id: string) => {
    setNotifications(prev => prev.filter(n => n.id !== id));
  };

  return (
    <>
      {notifications.map((notification, index) => (
        <motion.div
          key={notification.id}
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: index * 0.1 }}
        >
          <ErrorNotification
            {...notification}
            onClose={() => removeNotification(notification.id)}
          />
        </motion.div>
      ))}
    </>
  );
}

