---
import { Icon } from 'astro-icon/components'
import { tv, type VariantProps } from 'tailwind-variants'

import type { Polymorphic } from 'astro/types'

const badge = tv({
  slots: {
    base: 'inline-flex h-4 items-center justify-center gap-0.75 rounded-full px-1.25 text-[10px] font-medium',
    icon: 'size-3 shrink-0',
    text: 'mx-0.25 overflow-hidden text-ellipsis whitespace-nowrap',
  },
  variants: {
    color: {
      red: '',
      orange: '',
      amber: '',
      yellow: '',
      lime: '',
      green: '',
      emerald: '',
      teal: '',
      cyan: '',
      sky: '',
      blue: '',
      indigo: '',
      violet: '',
      purple: '',
      fuchsia: '',
      pink: '',
      rose: '',
      slate: '',
      gray: '',
      zinc: '',
      neutral: '',
      stone: '',
      white: '',
      black: '',
    },
    variant: {
      solid: '',
      faded: '',
    },
  },
  compoundVariants: [
    // Red
    { color: 'red', variant: 'solid', class: { base: 'bg-red-500 text-white' } },
    { color: 'red', variant: 'faded', class: { base: 'bg-red-500/30 text-red-300' } },
    // Orange
    { color: 'orange', variant: 'solid', class: { base: 'bg-orange-500 text-white' } },
    { color: 'orange', variant: 'faded', class: { base: 'bg-orange-500/30 text-orange-300' } },
    // Amber
    { color: 'amber', variant: 'solid', class: { base: 'bg-amber-500 text-black' } },
    { color: 'amber', variant: 'faded', class: { base: 'bg-amber-500/30 text-amber-300' } },
    // Yellow
    { color: 'yellow', variant: 'solid', class: { base: 'bg-yellow-500 text-black' } },
    { color: 'yellow', variant: 'faded', class: { base: 'bg-yellow-500/30 text-yellow-300' } },
    // Lime
    { color: 'lime', variant: 'solid', class: { base: 'bg-lime-500 text-black' } },
    { color: 'lime', variant: 'faded', class: { base: 'bg-lime-500/30 text-lime-300' } },
    // Green
    { color: 'green', variant: 'solid', class: { base: 'bg-green-500 text-black' } },
    { color: 'green', variant: 'faded', class: { base: 'bg-green-500/30 text-green-300' } },
    // Emerald
    { color: 'emerald', variant: 'solid', class: { base: 'bg-emerald-500 text-white' } },
    { color: 'emerald', variant: 'faded', class: { base: 'bg-emerald-500/30 text-emerald-300' } },
    // Teal
    { color: 'teal', variant: 'solid', class: { base: 'bg-teal-500 text-white' } },
    { color: 'teal', variant: 'faded', class: { base: 'bg-teal-500/30 text-teal-300' } },
    // Cyan
    { color: 'cyan', variant: 'solid', class: { base: 'bg-cyan-500 text-white' } },
    { color: 'cyan', variant: 'faded', class: { base: 'bg-cyan-500/30 text-cyan-300' } },
    // Sky
    { color: 'sky', variant: 'solid', class: { base: 'bg-sky-500 text-white' } },
    { color: 'sky', variant: 'faded', class: { base: 'bg-sky-500/30 text-sky-300' } },
    // Blue
    { color: 'blue', variant: 'solid', class: { base: 'bg-blue-500 text-white' } },
    { color: 'blue', variant: 'faded', class: { base: 'bg-blue-500/30 text-blue-300' } },
    // Indigo
    { color: 'indigo', variant: 'solid', class: { base: 'bg-indigo-500 text-white' } },
    { color: 'indigo', variant: 'faded', class: { base: 'bg-indigo-500/30 text-indigo-300' } },
    // Violet
    { color: 'violet', variant: 'solid', class: { base: 'bg-violet-500 text-white' } },
    { color: 'violet', variant: 'faded', class: { base: 'bg-violet-500/30 text-violet-300' } },
    // Purple
    { color: 'purple', variant: 'solid', class: { base: 'bg-purple-500 text-white' } },
    { color: 'purple', variant: 'faded', class: { base: 'bg-purple-500/30 text-purple-300' } },
    // Fuchsia
    { color: 'fuchsia', variant: 'solid', class: { base: 'bg-fuchsia-500 text-white' } },
    { color: 'fuchsia', variant: 'faded', class: { base: 'bg-fuchsia-500/30 text-fuchsia-300' } },
    // Pink
    { color: 'pink', variant: 'solid', class: { base: 'bg-pink-500 text-white' } },
    { color: 'pink', variant: 'faded', class: { base: 'bg-pink-500/30 text-pink-300' } },
    // Rose
    { color: 'rose', variant: 'solid', class: { base: 'bg-rose-500 text-white' } },
    { color: 'rose', variant: 'faded', class: { base: 'bg-rose-500/30 text-rose-300' } },
    // Slate
    { color: 'slate', variant: 'solid', class: { base: 'bg-slate-500 text-white' } },
    { color: 'slate', variant: 'faded', class: { base: 'bg-slate-500/30 text-slate-300' } },
    // Gray
    { color: 'gray', variant: 'solid', class: { base: 'bg-gray-500 text-white' } },
    { color: 'gray', variant: 'faded', class: { base: 'bg-gray-500/30 text-gray-300' } },
    // Zinc
    { color: 'zinc', variant: 'solid', class: { base: 'bg-zinc-500 text-white' } },
    { color: 'zinc', variant: 'faded', class: { base: 'bg-zinc-500/30 text-zinc-300' } },
    // Neutral
    { color: 'neutral', variant: 'solid', class: { base: 'bg-neutral-500 text-white' } },
    { color: 'neutral', variant: 'faded', class: { base: 'bg-neutral-500/30 text-neutral-300' } },
    // Stone
    { color: 'stone', variant: 'solid', class: { base: 'bg-stone-500 text-white' } },
    { color: 'stone', variant: 'faded', class: { base: 'bg-stone-500/30 text-stone-300' } },
    // White
    { color: 'white', variant: 'solid', class: { base: 'bg-white text-black' } },
    { color: 'white', variant: 'faded', class: { base: 'bg-white-500/30 text-white-300' } },
    // Black
    { color: 'black', variant: 'solid', class: { base: 'bg-black text-white' } },
    { color: 'black', variant: 'faded', class: { base: 'bg-black-500/30 text-black-300' } },
  ],
  defaultVariants: {
    color: 'gray',
    variant: 'solid',
  },
})

type Props<Tag extends 'a' | 'div' | 'li' = 'div'> = Polymorphic<
  VariantProps<typeof badge> & {
    as: Tag
    icon?: string
    text: string
    inlineIcon?: boolean
    classNames?: {
      icon?: string
      text?: string
    }
  }
>

const {
  as: Tag = 'div',
  icon: iconName,
  text: textContent,
  inlineIcon,
  classNames,

  color,
  variant,

  class: className,
  ...props
} = Astro.props

const { base, icon: iconSlot, text: textSlot } = badge({ color, variant })
---

<Tag {...props} class={base({ class: className })}>
  {
    !!iconName && (
      <Icon name={iconName} class={iconSlot({ class: classNames?.icon })} is:inline={inlineIcon} />
    )
  }
  <span class={textSlot({ class: classNames?.text })}>{textContent}</span>
</Tag>
