import React, { forwardRef, ButtonHTMLAttributes } from 'react';
import { clsx } from 'clsx';

export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'success' | 'warning' | 'gradient';
  size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
  isLoading?: boolean;
  isFullWidth?: boolean;
  leftIcon?: React.ReactNode;
  rightIcon?: React.ReactNode;
  loadingText?: string;
}

const Button = forwardRef<HTMLButtonElement, ButtonProps>(({
  variant = 'primary',
  size = 'md',
  isLoading = false,
  isFullWidth = false,
  leftIcon,
  rightIcon,
  loadingText,
  className,
  children,
  disabled,
  ...props
}, ref) => {
  const baseClasses = [
    '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-50 disabled:cursor-not-allowed',
    'border rounded-md',
  ];

  const variantClasses = {
    primary: [
      'bg-[var(--color-primary)] text-[var(--text-inverse)] border-[var(--color-primary)]',
      'hover:bg-[var(--color-primary-dark)] hover:border-[var(--color-primary-dark)]',
      'focus:ring-[var(--color-primary)]/20',
      'active:bg-[var(--color-primary-dark)]',
      'shadow-sm hover:shadow-md active:shadow-sm'
    ],
    secondary: [
      'bg-[var(--color-secondary)] text-[var(--text-inverse)] border-[var(--color-secondary)]',
      'hover:bg-[var(--color-secondary-dark)] hover:border-[var(--color-secondary-dark)]',
      'focus:ring-[var(--color-secondary)]/20',
      'active:bg-[var(--color-secondary-dark)]',
      'shadow-sm hover:shadow-md active:shadow-sm'
    ],
    outline: [
      'bg-transparent text-[var(--color-primary)] border-[var(--color-primary)]',
      'hover:bg-[var(--color-primary)] hover:text-[var(--text-inverse)]',
      'focus:ring-[var(--color-primary)]/20',
      'active:bg-[var(--color-primary-dark)] active:border-[var(--color-primary-dark)]',
      'shadow-sm hover:shadow-md active:shadow-sm'
    ],
    ghost: [
      'bg-transparent text-[var(--text-primary)] border-transparent',
      'hover:bg-[var(--bg-tertiary)] hover:text-[var(--text-primary)]',
      'focus:ring-[var(--color-primary)]/20',
      'active:bg-[var(--bg-secondary)]'
    ],
    danger: [
      'bg-[var(--color-error)] text-[var(--text-inverse)] border-[var(--color-error)]',
      'hover:bg-[var(--color-error-dark)] hover:border-[var(--color-error-dark)]',
      'focus:ring-[var(--color-error)]/20',
      'active:bg-[var(--color-error-dark)]',
      'shadow-sm hover:shadow-md active:shadow-sm'
    ],
    success: [
      'bg-[var(--color-success)] text-[var(--text-inverse)] border-[var(--color-success)]',
      'hover:bg-[var(--color-success-dark)] hover:border-[var(--color-success-dark)]',
      'focus:ring-[var(--color-success)]/20',
      'active:bg-[var(--color-success-dark)]',
      'shadow-sm hover:shadow-md active:shadow-sm'
    ],
    warning: [
      'bg-[var(--color-warning)] text-[var(--text-inverse)] border-[var(--color-warning)]',
      'hover:bg-[var(--color-warning-dark)] hover:border-[var(--color-warning-dark)]',
      'focus:ring-[var(--color-warning)]/20',
      'active:bg-[var(--color-warning-dark)]',
      'shadow-sm hover:shadow-md active:shadow-sm'
    ],
    gradient: [
      'bg-[var(--color-primary)] text-white border-[var(--color-primary)]',
      'hover:bg-[var(--color-primary-dark)] hover:border-[var(--color-primary-dark)]',
      'focus:ring-[var(--color-primary)]/20',
      'shadow-lg hover:shadow-xl',
      'transform hover:scale-105',
      'font-semibold'
    ]
  };

  const sizeClasses = {
    xs: 'px-2 py-1 text-xs gap-1 min-h-[1.75rem]',
    sm: 'px-3 py-1.5 text-sm gap-1.5 min-h-[2.25rem]',
    md: 'px-4 py-2 text-sm gap-2 min-h-[2.75rem]',
    lg: 'px-5 py-2.5 text-base gap-2.5 min-h-[3.25rem]',
    xl: 'px-6 py-3 text-lg gap-3 min-h-[3.75rem]'
  };

  const loadingSpinner = (
    <svg 
      className="animate-spin -ml-1 mr-2 h-4 w-4" 
      xmlns="http://www.w3.org/2000/svg" 
      fill="none" 
      viewBox="0 0 24 24"
    >
      <circle 
        className="opacity-25" 
        cx="12" 
        cy="12" 
        r="10" 
        stroke="currentColor" 
        strokeWidth="4"
      />
      <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"
      />
    </svg>
  );

  const classes = clsx(
    baseClasses,
    variantClasses[variant],
    sizeClasses[size],
    {
      'w-full': isFullWidth,
      'cursor-wait': isLoading
    },
    className
  );

  return (
    <button
      ref={ref}
      className={classes}
      disabled={disabled || isLoading}
      {...props}
    >
      {isLoading && loadingSpinner}
      {!isLoading && leftIcon && (
        <span className="flex-shrink-0 w-4 h-4 flex items-center justify-center">{leftIcon}</span>
      )}
      <span className="relative">
        {isLoading && loadingText ? loadingText : children}
      </span>
      {!isLoading && rightIcon && (
        <span className="flex-shrink-0 w-4 h-4 flex items-center justify-center">{rightIcon}</span>
      )}
    </button>
  );
});

Button.displayName = 'Button';

export default Button;