<template>
  <el-select v-model="modelObj"
             :clearable="props.clearable"
             :remote="props.remote"
             :id="props.id"
             :remote-method="xcMethod"
             :style="{width: props.width + 'px'}"
             ref="xcselect"
             filterable
             @change="changeStaff"
             @clear="clear"
             @focus="getFocus">
    <el-option v-for="(item,index) in props.data"
               :key="item.index"
               :label="item.name"
               :value="item.code">
      <template v-for="(opitem,index) in optionList" v-if="optionList.length > 0">
        <el-divider v-if="index !== 0" direction='vertical'></el-divider>
        <span :style="opitem.style">{{ item[opitem.label] }}</span>
      </template>
      <template v-else>
        <span>{{ item.code }}</span>
        <el-divider direction='vertical'></el-divider>
        <span>{{ item.name }}</span>
      </template>
    </el-option>
  </el-select>
</template>

<script name="XcSelect" setup>
import {debounce} from "@/utils/debounce";
import {stringNotBlank} from "@/utils/blank-utils";
import {onMounted, watch} from 'vue'

const props = defineProps({
  modelValue: {
    type: Object,
  },
  name: {
    type: Array,
    default: ['code', 'name']
  },
  width: {
    type: Number,
    default: 120
  },
  data: {
    type: Array,
    default: []
  },
  remote: {
    type: Boolean,
    default: false
  },
  clearable: {
    type: Boolean,
    default: false
  },
  id: {
    type: String
  }
})

const emit = defineEmits(['method', 'change', 'focus'])

let modelObj = $ref(null)
let xcselect = $ref()
let optionList = $ref([])
const colorList = {
  'primary': '#409eff',
  'danger': '#f56c6c',
  'info': '#8492a6',
  'success': '#67C23A',
  'warning': '#E6A23C'
}

const changeStaff = () => {
  nextTick(() => {
    props.modelValue[props.name[0]] = xcselect?.selected?.value
    props.modelValue[props.name[1]] = xcselect?.selected?.currentLabel
  })
  emit('change', props.data.find((i) => i.code === modelObj))
}

const clear = () => {
  modelObj = null
  props.modelValue[props.name[0]] = null
  props.modelValue[props.name[1]] = null
}

const xcMethod = debounce(value => {
  if (stringNotBlank(value) && value.length > 1) {
    method(value)
  }
}, 400)

const getFocus = () => {
  emit('focus')
}

/**
 * 监听父组件的值是否改变
 * 如果改变了那么就，要执行查询动作
 * 如果 props.data 里面有值了就不用查询
 * props.data 里面没有值对得上那就需要执行查询动作了
 *
 */
watch(() => props.modelValue[props.name[0]], () => {
  modelObj = props.modelValue[props.name[0]]
  let len = props.data.length
  if (len === 0) {
    method(modelObj)
  }
  for (let i = 0; i < len; i++) {
    if (modelObj === props.data[i].code) {
      return
    }
  }
  method(modelObj)
})

const method = (value) => {
  emit('method', value)
}

const focus = () => {
  xcselect.focus()
}

const blur = () => {
  xcselect.blur()
}

defineExpose({focus, blur})

onMounted(() => {

  nextTick(() => {
    modelObj = props.modelValue[props.name[0]]
  })

  // 判断组件是否使用了 slot
  if (!!useSlots().default) {
    // 判断 slot 有没有想要的值
    for (let item of useSlots().default()) {
      if (item.props !== null) {
        let style = {}
        if (typeof item.props.style === 'undefined') {
          if (typeof item.props.type === 'undefined') {
            style = {'color': '#8492a6'}
          } else {
            style = {'color': colorList[item.props.type]}
          }
        } else {
          style = item.props.style
        }
        let data = {
          label: item.props.label,
          style: style,
        }
        optionList.push(data)
      }
    }
  }
})

</script>

<style scoped>

</style>
