<template>
  <LabelBox
    :label="formItems.attrs?.label"
    :need-star="formItems.attrs?.needStar"
    :width="formItems.attrs?.width"
  >
    <el-select
      ref="select"
      v-model="value"
      size="mini"
      :multiple="false"
      :placeholder="formItems.attrs?.placeholder || '请选择'"
      :clearable="formItems.clearable || true"
      style="width: 100%"
      v-bind="formItems.attrs"
      v-on="formItems.events"
    >
      <el-option
        ref="option"
        class="tree-select__option"
        :value="optionData.value"
        :label="optionData.label"
      >
        <el-tree
          ref="tree"
          class="tree-select__tree"
          :class="`tree-select__tree--${
            formItems.attrs?.multiple ? 'checked' : 'radio'
          }`"
          :node-key="nodeKey"
          :data="formItems.options"
          :props="props"
          :show-checkbox="formItems.attrs?.multiple || false"
          :highlight-current="!formItems.attrs?.multiple || false"
          :expand-on-click-node="formItems.attrs?.multiple || false"
          :filter-node-method="filterNode"
          @node-click="handleNodeClick"
          @check-change="handleCheckChange"
        />
      </el-option>
    </el-select>
  </LabelBox>
</template>

<script>
import LabelBox from '../labelBox/index.vue';

export default {
  name: 'TreeSelect',
  components: {
    LabelBox,
  },
  props: {
    formItems: {
      type: Object,
      default: () => {},
    },
    value: {
      type: String,
      default: '',
    },
    multiple: {
      type: Boolean,
      default: true,
    },
    // 每个树节点用来作为唯一标识的属性
    nodeKey: {
      type: [String, Number],
      default: 'id',
    },
    filterable: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    // tree的props配置
    props: {
      type: Object,
      default: function() {
        return {
          label: 'label',
          children: 'children',
        };
      },
    },
  },
  data() {
    return {
      optionData: {
        value: '',
        label: '',
      },
    };
  },
  watch: {
    value: {
      handler(val) {
        if (this.formItems.prop && val) {
          this.init(val);
        }
      },
      immediate: true,
      deep: true,
    },
    formItems: {
      handler(val) {
        if (this.formItems.prop && val) {
          this.init(val);
        }
      },
      immediate: true,
      deep: true,
    },
  },
  created() {},
  methods: {
    init(val) {
      // 多选
      if (this.formItems.attrs?.multiple) {
        const arr = val.toString().split(',');
        this.$nextTick(() => {
          this.$refs.tree.setCheckedKeys(arr);
          const nodes = this.$refs.tree.getCheckedNodes();
          this.optionData.value = val;
          this.optionData.label = nodes
            .map((item) => item[this.props.label])
            .join(',');
        });
      }
      // 单选
      else {
        val = val === '' ? null : val;
        this.$nextTick(() => {
          this.$refs.tree.setCurrentKey(val);
          if (val === null) {
            return;
          }
          const node = this.$refs.tree.getNode(val);
          this.optionData.value = val;
          this.optionData.label = node.label;
        });
      }
    },
    handleNodeClick(data) {
      if (this.formItems.attrs?.multiple) {
        return;
      }
      this.$emit('input', data[this.nodeKey]);
      this.$emit('outOperation', data[this.nodeKey]);
      this.$refs.select.visible = false;
    },
    handleCheckChange() {
      const nodes = this.$refs.tree.getCheckedNodes();
      const value = nodes.map((item) => item[this.nodeKey]).join(',');
      this.$emit('input', value);
      this.$emit('outOperation', value);
    },
    filterMethod(val) {
      this.$refs.tree.filter(val);
    },
    filterNode(value, data) {
      if (!value) return true;
      const label = this.props.label || 'label';
      return data[label].indexOf(value) !== -1;
    },
  },
};
</script>

<style lang="scss" scoped>
.tree-select__option {
  &.el-select-dropdown__item {
    height: auto;
    line-height: 1;
    padding: 0;
    background-color: #fff;
  }
}

.tree-select__tree {
  padding: 4px 0px;
  font-weight: 400;
  &.tree-select__tree--radio {
    .el-tree-node.is-current > .el-tree-node__content {
      font-weight: 700;
      color: #ff0000;
    }
  }
}

::v-deep.el-select .el-input__icon {
  height: 24px;
  line-height: 25px;
}

::v-deep.el-select .el-input-group__prepend {
  box-sizing: border-box;
  padding: 0 10px;
  height: 24px;
  line-height: 24px;
  border: none;
}

::v-deep.el-select .el-input__inner {
  height: 24px;
  line-height: 24px;
}
</style>
