<!-- components/uni-app-tag/uni-app-tag.vue -->
<template>
  <view class="uni-app-tag-container">
    <!-- 匹配的标签 -->
    <template
      v-for="(item, index) in matchedItems"
      :key="getValue(item)"
    >
      <!-- 普通 span（default 类型 + 无 class） -->
      <span
        v-if="isDefaultTag(item)"
        class="uni-app-tag-span"
        :class="item.elTagClass"
      >
        {{ getText(item) }}&nbsp;
      </span>

      <!-- 自定义样式 view 模拟 tag -->
      <view
        v-else
        class="uni-app-tag"
        :class="[
          `uni-app-tag--${getUniType(item.elTagType)}`,
          item.elTagClass
        ]"
      >
        {{ getText(item) }}
      </view>
    </template>

    <!-- 未匹配的值 -->
    <text v-if="unmatch && showValue" class="uni-app-tag-unmatch">
      {{ unmatchText }}
    </text>
  </view>
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
  /* 选项数组 */
  options: {
    type: Array,
    default: () => []
  },
  /* 当前值：String | Number | Array */
  value: [String, Number, Array],
  /* 是否显示未匹配值 */
  showValue: {
    type: Boolean,
    default: true
  },
  /* 字符串分隔符（仅 value 为字符串时生效） */
  separator: {
    type: String,
    default: ','
  },
  /* 字段映射：值字段名 */
  valueField: {
    type: String,
    default: 'dictValue'
  },
  /* 字段映射：文本字段名 */
  textField: {
    type: String,
    default: 'dictLabel'
  }
})

/* 工具函数：统一取出值 / 文本 */
const getValue = (opt) => String(opt[props.valueField])
const getText  = (opt) => opt[props.textField] ?? ''

/* 1. 统一转成字符串数组 */
const values = computed(() => {
  if (props.value == null || props.value === '') return []
  return Array.isArray(props.value)
    ? props.value.map(String)
    : String(props.value).split(props.separator).map(v => v.trim())
})

/* 2. 匹配到的选项 */
const matchedItems = computed(() =>
  values.value
    .map(val => props.options.find(opt => getValue(opt) === val))
    .filter(Boolean)
)

/* 3. 未匹配的值 */
const unmatchArray = computed(() => {
  if (!values.value.length || !props.options.length) return []
  return values.value.filter(
    val => !props.options.some(opt => getValue(opt) === val)
  )
})
const unmatch     = computed(() => unmatchArray.value.length > 0)
const unmatchText = computed(() => unmatchArray.value.join(' '))

/* 4. 判断是否为默认 tag（default 且无自定义 class） */
const isDefaultTag = (item) => {
  const type = item.elTagType || 'default'
  const cls  = item.elTagClass || ''
  return (type === 'default' || !type) && !cls
}

/* 5. el-tag type -> uni 类名映射 */
const getUniType = (type) => {
  const map = {
    primary: 'primary',
    success: 'success',
    warning: 'warning',
    danger:  'error',
    info:    'info',
    default: 'default'
  }
  return map[type] || 'default'
}
</script>

<style scoped>
.uni-app-tag-container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  font-size: 14px;
}

.uni-app-tag-span {
  margin-right: 8px;
  white-space: nowrap;
}

.uni-app-tag {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  margin-right: 8px;
  white-space: nowrap;
}

.uni-app-tag--primary {
  background-color: #d0e3ff;
  color: #0066ff;
  border: 1px solid #99ccff;
}

.uni-app-tag--success {
  background-color: #dcf5e7;
  color: #00aa55;
  border: 1px solid #88ccaa;
}

.uni-app-tag--warning {
  background-color: #fff0d9;
  color: #cc8800;
  border: 1px solid #ffcc88;
}

.uni-app-tag--error {
  background-color: #ffd9dc;
  color: #ff3344;
  border: 1px solid #ff99aa;
}

.uni-app-tag--info {
  background-color: #e6e6e6;
  color: #666666;
  border: 1px solid #cccccc;
}

.uni-app-tag--default {
  background-color: #f4f4f4;
  color: #333;
  border: 1px solid #ddd;
}

.uni-app-tag-unmatch {
  margin-left: 4px;
  color: #999;
  font-size: 12px;
}
</style>