<template>
  <div
    class="property-tree-select el-select el-select--medium"
    @click="switchOpen"
  >
    <div
      :class="[
        'el-input el-input--medium el-input--suffix',
        { 'is-focus': isFocus },
      ]"
      @mouseenter="inputHovering = true"
      @mouseleave="inputHovering = false"
    >
      <input
        ref="inputRef"
        type="text"
        autocomplete="off"
        :placeholder="placeholder"
        class="el-input__inner"
        :value="selectedPropName"
        readonly
      />
      <span class="el-input__suffix">
        <span class="el-input__suffix-inner">
          <i
            v-show="!showClose"
            :class="[
              'el-select__caret',
              'el-input__icon',
              'el-icon-arrow-up',
              { 'is-reverse': visible },
            ]"
          ></i>
          <i
            v-if="showClose"
            class="el-select__caret el-input__icon el-icon-circle-close"
            @click="handleClearClick"
          ></i>
        </span>
      </span>
    </div>

    <el-popover
      v-model="visible"
      popper-class="property-popover"
      placement="bottom"
      trigger="manual"
    >
      <div ref="popoverRef" slot="reference"></div>
      <div v-clickoutside="handleClose" class="property-popover-tree">
        <el-tree
          ref="PropertyTree"
          :data="proptree"
          default-expand-all
          show-checkbox
          node-key="id"
          :props="defaultProps"
          :check-strictly="true"
          check-on-click-node
          :expand-on-click-node="false"
          @check-change="checkChange"
        >
          <span slot-scope="{ data }" :class="['custom-tree-node']">
            <span v-if="!data.code">{{ data.name }}</span>
            <span v-else>[{{ data.code }}]{{ data.name }}</span>
          </span>
        </el-tree>
      </div>
    </el-popover>
  </div>
</template>

<script>
import { propertyTreeQueryApi, propertyNameQueryApi } from "../api";
import Clickoutside from "element-ui/src/utils/clickoutside";

export default {
  name: "PropertyTreeSelect",
  directives: { Clickoutside },
  props: {
    value: {
      type: [Array, String],
      default: "",
    },
    placeholder: { type: String, default: "请选择" },
    multiple: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    clearable: {
      type: Boolean,
      default: true,
    },
    courseId: {
      type: [String, Number],
      default: "",
    },
  },
  data() {
    return {
      selectedPropName: "",
      selectedPropList: [],
      selectedPropIds: [],
      visible: false,
      isFocus: false,
      inputHovering: false,
      proptree: [],
      defaultProps: {
        children: "propertyList",
        disabled: "disabled",
      },
    };
  },
  computed: {
    showClose() {
      let hasValue = this.multiple
        ? Array.isArray(this.value) && this.value.length > 0
        : this.value !== undefined && this.value !== null && this.value !== "";
      let criteria = this.clearable && this.inputHovering && hasValue;
      return criteria;
    },
  },
  watch: {
    value(val, oldval) {
      if (val !== oldval) this.initSelected(val);
    },
    courseId(val, oldval) {
      if (val !== oldval) {
        this.resetData();
        this.emitChange();
        this.getList();
      }
    },
  },
  methods: {
    resetData() {
      this.selectedPropName = "";
      this.selectedPropList = [];
      this.selectedPropIds = [];
      this.visible = false;
      this.isFocus = false;
      this.inputHovering = false;
      this.proptree = [];
    },
    async getList() {
      if (!this.courseId) return;
      const res = await propertyNameQueryApi(this.courseId);
      let propList = res.data || [];
      const fetchAll = propList.map((item) => propertyTreeQueryApi(item.id));
      const datas = await Promise.all(fetchAll).catch(() => {});
      if (!datas) return;

      this.proptree = propList.map((item, index) => {
        let nitem = { ...item, disabled: true };
        nitem.propertyList = datas[index].data;
        return nitem;
      });
      if (this.value) this.initSelected(this.value);
    },
    switchOpen() {
      if (this.visible) {
        this.handleClose();
      } else {
        this.handleOpen();
      }
    },
    handleOpen() {
      this.isFocus = true;
      setTimeout(() => {
        this.visible = true;
      }, 100);
    },
    handleClose() {
      this.visible = false;
      this.isFocus = false;
    },
    initSelected(val) {
      this.$refs.PropertyTree.setCheckedKeys(val);
    },
    handleClearClick(event) {
      event.stopPropagation();
      this.$refs.PropertyTree.setCheckedKeys([]);
      this.selectedPropName = "";
      this.emitChange();
      this.handleClose();
    },
    checkChange() {
      const nodes = this.$refs.PropertyTree.getCheckedNodes(true);
      this.selectedPropName = nodes.map((item) => item.name).join("；");
      this.emitChange();
    },
    emitChange() {
      this.selectedPropIds = this.$refs.PropertyTree.getCheckedKeys();
      this.$emit("input", this.selectedPropIds);
      this.$emit("change", this.selectedPropIds);
    },
  },
};
</script>

<style lang="scss">
.property-popover {
  &.el-popover {
    width: 300px;
    padding: 0;
  }

  &-tree {
    max-height: 300px;
    overflow: auto;
    padding: 10px;
  }
}
</style>
