<template>
  <div>
    <template v-for="(item, index) in matchedOptions" :key="item.dictValue">
      <span v-if="plain" :index="index">
        {{ item.dictLabel }}
        <span v-if="index < matchedOptions.length - 1 && !wholeMatch" style="margin-left: 4px;">,</span>
      </span>
      <template v-else>
        <span
          v-if="(item.raw?.listClass === 'default' || item.raw?.listClass === '') && (item.raw?.cssClass === '' || item.raw?.cssClass == null)"
          :index="index"
          :class="item.raw?.cssClass"
        >{{ item.dictLabel }}</span>
        <el-tag
          v-else
          :disable-transitions="true"
          :index="index"
          :class="item.raw?.cssClass"
        >
          {{ item.dictLabel }}
        </el-tag>
      </template>
    </template>
    <template v-if="unmatch && showValue">
      {{ handleArray(unmatchArray) }}
    </template>
  </div>
</template>

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

interface DictOption {
  dictValue: string | number
  dictLabel: string
  raw?: {
    listClass?: string
    cssClass?: string
  }
}

interface Props {
  options: DictOption[]
  dictValue?: number | string | Array<number | string>
  showValue?: boolean
  separator?: string
  plain?: boolean  // 添加plain属性控制是否显示为普通文本
  wholeMatch?: boolean // 是否将逗号分隔的值作为整体匹配，而不是拆分成多个值
}

const props = withDefaults(defineProps<Props>(), {
  options: () => [],
  showValue: true,
  separator: ',',
  plain: true,  // 默认不显示tag样式
  wholeMatch: false // 默认拆分为多个值匹配
})

const unmatchArray = ref<Array<string | number>>([])

// 计算属性：根据wholeMatch决定如何处理value
const values = computed(() => {
  if (props.dictValue === null || typeof props.dictValue === 'undefined' || props.dictValue === '') return []

  if (props.wholeMatch) {
    // 整体匹配模式：直接返回原始值，不进行拆分
    return Array.isArray(props.dictValue)
      ? props.dictValue.map(item => String(item))
      : [String(props.dictValue)]
  } else {
    // 拆分匹配模式：按分隔符拆分
    return Array.isArray(props.dictValue)
      ? props.dictValue.map(item => String(item))
      : String(props.dictValue).split(props.separator)
  }
})

// 计算属性：获取匹配的选项
const matchedOptions = computed(() => {
  // 如果是整体匹配模式，直接查找完全相等的值
  if (props.wholeMatch) {
    const matched = props.options.filter(item =>
      values.value.some(value => String(item.dictValue) === value)
    )
    // 如果没有匹配项，显示原始值
    if (matched.length === 0 && values.value.length > 0) {
      return [{
        dictValue: values.value[0],
        dictLabel: values.value[0],
        raw: undefined
      }]
    }
    return matched
  } else {
    // 拆分匹配模式：每个值单独匹配
    return props.options.filter(item =>
      values.value.includes(String(item.dictValue))
    )
  }
})

// 计算属性：是否有未匹配的值
const unmatch = computed(() => {
  // eslint-disable-next-line vue/no-side-effects-in-computed-properties
  unmatchArray.value = []

  // 没有value不显示
  if (props.dictValue === null || typeof props.dictValue === 'undefined' || props.dictValue === '' || props.options.length === 0) {
    return false
  }

  // 如果是整体匹配模式，不需要显示未匹配值（因为已经显示原始值）
  if (props.wholeMatch) {
    return false
  }

  // 检查是否有未匹配项（仅拆分模式）
  let hasUnmatch = false
  values.value.forEach(item => {
    if (!props.options.some(v => String(v.dictValue) === item)) {
      unmatchArray.value.push(item)
      hasUnmatch = true
    }
  })

  return hasUnmatch
})

// 处理数组显示的方法
const handleArray = (array: Array<string | number>): string => {
  if (array.length === 0) return ''
  return array.reduce((pre: string, cur: string | number) => {
    return pre + ' ' + cur
  }, '').trim()
}
</script>

<style scoped>
.el-tag + .el-tag {
  margin-left: 10px;
}
</style>
