import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react'
import { clsx } from 'clsx'
import { Loader2 } from 'lucide-react'

interface NeonButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger'
  size?: 'sm' | 'md' | 'lg'
  color?: 'neon' | 'purple' | 'pink'
  isLoading?: boolean
  icon?: ReactNode
  iconPosition?: 'left' | 'right'
  glow?: boolean
  pulse?: boolean
}

export const NeonButton = forwardRef<HTMLButtonElement, NeonButtonProps>(
  (
    {
      className,
      variant = 'primary',
      size = 'md',
      color = 'neon',
      isLoading,
      icon,
      iconPosition = 'left',
      glow = true,
      pulse = false,
      children,
      disabled,
      ...props
    },
    ref
  ) => {
    const colorMap = {
      neon: {
        primary: 'bg-neon-500 hover:bg-neon-400 text-dark-900',
        secondary: 'bg-dark-600 hover:bg-dark-500 text-neon-400 border border-neon-500/30',
        outline: 'bg-transparent border-2 border-neon-500 text-neon-500 hover:bg-neon-500 hover:text-dark-900',
        ghost: 'bg-transparent hover:bg-neon-500/10 text-neon-400',
        danger: 'bg-red-600 hover:bg-red-700 text-white',
        glow: '0 0 12px rgba(34, 211, 238, 0.4)',
        glowHover: '0 0 18px rgba(34, 211, 238, 0.55)',
        glowDanger: '0 0 12px rgba(239, 68, 68, 0.4)',
        glowDangerHover: '0 0 18px rgba(239, 68, 68, 0.55)',
      },
      purple: {
        primary: 'bg-accent-500 hover:bg-accent-400 text-white',
        secondary: 'bg-dark-600 hover:bg-dark-500 text-accent-400 border border-accent-500/30',
        outline: 'bg-transparent border-2 border-accent-500 text-accent-500 hover:bg-accent-500 hover:text-white',
        ghost: 'bg-transparent hover:bg-accent-500/10 text-accent-400',
        danger: 'bg-red-600 hover:bg-red-700 text-white',
        glow: '0 0 12px rgba(139, 92, 246, 0.4)',
        glowHover: '0 0 18px rgba(139, 92, 246, 0.55)',
        glowDanger: '0 0 12px rgba(239, 68, 68, 0.4)',
        glowDangerHover: '0 0 18px rgba(239, 68, 68, 0.55)',
      },
      pink: {
        primary: 'bg-pink-500 hover:bg-pink-400 text-white',
        secondary: 'bg-dark-600 hover:bg-dark-500 text-pink-400 border border-pink-500/30',
        outline: 'bg-transparent border-2 border-pink-500 text-pink-500 hover:bg-pink-500 hover:text-white',
        ghost: 'bg-transparent hover:bg-pink-500/10 text-pink-400',
        danger: 'bg-red-600 hover:bg-red-700 text-white',
        glow: '0 0 12px rgba(244, 114, 182, 0.4)',
        glowHover: '0 0 18px rgba(244, 114, 182, 0.55)',
        glowDanger: '0 0 12px rgba(239, 68, 68, 0.4)',
        glowDangerHover: '0 0 18px rgba(239, 68, 68, 0.55)',
      },
    }

    const iconSizes = {
      sm: 'w-4 h-4',
      md: 'w-5 h-5',
      lg: 'w-6 h-6',
    }

    const isIconOnly = icon && !children

    const sizeClassesWithText = {
      sm: 'px-3 py-1.5 text-sm gap-1.5',
      md: 'px-4 py-2.5 text-base gap-2',
      lg: 'px-6 py-3 text-lg gap-2.5',
    }

    const sizeClassesIconOnly = {
      sm: 'p-2 text-sm',
      md: 'p-2.5 text-base',
      lg: 'p-3 text-lg',
    }

    const sizeClasses = isIconOnly ? sizeClassesIconOnly : sizeClassesWithText

    const colors = colorMap[color]

    return (
      <button
        ref={ref}
        disabled={disabled || isLoading}
        className={clsx(
          'inline-flex items-center justify-center font-semibold rounded-lg',
          'transition-all duration-300 ease-out',
          'disabled:opacity-50 disabled:cursor-not-allowed disabled:shadow-none',
          'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-dark-900',
          color === 'neon' && 'focus:ring-neon-500',
          color === 'purple' && 'focus:ring-accent-500',
          color === 'pink' && 'focus:ring-pink-500',
          colors[variant],
          sizeClasses[size],
          pulse && 'neon-glow-pulse',
          className
        )}
        style={{
          boxShadow: glow && !disabled && variant !== 'ghost'
            ? (variant === 'danger' ? colors.glowDanger : colors.glow)
            : undefined,
        }}
        onMouseEnter={(e) => {
          if (glow && !disabled && variant !== 'ghost') {
            e.currentTarget.style.boxShadow = variant === 'danger' ? colors.glowDangerHover : colors.glowHover
          }
          props.onMouseEnter?.(e)
        }}
        onMouseLeave={(e) => {
          if (glow && !disabled && variant !== 'ghost') {
            e.currentTarget.style.boxShadow = variant === 'danger' ? colors.glowDanger : colors.glow
          }
          props.onMouseLeave?.(e)
        }}
        {...props}
      >
        {isLoading && <Loader2 className={clsx(iconSizes[size], 'animate-spin')} />}
        {!isLoading && icon && iconPosition === 'left' && (
          <span className={iconSizes[size]}>{icon}</span>
        )}
        {children}
        {!isLoading && icon && iconPosition === 'right' && (
          <span className={iconSizes[size]}>{icon}</span>
        )}
      </button>
    )
  }
)

NeonButton.displayName = 'NeonButton'

// Gradient button variant
interface GradientButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  size?: 'sm' | 'md' | 'lg'
  isLoading?: boolean
  icon?: ReactNode
}

export const GradientButton = forwardRef<HTMLButtonElement, GradientButtonProps>(
  ({ className, size = 'md', isLoading, icon, children, disabled, ...props }, ref) => {
    const sizeClasses = {
      sm: 'px-3 py-1.5 text-sm gap-1.5',
      md: 'px-4 py-2.5 text-base gap-2',
      lg: 'px-6 py-3 text-lg gap-2.5',
    }

    return (
      <button
        ref={ref}
        disabled={disabled || isLoading}
        className={clsx(
          'relative inline-flex items-center justify-center font-semibold rounded-lg',
          'bg-gradient-to-r from-neon-500 via-accent-500 to-pink-500',
          'text-white transition-all duration-300',
          'hover:shadow-[0_0_20px_rgba(139,92,246,0.35)]',
          'disabled:opacity-50 disabled:cursor-not-allowed',
          'focus:outline-none focus:ring-2 focus:ring-accent-500 focus:ring-offset-2 focus:ring-offset-dark-900',
          sizeClasses[size],
          className
        )}
        {...props}
      >
        {isLoading && <Loader2 className="w-5 h-5 animate-spin" />}
        {!isLoading && icon && <span className="w-5 h-5">{icon}</span>}
        {children}
      </button>
    )
  }
)

GradientButton.displayName = 'GradientButton'
