'use client';

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

export type MessageType = 'success' | 'error' | 'warning' | 'info' | 'loading';

export interface MessageNotificationProps {
  message: string;
  type?: MessageType;
  duration?: number;
  onClose?: () => void;
  title?: string;
  position?: 'top-left' | 'top-right' | 'top-center' | 'bottom-left' | 'bottom-right' | 'bottom-center';
  showProgress?: boolean;
  closable?: boolean;
  action?: {
    label: string;
    onClick: () => void;
  };
}

interface Message extends MessageNotificationProps {
  id: string;
  createdAt: number;
}

export function MessageNotification({ 
  message, 
  type = 'info', 
  duration = 3000, 
  onClose, 
  title,
  position = 'top-right',
  showProgress = true,
  closable = true,
  action
}: MessageNotificationProps) {
  const [isVisible, setIsVisible] = useState(true);
  const [remainingTime, setRemainingTime] = useState(duration);

  useEffect(() => {
    if (duration > 0 && type !== 'loading') {
      const timer = setTimeout(() => {
        setIsVisible(false);
        onClose?.();
      }, duration);

      // 进度条更新
      const progressTimer = setInterval(() => {
        setRemainingTime(prev => {
          const newTime = prev - 100;
          if (newTime <= 0) {
            clearInterval(progressTimer);
          }
          return newTime;
        });
      }, 100);

      return () => {
        clearTimeout(timer);
        clearInterval(progressTimer);
      };
    }
  }, [duration, onClose, type]);

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

  const getIcon = () => {
    const iconClass = "w-5 h-5";
    switch (type) {
      case 'error':
        return <XCircleIcon className={iconClass} />;
      case 'warning':
        return <ExclamationTriangleIcon className={iconClass} />;
      case 'success':
        return <CheckCircleIcon className={iconClass} />;
      case 'loading':
        return (
          <div className="animate-spin">
            <svg className={iconClass} viewBox="0 0 24 24" fill="none">
              <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
              <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
            </svg>
          </div>
        );
      case 'info':
      default:
        return <InformationCircleIcon className={iconClass} />;
    }
  };

  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',
          action: 'bg-red-500 hover:bg-red-600 text-white'
        };
      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',
          action: 'bg-yellow-500 hover:bg-yellow-600 text-white'
        };
      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',
          action: 'bg-green-500 hover:bg-green-600 text-white'
        };
      case 'loading':
        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',
          action: 'bg-blue-500 hover:bg-blue-600 text-white'
        };
      case 'info':
      default:
        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',
          action: 'bg-blue-500 hover:bg-blue-600 text-white'
        };
    }
  };

  const getPositionStyles = () => {
    switch (position) {
      case 'top-left':
        return 'top-4 left-4';
      case 'top-center':
        return 'top-4 left-1/2 -translate-x-1/2';
      case 'top-right':
        return 'top-4 right-4';
      case 'bottom-left':
        return 'bottom-4 left-4';
      case 'bottom-center':
        return 'bottom-4 left-1/2 -translate-x-1/2';
      case 'bottom-right':
        return 'bottom-4 right-4';
      default:
        return 'top-4 right-4';
    }
  };

  const styles = getStyles();
  const positionStyles = getPositionStyles();
  const progressPercentage = duration > 0 ? (remainingTime / duration) * 100 : 0;

  return (
    <AnimatePresence>
      {isVisible && (
        <motion.div
          initial={{ opacity: 0, y: -20, scale: 0.9 }}
          animate={{ opacity: 1, y: 0, scale: 1 }}
          exit={{ opacity: 0, y: -20, scale: 0.9 }}
          transition={{ duration: 0.3, ease: 'easeOut' }}
          className={`fixed z-[9999] max-w-sm w-full ${positionStyles}`}
        >
          <div className={`${styles.bg} ${styles.border} border rounded-xl shadow-lg backdrop-blur-sm overflow-hidden`}>
            <div className="flex items-start p-4">
              <div className={`flex-shrink-0 ${styles.icon} mr-3 mt-0.5`}>
                {getIcon()}
              </div>
              <div className="flex-1 min-w-0">
                {title && (
                  <h4 className={`text-sm font-semibold ${styles.text} mb-1`}>
                    {title}
                  </h4>
                )}
                <p className={`text-sm ${styles.text}`}>
                  {message}
                </p>
                {action && (
                  <button
                    onClick={action.onClick}
                    className={`mt-2 px-3 py-1 text-xs font-medium rounded-md transition-colors ${styles.action}`}
                  >
                    {action.label}
                  </button>
                )}
              </div>
              {closable && (
                <button
                  onClick={handleClose}
                  className={`flex-shrink-0 ml-3 ${styles.close} transition-colors`}
                >
                  <XMarkIcon className="w-4 h-4" />
                </button>
              )}
            </div>
            {showProgress && duration > 0 && type !== 'loading' && (
              <div className="h-1 bg-gray-200 dark:bg-gray-700 overflow-hidden">
                <motion.div
                  className={`h-full ${styles.progress}`}
                  initial={{ width: '100%' }}
                  animate={{ width: `${progressPercentage}%` }}
                  transition={{ duration: 0.1, ease: 'linear' }}
                />
              </div>
            )}
          </div>
        </motion.div>
      )}
    </AnimatePresence>
  );
}

