import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react'
import { cn } from '@/lib/utils'

export interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
  variant?: 'primary' | 'secondary' | 'tertiary'
  intent?: 'default' | 'danger' | 'neutral'
  size?: 'default' | 'large' | 'compact' | 'small' | 'xsmall'
  shape?: 'circle' | 'square'
  icon: ReactNode
  'aria-label': string
}

const variantIntentStyles: Record<string, Record<string, string>> = {
  primary: {
    default: 'bg-button-default text-white hover:bg-button-default/90 active:bg-button-default/80',
    danger: 'bg-button-danger text-white hover:bg-button-danger/90 active:bg-button-danger/80',
    neutral: 'bg-button-neutral text-white hover:bg-button-neutral/90 active:bg-button-neutral/80',
  },
  secondary: {
    default:
      'border-2 border-button-default text-button-default hover:bg-button-default/5 active:bg-button-default/10',
    danger:
      'border-2 border-button-danger text-button-danger hover:bg-button-danger/5 active:bg-button-danger/10',
    neutral:
      'border-2 border-button-neutral text-button-neutral hover:bg-button-neutral/5 active:bg-button-neutral/10',
  },
  tertiary: {
    default: 'text-button-default hover:bg-button-default/5 active:bg-button-default/10',
    danger: 'text-button-danger hover:bg-button-danger/5 active:bg-button-danger/10',
    neutral: 'text-button-neutral hover:bg-button-neutral/5 active:bg-button-neutral/10',
  },
}

const sizeStyles: Record<string, string> = {
  large: 'size-14',
  default: 'size-12',
  compact: 'size-10',
  small: 'size-8',
  xsmall: 'size-6',
}

const iconSizeStyles: Record<string, string> = {
  large: 'size-6',
  default: 'size-6',
  compact: 'size-[18px]',
  small: 'size-4',
  xsmall: 'size-3.5',
}

export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
  (
    {
      variant = 'primary',
      intent = 'default',
      size = 'default',
      shape = 'circle',
      icon,
      disabled,
      className,
      ...props
    },
    ref,
  ) => {
    return (
      <button
        ref={ref}
        disabled={disabled}
        className={cn(
          'inline-flex items-center justify-center transition-colors',
          shape === 'circle' ? 'rounded-full' : 'rounded-lg',
          'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-button-default',
          sizeStyles[size],
          variantIntentStyles[variant][intent],
          disabled && 'pointer-events-none opacity-50',
          className,
        )}
        {...props}
      >
        <span className={cn('shrink-0 [&>svg]:size-full', iconSizeStyles[size])}>
          {icon}
        </span>
      </button>
    )
  },
)

IconButton.displayName = 'IconButton'
