<template>
  <el-select
    :value="displayValue"
    multiple
    filterable
    clearable
    :filter-method="handleFilter"
    @input="handleInput"
    @visible-change="handleVisibleChange">
    <el-option
      v-if="!query || filteredOptions.length"
      :value="0"
      :label="allLabel">
    </el-option>
    <el-option
      v-for="item in filteredOptions"
      :key="item.id"
      :value="item.id"
      :label="item.name">
    </el-option>
  </el-select>
</template>

<script>
// 票种多选下拉：支持搜索过滤，且可通过顶部“全部票种”选项一键全选当前搜索结果
// 对外的 v-model 只包含真实票种id（不含“全部”标记0），页面可直接提交
export default {
  name: 'TicketTypeSelect',
  props: {
    value: {
      type: Array,
      default: () => []
    },
    // 票种列表，由外部传入（支持页面按订单类型等先过滤）
    options: {
      type: Array,
      default: () => []
    }
  },
  data () {
    return {
      query: ''
    }
  },
  computed: {
    // 当前搜索词过滤后的票种
    filteredOptions () {
      if (!this.query) return this.options
      const q = String(this.query).toLowerCase()
      return this.options.filter(i => i.name && String(i.name).toLowerCase().includes(q))
    },
    // 是否已全选（全部票种都在已选值中）
    allChecked () {
      return this.options.length > 0 && this.options.every(i => this.value.includes(i.id))
    },
    allLabel () {
      return this.query ? `全选搜索结果(${this.filteredOptions.length})` : '全部票种'
    },
    // 全选时附加“全部票种”标记用于展示，兼容历史数据中可能存在的0
    displayValue () {
      const realIds = this.value.filter(id => id !== 0)
      return this.allChecked ? [0, ...realIds] : realIds
    }
  },
  methods: {
    handleFilter (q) {
      this.query = q
    },
    handleVisibleChange (visible) {
      if (!visible) this.query = ''
    },
    handleInput (val) {
      val = Array.isArray(val) ? val : []
      const emitVal = (v) => {
        this.$emit('input', v)
        this.$emit('change', v)
      }

      // 清空
      if (!val.length) {
        emitVal([])
        return
      }

      const hadAll = this.allChecked
      const hasAll = val.includes(0)

      if (hasAll && !hadAll) {
        // 勾选“全选”：选中当前搜索结果内的全部票种（保留之前已勾选项）
        const visibleIds = this.filteredOptions.map(i => i.id)
        emitVal(Array.from(new Set([...this.value.filter(id => id !== 0), ...visibleIds])))
      } else if (hadAll && !hasAll) {
        // 取消“全选”：有搜索词时仅移除当前展示的票种，无搜索词时全部清空
        if (this.query) {
          const visibleIds = this.filteredOptions.map(i => i.id)
          emitVal(this.value.filter(id => id !== 0 && !visibleIds.includes(id)))
        } else {
          emitVal([])
        }
      } else {
        // 普通勾选/取消勾选，或在全选状态下取消某一项（此时去掉全选标记）
        emitVal(val.filter(id => id !== 0))
      }
    }
  }
}
</script>
