<template>
  <span v-if="isLook">{{ select_look || '-' }}</span>
  <el-checkbox-group v-model="select" :disabled="disabled" v-else>
    <template #default>
      <el-checkbox
        v-for="item in options"
        :key="item[field.value]"
        :value="item[field.value]"
        :label="item[field.label]"
      />
      <el-input
        v-model="other"
        v-if="showInput"
        :disabled="disabled"
        placeholder="请输入其他内容"
        @change="inputChange"
      />
    </template>
  </el-checkbox-group>
</template>

<script setup lang="ts">
import { useOptions } from '../hooks/useOptions'
import { ref, computed, watch } from 'vue'

const props = defineProps({
  modelValue: {
    type: [Array<string>],
    default: () => []
  },
  mode: {
    type: String,
    default: 'add'
  },
  formItem: {
    type: Object,
    default: () => {}
  },
  disabled: {
    type: Boolean,
    default: false
  }
})
const emits = defineEmits(['update:modelValue'])

const { options, field, isLook } = useOptions(props, emits)

// 其它 的功能
const other = ref('')
// 其它 这个选项的内容 主要用来筛选那个属于 其它 项
const otherItem = ref()
const showInput = ref(false)
// 记录用于表单的值
const formVal = ref<string[]>([])
const findOther = () => {
  // 如果包含其它项 记下来 用于之后的匹配
  const item = options.find((i) => i[field.label] === '其它')
  otherItem.value = item
}

watch(
  () => options,
  (val) => {
    if (val?.length) {
      findOther()
    }
  },
  {
    immediate: true
  }
)

const select = computed({
  get() {
    return props.modelValue
  },
  set(val) {
    // 显示输入框
    showInput.value = val.includes(otherItem.value?.[field.value])
    // 当其他项 被取消 则删除other字段
    if (!showInput.value && hasOtherField(val).has) {
      removeOtherField(val)
    }

    // 如果选择了其它 并且输入了内容 则拼装
    formVal.value =
      showInput.value && other.value && !hasOtherField(val).has
        ? [...(val as Array<string>), `other:${other.value}`]
        : val

    emits('update:modelValue', formVal.value)
  }
})

// 详情状态下的显示字段
const select_look = ref('')
watch(
  () => select.value,
  (val) => {
    if (val) {
      // 详情的字段拼接
      if (isLook) {
        const other_look = val.find((i) => i.includes('other:'))
        select_look.value = (other_look ? val.filter((i) => !i.includes('other:')) : val)
          .map((i) => {
            return i === otherItem.value[field.value] && other_look
              ? `${otherItem.value[field.label]}：${other_look.split(':')[1]}`
              : options.find((j) => j[field.value] === i)[field.label]
          })
          .join('，')
      }

      formVal.value = val
      if (val.includes(otherItem.value?.[field.value])) {
        showInput.value = true

        const otherText = val.find((i) => i.includes('other:'))
        if (otherText) {
          other.value = otherText.split(':')[1]
        }
      }
    }
  },
  {
    immediate: true
  }
)

const inputChange = (val) => {
  /**
   * 当最后勾选其他 然后再输入时 输入的值无法被绑定的
   * 所以需要再输入完成后 收到绑定一次
   */

  //  如果已经有other字段 移除
  if (hasOtherField(formVal.value).has) {
    removeOtherField()
  }

  if (val) {
    formVal.value = [...formVal.value, `other:${other.value}`]

    emits('update:modelValue', formVal.value)
  }
}

const hasOtherField = (val) => {
  if (val.length && val.find((i) => i.includes('other:'))) {
    const index = val.findIndex((i) => i.includes('other:'))
    return {
      index,
      has: true
    }
  }
  return {
    has: false
  }
}
// 移除other：部分
const removeOtherField = (val: undefined | Array<string> = undefined) => {
  ;(val || formVal.value).splice(hasOtherField(val || formVal.value).index, 1)
}
</script>
