<template>
  <el-tag 
    v-if="showTag"
    :type="tagType"
    :effect="tagEffect"
  >
    {{ label }}
  </el-tag>
  <span v-else class="status-tag" :class="statusClass" :style="statusStyle">
    {{ label }}
  </span>
</template>

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

interface Option {
  label: string
  value: string | number
}

interface Props {
  value?: string | number // 当前值
  options?: Option[] // 选项列表，格式：[{label: '是', value: '1'}, {label: '否', value: '0'}]
  showTag?: boolean // 是否显示标签样式（有边框和背景），默认为 true
  typeMap?: Record<string | number, { type: string; effect?: string }> // 自定义类型映射，如 {'1': {type: 'warning', effect: 'dark'}}
  colorMap?: Record<string | number, string> // 纯文本模式下的颜色映射，如 {'1': '#E6A23C'}
}

const props = withDefaults(defineProps<Props>(), {
  value: '',
  options: () => [],
  showTag: true,
  typeMap: () => ({}),
  colorMap: () => ({})
})

// 默认的类型映射（只使用字符串键）
const defaultTypeMap: Record<string, { type: string; effect: string }> = {
  '1': { type: 'danger', effect: 'dark' },
  '0': { type: 'primary', effect: 'light' }
}

// 默认的颜色映射（只使用字符串键）
const defaultColorMap: Record<string, string> = {
  '1': 'var(--el-color-danger)',
  '0': 'var(--el-color-primary)'
}

// 获取值的字符串形式（用于查找映射）
const getValueKey = (value: string | number): string => {
  return String(value)
}

// 合并后的类型映射（外部传入优先，否则使用默认）
const mergedTypeMap = computed(() => {
  // 将外部传入的 typeMap 也转换为字符串键
  const externalTypeMap: Record<string, { type: string; effect?: string }> = {}
  Object.keys(props.typeMap).forEach(key => {
    externalTypeMap[String(key)] = props.typeMap[key]
  })
  return { ...defaultTypeMap, ...externalTypeMap }
})

// 合并后的颜色映射（外部传入优先，否则使用默认）
const mergedColorMap = computed(() => {
  // 将外部传入的 colorMap 也转换为字符串键
  const externalColorMap: Record<string, string> = {}
  Object.keys(props.colorMap).forEach(key => {
    externalColorMap[String(key)] = props.colorMap[key]
  })
  return { ...defaultColorMap, ...externalColorMap }
})

// 合并后的选项列表（必须通过外部传入 options）
const mergedOptions = computed(() => {
  // 必须传入 options，否则返回空数组
  return props.options && props.options.length > 0 ? props.options : []
})

// 根据值找到对应的选项
const currentOption = computed(() => {
  return mergedOptions.value.find((opt: Option) => {
    const optValue = String(opt.value)
    const propValue = String(props.value)
    return optValue === propValue || Number(opt.value) === Number(props.value)
  })
})

// 显示标签
const label = computed(() => {
  return currentOption.value?.label || '-'
})

// 标签类型（showTag 为 true 时使用）
const tagType = computed(() => {
  const valueKey = getValueKey(props.value)
  if (mergedTypeMap.value[valueKey]) {
    return mergedTypeMap.value[valueKey].type
  }
  return 'info'
})

// 标签效果（showTag 为 true 时使用）
const tagEffect = computed(() => {
  const valueKey = getValueKey(props.value)
  if (mergedTypeMap.value[valueKey]?.effect) {
    return mergedTypeMap.value[valueKey].effect
  }
  return 'light'
})

// 纯文本模式下的样式类
const statusClass = computed(() => {
  if (props.colorMap[props.value]) {
    return ''
  }
  return 'status-default'
})

// 纯文本模式下的内联样式
const statusStyle = computed(() => {
  const valueKey = getValueKey(props.value)
  if (mergedColorMap.value[valueKey]) {
    return { color: mergedColorMap.value[valueKey] }
  }
  return {}
})
</script>

<style scoped>
.status-tag {
  display: inline-block;
}

.status-default {
  color: var(--el-text-color-regular);
}
</style>

