import React from 'react'
import { cn } from '@/utils/cn'

export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger'
export type ButtonSize = 'sm' | 'md' | 'lg'

export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: ButtonVariant
  size?: ButtonSize
  isLoading?: boolean
  leftIcon?: string
  rightIcon?: string
  children?: React.ReactNode
}

const variantStyles: Record<ButtonVariant, string> = {
  primary:
    'bg-teal-500 hover:bg-teal-600 active:bg-teal-700 text-white font-bold shadow-soft-md hover:shadow-soft-lg focus:outline-2 focus:outline-teal-400 focus:outline-offset-2',
  secondary:
    'bg-teal-50 hover:bg-teal-100 active:bg-teal-200 text-teal-600 font-bold shadow-soft-md hover:shadow-soft-lg focus:outline-2 focus:outline-teal-400 focus:outline-offset-2',
  outline:
    'border-[1.5px] border-slate-200 hover:border-slate-300 hover:bg-slate-50 active:bg-slate-100 text-slate-800 font-bold focus:outline-2 focus:outline-teal-400 focus:outline-offset-2',
  ghost:
    'text-slate-500 hover:text-slate-800 hover:bg-slate-100 active:bg-slate-200 font-semibold focus:outline-2 focus:outline-teal-400 focus:outline-offset-2',
  danger:
    'bg-red-500 hover:bg-red-600 active:bg-red-700 text-white font-bold shadow-soft-md hover:shadow-soft-lg focus:outline-2 focus:outline-red-400 focus:outline-offset-2',
}

const sizeStyles: Record<ButtonSize, string> = {
  sm: 'text-caption px-3 py-1.5 rounded-lg',
  md: 'text-body-sm px-5 py-2.5 rounded-[10px]',
  lg: 'text-sm px-7 py-3.5 rounded-xl',
}

const iconOnlyStyles: Record<ButtonSize, string> = {
  sm: 'w-8 h-8 rounded-lg',
  md: 'w-10 h-10 rounded-[10px]',
  lg: 'w-12 h-12 rounded-xl',
}

export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  (
    {
      variant = 'primary',
      size = 'md',
      isLoading = false,
      leftIcon,
      rightIcon,
      className,
      children,
      disabled,
      ...props
    },
    ref
  ) => {
    const isIconOnly = !children && (leftIcon || rightIcon)

    return (
      <button
        ref={ref}
        className={cn(
          'inline-flex items-center justify-center gap-1.5 transition-all duration-150 cursor-pointer',
          variantStyles[variant],
          isIconOnly ? iconOnlyStyles[size] : sizeStyles[size],
          isLoading && 'opacity-70 cursor-not-allowed',
          disabled && !isLoading && 'opacity-50 cursor-not-allowed',
          className
        )}
        disabled={disabled || isLoading}
        aria-busy={isLoading || undefined}
        {...props}
      >
        {isLoading ? (
          <>
            <svg className="animate-spin h-3.5 w-3.5" viewBox="0 0 24 24" fill="none">
              <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 12h4z" />
            </svg>
            {children}
          </>
        ) : (
          <>
            {leftIcon && (
              <span className="material-symbols-outlined text-body-lg">{leftIcon}</span>
            )}
            {children}
            {rightIcon && (
              <span className="material-symbols-outlined text-body-lg">{rightIcon}</span>
            )}
          </>
        )}
      </button>
    )
  }
)

Button.displayName = 'Button'
