<template>
  <span
    class="badge"
    :class="[`badge--${variant}`, `badge--${size}`, { 'badge--clickable': clickable }]"
    :role="clickable ? 'button' : undefined"
    @click="onClick"
  >
    <span v-if="dot" class="badge__dot" />
    <SvgIcon v-if="icon" :name="icon" :size="iconSize" class="badge__icon" :color="iconColor" />
    <slot name="prepend" />
    <span v-if="label" class="badge__label">{{ label }}</span>
    <span v-if="$slots.default || value" class="badge__value">
      <slot>{{ value }}</slot>
    </span>
    <slot name="append" />
  </span>
</template>

<script setup>
import { computed } from 'vue'
import SvgIcon from '@/components/icons/SvgIcon.vue'

const props = defineProps({
  /** @type {import('vue').PropType<'neutral' | 'success' | 'danger' | 'warning' | 'primary' | 'info' | 'cyan' | 'blue'>} */
  variant: { type: String, default: 'neutral' },
  /** @type {import('vue').PropType<'sm' | 'md' | 'lg'>} */
  size: { type: String, default: 'md' },
  label: { type: String, default: '' },
  value: { type: [String, Number], default: '' },
  /** @type {import('vue').PropType<import('@/components/icons/icon-names').IconName | ''>} */
  icon: { type: String, default: '' },
  dot: { type: Boolean, default: false },
  clickable: { type: Boolean, default: false },
})

const emit = defineEmits(['click'])

const ICON_SIZE_MAP = { sm: 11, md: 14, lg: 16 }
const iconSize = computed(() => ICON_SIZE_MAP[props.size] ?? 14)
const iconColor = computed(() => 'currentColor')

const onClick = (event) => {
  if (!props.clickable) return
  emit('click', event)
}
</script>

<style lang="scss" scoped>
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  border-radius: 0.75rem;
  font-family: var(--font-family-fa);
  white-space: nowrap;
  line-height: 1.5;
  transition: filter 0.15s ease;

  &--clickable {
    cursor: pointer;

    &:hover {
      filter: brightness(0.96);
    }
  }

  &__dot {
    width: 0.4em;
    height: 0.4em;
    border-radius: 9999px;
    background: currentcolor;
    flex-shrink: 0;
  }

  &__icon {
    flex-shrink: 0;
  }

  &__label {
    font-weight: 300;
    color: inherit;
    opacity: 0.85;
  }

  &__value {
    font-weight: 500;
  }

  &--sm {
    padding: 0.2rem 0.625rem;
    font-size: 0.65rem;
    gap: 0.3rem;
    border-radius: 0.625rem;
  }

  &--md {
    padding: 0.3rem 0.875rem;
    font-size: 0.75rem;
  }

  &--lg {
    padding: 0.4rem 1rem;
    font-size: 0.875rem;
    border-radius: 0.875rem;
  }

  &--neutral {
    background: rgba(107, 107, 107, 5%);
    color: #535353;
  }

  &--success {
    background: rgba(0, 153, 76, 10%);
    color: #00994c;
  }

  &--danger {
    background: rgba(243, 102, 117, 8%);
    color: #cc2831;
  }

  &--warning {
    background: rgba(204, 154, 40, 10%);
    color: #cc6f00;
  }

  &--primary {
    background: rgba(0, 112, 116, 8%);
    color: #007074;
  }

  &--info {
    background: rgba(104, 104, 104, 10%);
    color: #686868;
  }

  &--cyan {
    background: rgba(104, 104, 104, 10%);
    color: #686868;
  }

  &--blue {
    background: rgba(0, 72, 255, 8%);
    color: #0048ff;
  }
}
</style>