// 全局消息管理器
class MessageManager {
  private static instance: MessageManager;
  private listeners: Array<(message: Message) => void> = [];

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

  // 基础消息方法
  show(message: string, options?: Omit<MessageNotificationProps, 'message'>) {
    return this.addMessage(message, 'info', options);
  }

  success(message: string, options?: Omit<MessageNotificationProps, 'message'>) {
    return this.addMessage(message, 'success', options);
  }

  error(message: string, options?: Omit<MessageNotificationProps, 'message'>) {
    return this.addMessage(message, 'error', options);
  }

  warning(message: string, options?: Omit<MessageNotificationProps, 'message'>) {
    return this.addMessage(message, 'warning', options);
  }

  info(message: string, options?: Omit<MessageNotificationProps, 'message'>) {
    return this.addMessage(message, 'info', options);
  }

  loading(message: string, options?: Omit<MessageNotificationProps, 'message'>) {
    return this.addMessage(message, 'loading', { ...options, duration: 0 });
  }

  // 隐藏加载消息
  hideLoading(id?: string) {
    if (id) {
      this.listeners.forEach(listener => listener({ id, message: '', type: 'loading', createdAt: Date.now() } as Message));
    }
  }

  private addMessage(message: string, type: MessageType, options?: Omit<MessageNotificationProps, 'message'>) {
    const id = Math.random().toString(36).substr(2, 9);
    const notification: Message = {
      id,
      message,
      type,
      createdAt: Date.now(),
      ...options
    };

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

  subscribe(listener: (message: Message) => void) {
    this.listeners.push(listener);
    return () => {
      this.listeners = this.listeners.filter(l => l !== listener);
    };
  }
}

export const messageManager = MessageManager.getInstance();

// 消息提示容器组件
export function MessageNotificationContainer() {
  const [messages, setMessages] = useState<Message[]>([]);

  useEffect(() => {
    const unsubscribe = messageManager.subscribe((message) => {
      if (message.type === 'loading' && message.message === '') {
        // 隐藏加载消息
        setMessages(prev => prev.filter(m => m.id !== message.id));
      } else {
        setMessages(prev => [...prev, message]);
      }
    });

    return unsubscribe;
  }, []);

  const removeMessage = (id: string) => {
    setMessages(prev => prev.filter(m => m.id !== id));
  };

  // 按位置分组消息
  const messagesByPosition = messages.reduce((acc, message) => {
    const position = message.position || 'top-right';
    if (!acc[position]) {
      acc[position] = [];
    }
    acc[position].push(message);
    return acc;
  }, {} as Record<string, Message[]>);

  return (
    <>
      {Object.entries(messagesByPosition).map(([position, positionMessages]) => (
        <div key={position} className="fixed inset-0 pointer-events-none z-[9999]">
          <div className={`absolute ${getPositionContainerStyles(position)} space-y-2 pointer-events-auto`}>
            {positionMessages.map((message) => (
              <MessageNotification
                key={message.id}
                {...message}
                onClose={() => removeMessage(message.id)}
              />
            ))}
          </div>
        </div>
      ))}
    </>
  );
}

function getPositionContainerStyles(position: string) {
  switch (position) {
    case 'top-left':
      return 'top-4 left-4';
    case 'top-center':
      return 'top-4 left-1/2 -translate-x-1/2';
    case 'top-right':
      return 'top-4 right-4';
    case 'bottom-left':
      return 'bottom-4 left-4';
    case 'bottom-center':
      return 'bottom-4 left-1/2 -translate-x-1/2';
    case 'bottom-right':
      return 'bottom-4 right-4';
    default:
      return 'top-4 right-4';
  }
}

// 兼容层：保持与ErrorNotification的兼容性
export { errorManager } from './ErrorNotification';
export type { ErrorType } from './ErrorNotification';
