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

type ToastType = 'success' | 'error' | 'warning' | 'info'

interface Toast {
    id: string
    type: ToastType
    message: string
    duration?: number
}

interface ToastContextValue {
    toasts: Toast[]
    addToast: (type: ToastType, message: string, duration?: number) => void
    removeToast: (id: string) => void
    success: (message: string) => void
    error: (message: string) => void
    warning: (message: string) => void
    info: (message: string) => void
}

const ToastContext = createContext<ToastContextValue | null>(null)

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

interface ToastProviderProps {
    children: ReactNode
}

export function ToastProvider({ children }: ToastProviderProps) {
    const [toasts, setToasts] = useState<Toast[]>([])

    const removeToast = useCallback((id: string) => {
        setToasts((prev) => prev.filter((t) => t.id !== id))
    }, [])

    const addToast = useCallback(
        (type: ToastType, message: string, duration = 3000) => {
            const id = Math.random().toString(36).substring(2, 9)
            const toast: Toast = { id, type, message, duration }
            setToasts((prev) => [...prev, toast])

            if (duration > 0) {
                setTimeout(() => removeToast(id), duration)
            }
        },
        [removeToast]
    )

    const success = useCallback((message: string) => addToast('success', message), [addToast])
    const error = useCallback((message: string) => addToast('error', message), [addToast])
    const warning = useCallback((message: string) => addToast('warning', message), [addToast])
    const info = useCallback((message: string) => addToast('info', message), [addToast])

    return (
        <ToastContext.Provider
            value={{ toasts, addToast, removeToast, success, error, warning, info }}
        >
            {children}
            <ToastContainer toasts={toasts} onRemove={removeToast} />
        </ToastContext.Provider>
    )
}

interface ToastContainerProps {
    toasts: Toast[]
    onRemove: (id: string) => void
}

function ToastContainer({ toasts, onRemove }: ToastContainerProps) {
    if (toasts.length === 0) return null

    return (
        <div className="fixed bottom-6 right-6 z-[9999] space-y-3">
            {toasts.map((toast) => (
                <ToastItem key={toast.id} toast={toast} onRemove={onRemove} />
            ))}
        </div>
    )
}

interface ToastItemProps {
    toast: Toast
    onRemove: (id: string) => void
}

const typeStyles: Record<ToastType, { bg: string; icon: typeof CheckCircle }> = {
    success: {
        bg: 'bg-green-50 dark:bg-green-900/30 border-green-200 dark:border-green-800',
        icon: CheckCircle,
    },
    error: {
        bg: 'bg-red-50 dark:bg-red-900/30 border-red-200 dark:border-red-800',
        icon: XCircle,
    },
    warning: {
        bg: 'bg-yellow-50 dark:bg-yellow-900/30 border-yellow-200 dark:border-yellow-800',
        icon: AlertTriangle,
    },
    info: {
        bg: 'bg-blue-50 dark:bg-blue-900/30 border-blue-200 dark:border-blue-800',
        icon: Info,
    },
}

const iconColors: Record<ToastType, string> = {
    success: 'text-green-500',
    error: 'text-red-500',
    warning: 'text-yellow-500',
    info: 'text-blue-500',
}

function ToastItem({ toast, onRemove }: ToastItemProps) {
    const { bg, icon: Icon } = typeStyles[toast.type]
    const iconColor = iconColors[toast.type]

    return (
        <div
            className={`flex items-center gap-3 px-4 py-3 rounded-xl border shadow-lg animate-fadeIn min-w-[300px] max-w-md ${bg}`}
        >
            <Icon className={`h-5 w-5 flex-shrink-0 ${iconColor}`} />
            <p className="flex-1 text-sm font-medium text-slate-900 dark:text-slate-100">
                {toast.message}
            </p>
            <button
                onClick={() => onRemove(toast.id)}
                className="p-1 rounded-lg hover:bg-black/5 dark:hover:bg-white/5 transition-colors"
                aria-label="关闭"
            >
                <X className="h-4 w-4 text-slate-400" />
            </button>
        </div>
    )
}
