<template>
  <button
    v-if="clickable"
    type="button"
    class="vm-status-tag"
    :class="[resolved.variant, { 'is-clickable': clickable }]"
    :disabled="disabled"
    @click="emit('click', $event)"
  >
    {{ resolved.label }}
  </button>
  <span v-else class="vm-status-tag" :class="resolved.variant">
    {{ resolved.label }}
  </span>
</template>

<script setup lang="ts">
import { crudLabel } from '../style'
import { computed } from 'vue'

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

type Variant = 'success' | 'warning' | 'danger' | 'info' | 'brand' | 'neutral'

const props = withDefaults(
  defineProps<{
    modelValue?: unknown
    label?: string
    variant?: Variant
    /** http | queue | task 内置语义映射 */
    preset?: 'http' | 'queue' | 'task'
    /** 表格列传入的行数据，配合 labelProp 取展示文案 */
    scope?: Record<string, unknown>
    labelProp?: string
    clickable?: boolean
    disabled?: boolean
  }>(),
  {
    clickable: false,
    disabled: false,
  },
)

const emit = defineEmits<{
  click: [e: MouseEvent]
}>()

function resolveHttp(v: unknown): { variant: Variant; label: string } {
  const n = Number(v)
  const label = props.label ?? (v == null || v === '' ? '—' : String(v))
  if (!Number.isFinite(n)) return { variant: 'neutral', label }
  if (n >= 500) return { variant: 'danger', label }
  if (n >= 400) return { variant: 'warning', label }
  if (n >= 200 && n < 300) return { variant: 'success', label }
  return { variant: 'neutral', label }
}

function resolveQueue(v: unknown): { variant: Variant; label: string } {
  const key = String(v ?? '')
  const label = props.label ?? (key || '—')
  if (key === 'failed') return { variant: 'danger', label }
  if (key === 'completed') return { variant: 'success', label }
  if (key === 'active') return { variant: 'brand', label }
  if (key === 'waiting' || key === 'delayed') return { variant: 'warning', label }
  return { variant: 'neutral', label }
}

function resolveTask(v: unknown): { variant: Variant; label: string } {
  const on = Number(v) === 1
  const label = props.label ?? (on ? crudLabel('running') : crudLabel('stopped'))
  return { variant: on ? 'success' : 'neutral', label }
}

const resolved = computed(() => {
  const scopeLabel =
    props.labelProp && props.scope ? props.scope[props.labelProp] : undefined
  const fallbackLabel =
    props.label ??
    (scopeLabel != null && scopeLabel !== '' ? String(scopeLabel) : undefined)

  if (props.variant) {
    return {
      variant: props.variant,
      label: fallbackLabel ?? (props.modelValue == null ? '—' : String(props.modelValue)),
    }
  }
  if (props.preset === 'http') {
    const r = resolveHttp(props.modelValue)
    return { ...r, label: fallbackLabel ?? r.label }
  }
  if (props.preset === 'queue') {
    const r = resolveQueue(props.modelValue)
    return { ...r, label: fallbackLabel ?? r.label }
  }
  if (props.preset === 'task') {
    const r = resolveTask(props.modelValue)
    return { ...r, label: fallbackLabel ?? r.label }
  }
  return {
    variant: 'neutral' as Variant,
    label: fallbackLabel ?? (props.modelValue == null ? '—' : String(props.modelValue)),
  }
})
</script>

<style lang="scss" scoped>
.vm-status-tag {
  display: inline-flex;
  min-width: 40px;
  justify-content: center;
  padding: 2px 8px;
  border: none;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 650;
  line-height: 1.4;
  background: color-mix(in srgb, var(--foreground) 8%, transparent);
  color: var(--muted-foreground);

  &.is-success {
    background: var(--success-soft);
    color: var(--success);
  }

  &.is-warning {
    background: color-mix(in srgb, #f59e0b 16%, transparent);
    color: #d97706;
  }

  &.is-danger {
    background: var(--danger-soft);
    color: var(--danger);
  }

  &.is-info {
    background: color-mix(in srgb, var(--brand) 12%, transparent);
    color: var(--brand);
  }

  &.is-brand {
    background: color-mix(in srgb, var(--brand) 14%, transparent);
    color: var(--brand);
  }

  &.is-clickable {
    cursor: pointer;

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

    &:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
  }
}
</style>
