import { createContext, useContext, useState, useCallback, useRef } from 'react';
import type { ReactNode } from 'react';
import { X, CheckCircle, AlertCircle, AlertTriangle, Info } from 'lucide-react';

// Types
type ToastType = 'success' | 'error' | 'warning' | 'info';

interface Toast {
  id: string;
  type: ToastType;
  message: ReactNode;
  duration?: number;
  onClose?: () => void;
}

interface ToastContextValue {
  showToast: (message: ReactNode, type?: ToastType, duration?: number, onClose?: () => void) => string;
  success: (message: ReactNode, duration?: number, onClose?: () => void) => string;
  error: (message: ReactNode, duration?: number, onClose?: () => void) => string;
  warning: (message: ReactNode, duration?: number, onClose?: () => void) => string;
  info: (message: ReactNode, duration?: number, onClose?: () => void) => string;
  removeToast: (id: string) => void;
}

// Context
const ToastContext = createContext<ToastContextValue | null>(null);

// Hook
export function useToast() {
  const context = useContext(ToastContext);
  if (!context) {
    throw new Error('useToast must be used within a ToastProvider');
  }
  return context;
}

// Icons map
const icons = {
  success: <CheckCircle size={20} className="text-green-400" />,
  error: <AlertCircle size={20} className="text-red-400" />,
  warning: <AlertTriangle size={20} className="text-amber-400" />,
  info: <Info size={20} className="text-blue-400" />,
};

// Styles map
const styles = {
  success: 'border-green-500/20 bg-green-900/90 text-green-100',
  error: 'border-red-500/20 bg-red-900/90 text-red-100',
  warning: 'border-amber-500/20 bg-amber-900/90 text-amber-100',
  info: 'border-blue-500/20 bg-blue-900/90 text-blue-100',
};

// Provider Component
export function ToastProvider({ children }: { children: React.ReactNode }) {
  const [toasts, setToasts] = useState<Toast[]>([]);
  const timersRef = useRef<Map<string, number>>(new Map());

  const removeToast = useCallback((id: string) => {
    setToasts((prev) => {
      const toast = prev.find(t => t.id === id);
      if (toast && toast.onClose) {
        toast.onClose();
      }
      return prev.filter((t) => t.id !== id);
    });
    if (timersRef.current.has(id)) {
      clearTimeout(timersRef.current.get(id));
      timersRef.current.delete(id);
    }
  }, []);

  const showToast = useCallback((message: ReactNode, type: ToastType = 'info', duration = 3000, onClose?: () => void) => {
    const id = Math.random().toString(36).substring(2, 9);
    const newToast: Toast = { id, type, message, duration, onClose };

    setToasts((prev) => [...prev, newToast]);

    if (duration > 0) {
      const timer = window.setTimeout(() => {
        removeToast(id);
      }, duration);
      timersRef.current.set(id, timer);
    }
    
    return id;
  }, [removeToast]);

  // Convenience methods
  const success = useCallback((msg: ReactNode, d?: number, onClose?: () => void) => showToast(msg, 'success', d, onClose), [showToast]);
  const error = useCallback((msg: ReactNode, d = 3000, onClose?: () => void) => showToast(msg, 'error', d, onClose), [showToast]);
  const warning = useCallback((msg: ReactNode, d = 3000, onClose?: () => void) => showToast(msg, 'warning', d, onClose), [showToast]);
  const info = useCallback((msg: ReactNode, d?: number, onClose?: () => void) => showToast(msg, 'info', d, onClose), [showToast]);

  return (
    <ToastContext.Provider value={{ showToast, success, error, warning, info, removeToast }}>
      {children}
      
      {/* Toast Container - Top Right */}
      <div className="fixed top-24 right-6 z-[100] flex flex-col gap-3 pointer-events-none">
        {toasts.map((toast) => (
          <div
            key={toast.id}
            className={`
              pointer-events-auto
              flex items-start gap-3 px-4 py-3 rounded-xl border shadow-xl backdrop-blur-md
              min-w-[300px] max-w-sm
              animate-in slide-in-from-right-8 fade-in duration-300
              ${styles[toast.type]}
            `}
          >
            <div className="mt-0.5 shrink-0">{icons[toast.type]}</div>
            <div className="flex-1 text-sm font-medium leading-tight pt-0.5">{toast.message}</div>
            <button
              onClick={() => removeToast(toast.id)}
              className="text-white/40 hover:text-white transition-colors shrink-0"
            >
              <X size={16} />
            </button>
          </div>
        ))}
      </div>
    </ToastContext.Provider>
  );
}
