import { forwardRef, type ButtonHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react'

type ChipTone = 'neutral' | 'accent' | 'cool' | 'success' | 'warning' | 'error' | 'glow' | 'outline'
type ChipSize = 'xs' | 'sm' | 'md'

const toneClass: Record<ChipTone, string> = {
  neutral: 'bg-white/8 text-text-1 border-white/8 hover:bg-white/12',
  accent: 'bg-accent/15 text-accent border-accent/25 hover:bg-accent/20',
  cool: 'bg-cool/12 text-cool border-cool/25',
  success: 'bg-success/12 text-success border-success/25',
  warning: 'bg-warning/12 text-warning border-warning/25',
  error: 'bg-error/12 text-error border-error/25',
  glow:
    'bg-gradient-to-r from-accent/20 to-cool/15 text-text-1 border-accent/30 shadow-[0_0_12px_rgba(245,182,66,0.25)]',
  outline: 'bg-transparent text-text-2 border-border hover:border-border-hover hover:text-text-1',
}

const sizeClass: Record<ChipSize, string> = {
  xs: 'h-5 px-1.5 text-[10px] gap-1 rounded',
  sm: 'h-6 px-2 text-[11px] gap-1.5 rounded-md',
  md: 'h-7 px-2.5 text-[12px] gap-1.5 rounded-md',
}

interface ChipBase {
  tone?: ChipTone
  size?: ChipSize
  icon?: ReactNode
  trailing?: ReactNode
  active?: boolean
}

export type ChipProps = ChipBase & HTMLAttributes<HTMLSpanElement> & { as?: 'span' }
export type ChipButtonProps = ChipBase & ButtonHTMLAttributes<HTMLButtonElement> & { as: 'button' }

export const Chip = forwardRef<HTMLSpanElement | HTMLButtonElement, ChipProps | ChipButtonProps>(
  function Chip(props, ref) {
    const {
      tone = 'neutral',
      size = 'sm',
      icon,
      trailing,
      active,
      className = '',
      children,
      as = 'span',
      ...rest
    } = props as ChipBase & { as?: 'span' | 'button' } & Record<string, any>

    const baseCls =
      `inline-flex items-center font-medium tracking-tight border whitespace-nowrap select-none transition-colors duration-150 ${
        sizeClass[size]
      } ${toneClass[active ? 'accent' : tone]} ${className}`

    if (as === 'button') {
      return (
        <button
          {...(rest as ButtonHTMLAttributes<HTMLButtonElement>)}
          ref={ref as React.Ref<HTMLButtonElement>}
          className={`${baseCls} cursor-pointer focus-ring`}
        >
          {icon}
          {children}
          {trailing}
        </button>
      )
    }
    return (
      <span
        {...(rest as HTMLAttributes<HTMLSpanElement>)}
        ref={ref as React.Ref<HTMLSpanElement>}
        className={baseCls}
      >
        {icon}
        {children}
        {trailing}
      </span>
    )
  },
)
