<template>
  <span v-if="!resolved.length" class="vm-tag-list is-empty">—</span>
  <span v-else class="vm-tag-list">
    <span
      v-for="(item, i) in visible"
      :key="`${item.label}-${i}`"
      class="vm-tag-list__tag"
      :class="item.variant ? `is-${item.variant}` : ''"
    >
      {{ item.label }}
    </span>
    <span v-if="overflow > 0" class="vm-tag-list__more">+{{ overflow }}</span>
  </span>
</template>

<script setup lang="ts">
import { computed } from 'vue'

defineOptions({ name: 'vm-tag-list' })

export type TagItem = {
  label: string
  variant?: 'brand' | 'outline' | 'muted'
}

const props = withDefaults(
  defineProps<{
    modelValue?: string | string[] | number[] | null
    tags?: TagItem[]
    separator?: string
    max?: number
  }>(),
  {
    separator: ',',
    max: 0,
  },
)

const resolved = computed((): TagItem[] => {
  if (props.tags?.length) return props.tags
  const v = props.modelValue
  if (v == null || v === '') return []
  const labels = Array.isArray(v)
    ? v.map((x) => String(x).trim()).filter(Boolean)
    : String(v)
        .split(props.separator)
        .map((s) => s.trim())
        .filter(Boolean)
  return labels.map((label) => ({ label, variant: 'brand' as const }))
})

const visible = computed(() => {
  if (!props.max || props.max <= 0) return resolved.value
  return resolved.value.slice(0, props.max)
})

const overflow = computed(() => {
  if (!props.max || props.max <= 0) return 0
  return Math.max(0, resolved.value.length - props.max)
})
</script>

<style lang="scss" scoped>
.vm-tag-list {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  max-width: 100%;

  &.is-empty {
    color: var(--muted-foreground);
  }
}

.vm-tag-list__tag {
  display: inline-flex;
  max-width: 100%;
  height: 20px;
  align-items: center;
  overflow: hidden;
  padding: 0 6px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--brand) 14%, transparent);
  color: var(--brand);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.35;
  text-overflow: ellipsis;
  white-space: nowrap;

  &.is-outline {
    border: 1px solid color-mix(in srgb, var(--brand) 35%, transparent);
    background: transparent;
  }

  &.is-muted {
    background: color-mix(in srgb, var(--foreground) 6%, transparent);
    color: var(--muted-foreground);
  }
}

.vm-tag-list__more {
  font-size: 11px;
  font-weight: 600;
  color: var(--muted-foreground);
}
</style>
