import plugin from 'tailwindcss/plugin'
import type { CSSRuleObject } from 'tailwindcss/types/config'
declare let module: any

/**
 * Badges help highlight important information, such as notifications or new and
 * unread messages. They’re primarily used for communicating secondary or additional
 * information to text.
 *
 * Class Names:
 *
 *  btu-badge-[sm|md|lg] - Size of the Badge.
 *  btu-badge-[$theme-colors] - Color of the Badge (includes text-decoration-color support).
 *
 * Example Usages:
 *
 *  Base   ->  btu-badge-lg btu-badge-purple
 *  Dot    ->  btu-badge-lg btu-badge-primary before:size-2 before:rounded-lg before:bg-[currentColor] before:[content:'']
 *  Close  ->  btu-badge-lg btu-badge-error after:btu-icon after:btu-icon-x
 */

type Size = {
  fontSize: 'xs' | 'sm'
  minWidth: string
  px: string
  py: string
}

const className = '.btu-badge'

module.exports = plugin(
  function ({ addComponents, theme, e, matchUtilities, addUtilities }) {
    const sizes = theme('badgeSize')
    const colors: [CSSRuleObject] = theme('colors')
    const fontSizes: Record<string, CSSRuleObject> = theme('fontSize')
    const iconSizes: CSSRuleObject = theme('iconSize') || {}

    // Custom color utilities for badge foreground and background
    matchUtilities(
      {
        'btu-badge-foreground': value => ({
          '--badge-color-foreground': value,
        }),
      },
      { values: theme('colors'), type: ['color', 'any'] },
    )

    matchUtilities(
      {
        'btu-badge-background': value => ({
          '--badge-color-background': value,
        }),
      },
      { values: theme('colors'), type: ['color', 'any'] },
    )

    addUtilities(
      {
        '.btu-badge-dot': {
          '--badge-dot-size': '6px',
          '&::before': {
            content: "''",
            display: 'inline-block',
            width: 'var(--badge-dot-size)',
            height: 'var(--badge-dot-size)',
            backgroundColor: 'currentColor',
            clipPath: 'circle(50% at center)',
          },
        },
      },
      {},
    )

    if (colors) {
      const badgeColors: CSSRuleObject[] = []
      for (const key in colors) {
        badgeColors.push({
          [`${className}-${e(key)}`]: {
            '--icon-size': iconSizes['xs'],
            backgroundColor: `var(--badge-color-background, oklch(var(--btu-theme-${key}-50)))`,
            color: `var(--badge-color-foreground, oklch(var(--btu-theme-${key}-700)))`,
            textDecoration: 'underline',
            textDecorationColor: `var(--badge-color-background, oklch(var(--btu-theme-${key}-50)))`,
          },
        })
      }
      addComponents(badgeColors)
    }

    if (sizes && fontSizes) {
      const badgeSizes: CSSRuleObject[] = []
      const fontSizeStyles = {
        display: 'inline-block',
        borderRadius: 'var(--badge-radius-size, 999px)',
      }

      for (const key in sizes) {
        const size: Size = sizes[key]
        const fontSize = fontSizes[size.fontSize]

        if (fontSize) {
          badgeSizes.push({
            [`${className}-${e(key)}`]: {
              '--badge-px': size.px,
              '--badge-py': size.py,
              alignItems: 'center',
              justifyContent: 'center',
              gap: '0.38rem',
              ...fontSizeStyles,
              fontSize: fontSize[0],
              lineHeight: fontSize[1],
              padding: `var(--badge-py) var(--badge-px)`,
              minWidth: size.minWidth,
              maxWidth: 'max-content',
              display: 'inline-flex',
            },
          })
        }
      }
      addComponents(badgeSizes)
    }
  },
  {
    theme: {
      badgeSize: {
        sm: {
          px: '0.5rem',
          py: '.13rem',
          fontSize: 'xs',
          minWidth: '1.375rem',
        },
        md: {
          px: '0.63rem',
          py: '.13rem',
          fontSize: 'sm',
          minWidth: '1.813rem',
        },
        lg: {
          px: '0.75rem',
          py: '.25rem',
          fontSize: 'sm',
          minWidth: '1.813rem',
        },
      },
    },
  },
)
