import { HTMLMotionProps, motion } from 'framer-motion';
import { forwardRef, ReactNode } from 'react';
import { cn } from '@web/src/utils/classname';
import { LoadingOutlined } from '@ant-design/icons';

export interface ButtonProps extends Omit<HTMLMotionProps<"button">, keyof React.ButtonHTMLAttributes<HTMLButtonElement>> {
    variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'success' | 'warning' | 'info' | 'light' | 'dark' |
    'soft-primary' | 'soft-secondary' | 'soft-danger' | 'soft-success' | 'soft-warning' | 'soft-info' |
    'ghost-primary' | 'ghost-secondary' | 'ghost-danger' | 'ghost-success' | 'ghost-warning' | 'ghost-info';
    size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'icon';
    isLoading?: boolean;
    leftIcon?: React.ReactNode;
    rightIcon?: React.ReactNode;
    fullWidth?: boolean;
    rounded?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
    elevation?: 'none' | 'sm' | 'md' | 'lg';
    glassmorphism?: boolean;
    animated?: boolean;
    className?: string;
    disabled?: boolean;
    children?: ReactNode;
    title?: string;
    onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
    onMouseEnter?: (event: React.MouseEvent<HTMLButtonElement>) => void;
    onMouseLeave?: (event: React.MouseEvent<HTMLButtonElement>) => void;
    onFocus?: (event: React.FocusEvent<HTMLButtonElement>) => void;
    onBlur?: (event: React.FocusEvent<HTMLButtonElement>) => void;
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
    (
        {
            className,
            variant = 'primary',
            size = 'md',
            isLoading = false,
            disabled,
            leftIcon,
            rightIcon,
            children,
            fullWidth,
            rounded = 'md',
            elevation = "none",
            glassmorphism = false,
            animated = true,
            title,
            ...props
        },
        ref
    ) => {
        const variants = {
            primary: 'bg-blue-600 text-white hover:bg-blue-700 disabled:bg-gray-400',
            secondary: 'bg-gray-600 text-white hover:bg-gray-700 disabled:bg-gray-400',
            outline: 'border-2 bg-transparent hover:bg-gray-50 ',
            ghost: 'bg-transparent hover:bg-gray-50 ',
            danger: 'bg-red-600 text-white hover:bg-red-700',
            success: 'bg-green-600 text-white hover:bg-green-700',
            warning: 'bg-yellow-600 text-white hover:bg-yellow-700',
            info: 'bg-cyan-600 text-white hover:bg-cyan-700',
            light: 'bg-white text-gray-900 hover:bg-gray-50 border border-gray-200',
            dark: 'bg-gray-900 text-white hover:bg-gray-800',
            'soft-primary': 'bg-blue-50 text-blue-600 hover:bg-blue-100 disabled:bg-gray-50 disabled:text-gray-400',
            'soft-secondary': 'bg-gray-50 text-gray-600 hover:bg-gray-100 disabled:bg-gray-50 disabled:text-gray-400',
            'soft-danger': 'bg-red-50 text-red-600 hover:bg-red-100 disabled:bg-gray-50 disabled:text-gray-400',
            'soft-success': 'bg-green-50 text-green-600 hover:bg-green-100 disabled:bg-gray-50 disabled:text-gray-400',
            'soft-warning': 'bg-yellow-50 text-yellow-600 hover:bg-yellow-100 disabled:bg-gray-50 disabled:text-gray-400',
            'soft-info': 'bg-cyan-50 text-cyan-600 hover:bg-cyan-100 disabled:bg-gray-50 disabled:text-gray-400',
            'ghost-primary': 'bg-transparent text-blue-600 hover:bg-blue-50',
            'ghost-secondary': 'bg-transparent text-gray-600 hover:bg-gray-50',
            'ghost-danger': 'bg-transparent text-red-600 hover:bg-red-50',
            'ghost-success': 'bg-transparent text-green-600 hover:bg-green-50',
            'ghost-warning': 'bg-transparent text-yellow-600 hover:bg-yellow-50',
            'ghost-info': 'bg-transparent text-cyan-600 hover:bg-cyan-50',
        };
        const borderColors = {
            primary: 'border-blue-600',
            secondary: 'border-gray-600',
            outline: 'border-gray-300 ',
            ghost: 'border-transparent',
            danger: 'border-red-600',
            success: 'border-green-600',
            warning: 'border-yellow-600',
            info: 'border-cyan-600',
            light: 'border-gray-200',
            dark: 'border-gray-900',
            'soft-primary': 'border-transparent',
            'soft-secondary': 'border-transparent',
            'soft-danger': 'border-transparent',
            'soft-success': 'border-transparent',
            'soft-warning': 'border-transparent',
            'soft-info': 'border-transparent',
            'ghost-primary': 'border-transparent',
            'ghost-secondary': 'border-transparent',
            'ghost-danger': 'border-transparent',
            'ghost-success': 'border-transparent',
            'ghost-warning': 'border-transparent',
            'ghost-info': 'border-transparent',
        };

        const ringColors = {
            primary: 'focus:ring-blue-500/50',
            secondary: 'focus:ring-gray-500/50',
            outline: 'focus:ring-gray-400/50',
            ghost: 'focus:ring-gray-400/50',
            danger: 'focus:ring-red-500/50',
            success: 'focus:ring-green-500/50',
            warning: 'focus:ring-yellow-500/50',
            info: 'focus:ring-cyan-500/50',
            light: 'focus:ring-gray-200/50',
            dark: 'focus:ring-gray-900/50',
            'soft-primary': 'focus:ring-blue-200/50',
            'soft-secondary': 'focus:ring-gray-200/50',
            'soft-danger': 'focus:ring-red-200/50',
            'soft-success': 'focus:ring-green-200/50',
            'soft-warning': 'focus:ring-yellow-200/50',
            'soft-info': 'focus:ring-cyan-200/50',
            'ghost-primary': 'focus:ring-blue-200/50',
            'ghost-secondary': 'focus:ring-gray-200/50',
            'ghost-danger': 'focus:ring-red-200/50',
            'ghost-success': 'focus:ring-green-200/50',
            'ghost-warning': 'focus:ring-yellow-200/50',
            'ghost-info': 'focus:ring-cyan-200/50',
        };
        const sizes = {
            xs: 'px-2.5 py-1.5 text-xs',
            sm: 'px-3 py-2 text-sm',
            md: 'px-4 py-2 text-base',
            lg: 'px-6 py-3 text-lg',
            xl: 'px-8 py-4 text-xl',
            icon: 'p-2',  // 修改为等边距的 padding
        };

        const iconSizes = {
            xs: 'h-3 w-3',
            sm: 'h-4 w-4',
            md: 'h-5 w-5',
            lg: 'h-6 w-6',
            xl: 'h-7 w-7',
            icon: 'h-4 w-4',
        };

        const roundedStyles = {
            none: 'rounded-none',
            sm: 'rounded-sm',
            md: 'rounded-md',
            lg: 'rounded-lg',
            xl: 'rounded-xl',
            full: 'rounded-full',
        };

        const elevationStyles = {
            none: '',
            sm: 'shadow-sm',
            md: 'shadow-md',
            lg: 'shadow-lg',
        };

        const isIconOnly = size === 'icon' || (!children && (leftIcon || rightIcon));

        return (
            <button
                ref={ref}
                title={title}
                disabled={disabled || isLoading}
                className={cn(
                    // Base styles
                    'relative inline-flex items-center justify-center font-medium',
                    'transition-all duration-200 ease-in-out',
                    'focus:outline-none focus:ring-2 focus:ring-offset-2',
                    'disabled:opacity-75 disabled:cursor-not-allowed',
                    // Variant styles
                    variants[variant],
                    borderColors[variant],
                    // Conditional styles
                    glassmorphism && 'backdrop-blur-sm bg-opacity-80',
                    // Ring color based on variant
                    ringColors[variant],
                    // Size and shape styles
                    isIconOnly ? sizes.icon : sizes[size],
                    roundedStyles[rounded],
                    elevationStyles[elevation],
                    // Full width
                    fullWidth && 'w-full',
                    className
                )}
                {...props}
            >
                {isLoading && (
                    <LoadingOutlined
                        className={cn(
                            "animate-spin",
                            !isIconOnly && "mr-2",
                            iconSizes[size]
                        )}
                        aria-hidden="true"
                    />
                )}
                {!isLoading && leftIcon && (
                    <span className={cn(
                        "inline-flex",
                        !isIconOnly && "mr-2",
                        iconSizes[size]
                    )}>
                        {leftIcon}
                    </span>
                )}
                {children}
                {!isLoading && rightIcon && !isIconOnly && (
                    <span className={cn(
                        "inline-flex ml-2",
                        iconSizes[size]
                    )}>
                        {rightIcon}
                    </span>
                )}
            </button>
        );
    }
);

Button.displayName = 'Button';