<template>
  <el-select
    v-model="modelObj"
    :clearable="props.clearable"
    :remote="props.remote"
    :id="props.id"
    :remote-method="xcMethod"
    :style="{ width: props.width + 'px' }"
    ref="selectRef"
    filterable
    @change="el => changeStaff(el)"
    @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 setup>
import { debounce } from "@/utils/debounce";
import { stringNotBlank } from "@/utils/blank-utils";
import { onMounted, watch } from "vue";
import useCompRef from "@/utils/useCompRef";
import { ElSelect } from "element-plus";

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"]);

const modelObj = ref(null);
const selectRef = useCompRef(ElSelect);
const optionList = ref([]);
const colorList = {
  primary: "#409eff",
  danger: "#f56c6c",
  info: "#8492a6",
  success: "#67C23A",
  warning: "#E6A23C",
};

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

const clear = () => {
  modelObj.value = 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.value = props.modelValue[props.name[0]];
    let len = props.data.length;
    if (len === 0) {
      method(modelObj.value);
    }
    for (let i = 0; i < len; i++) {
      if (modelObj.value === props.data[i].code) {
        return;
      }
    }
    method(modelObj.value);
  }
);

const method = value => {
  emit("method", value);
};

const focus = () => {
  selectRef.value.focus();
};

const blur = () => {
  selectRef.value.blur();
};

defineExpose({ focus, blur });

onMounted(() => {
  nextTick(() => {
    modelObj.value = 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.value.push(data);
      }
    }
  }
});
</script>

<style scoped></style>
