<template>
  <div class="tree-wrapper">
    <el-popover
      v-model="visible"
      :disabled="disabled"
      :placement="placement"
      trigger="click"
      @show="onPopoverShow"
    >
      <el-input
        v-if="filterable"
        ref="input"
        v-model="filterKeyWord"
        class="inputKey"
        size="small"
        placeholder="请输入"
        clearable
      />
      <div class="content-wrapper" ref="contentWrapper" :style="{maxHeight:popoverHeight}">
        <!-- ref为tree的name不能更改，因为文档里面用到了name -->
        <el-tree
          ref="tree"
          v-bind="{...$props, ...$attrs}"
          :show-checkbox="multiple"
          :draggable="false"
          @check="getChecked"
          @node-click="nodeClick"
          v-on="$listeners"
        />
      </div>
      <el-select
        ref="select"
        slot="reference"
        style="display:block"
        :value="currentSelectLabel"
        :disabled="disabled"
        :collapse-tags="collapseTags"
        remote
        :multiple="multiple"
        :placeholder="placeholder"
        clearable
        @remove-tag="removeTag"
        @clear="clearSelected"
      />
    </el-popover>
  </div>
</template>

<script>
import { Tree, Input, Popover, Select } from 'xl-element-ui'

export default {
  name: 'XlSelectTree',
  components: {
    elInput: Input,
    elPopover: Popover,
    elTree: Tree,
    elSelect: Select
  },
  props: {
    popoverHeight: {
      type: String,
      default: '360px'
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    placement: {
      type: String,
      default: 'bottom-start'
    },
    data: {
      type: Array,
      default() {
        return []
      }
    },
    props: {
      type: Object,
      default() {
        return {}
      }
    },
    disabled: Boolean,
    filterable: Boolean,
    multiple: Boolean,
    collapseTags: Boolean,
    /* eslint-disable */
    nodeKey: String,
    filterNodeMethod: Function,
    /* eslint-enable */
    value: {
      type: [String, Number, Array],
      default: ''
    }
  },
  data() {
    return {
      visible: false,
      filterKeyWord: '',
      selectedValue: [],
      unwatchValue: null
    }
  },
  computed: {
    currentSelectLabel() {
      const showLabel = this.selectedValue.map(item => item[this.props.label])// this.$attrs.props.defaultProps.label
      return this.multiple ? showLabel : showLabel.join('')
    }
  },
  watch: {
    filterKeyWord(val) {
      if (this.filterable) {
        if (!this.filterNodeMethod) throw new Error('[xl-select-tree] filterNodeMethod is required in filterable')
        this.$refs.tree.filter(val)
      }
    }
  },
  mounted() {
    if (this.multiple && !this.nodeKey) {
      throw new Error('[xl-select-tree] nodeKey is required in multiple')
    }
    this.init()
  },
  methods: {
    onPopoverShow() {
      this.filterKeyWord = ''
      this.$refs.contentWrapper.style.width = this.$refs.select.$el.clientWidth -30 + 'px'
    },
    clearSelected() {
      this.valueChange(this.multiple ? [] : '')
      this.selectedValue = []
    },
    getChecked() { // 多选模式下
      const list = this.$refs.tree.getCheckedNodes()
      const newVal = list.map(item => {
        /* eslint-disable */
        const { children, ...rest } = item
        /* eslint-enable*/
        return rest[this.nodeKey]
      })
      if(!this.multiple) {
        this.valueChange((newVal.filter(item=> item === this.value)[0]))
        return 
      }
      this.valueChange(newVal)
      this.selectedValue = list
    },
    removeTag(label) { // 取消选中 单个的节点
      const target = this.selectedValue.find(item => item[this.props.label] === label)
      this.$refs.tree.setChecked(target, false, true)
      this.getChecked()
    },
    nodeClick(value) { // 单选模式下获取value
      if (this.multiple) return
      /* eslint-disable */
      const { children, ...rest } = value
      /* eslint-enable*/
      this.valueChange(rest[this.nodeKey])
      this.selectedValue = [value]
      this.visible = false
    },
    getLabelBy(v) {
      const tree = this.$refs.tree
      if(typeof v === 'string') {
        this.$nextTick(() => {
          tree.setCheckedKeys([v])
          const list = tree.getCheckedNodes()
          const newVal = list.map(item => {
            /* eslint-disable */
            const { children, ...rest } = item
            /* eslint-enable*/
            return rest
          })
          this.selectedValue = newVal.filter(item => item[this.nodeKey] === v)
        })
      } else if(Array.isArray(v)) {
        this.$nextTick(() => {
          tree.setCheckedKeys(v)
          const list = tree.getCheckedNodes()
          const newVal = list.map(item => {
            /* eslint-disable */
            const { children, ...rest } = item
            /* eslint-enable*/
            return rest
          })
          this.selectedValue = newVal
        })
      }
    },
    valueChange(value) {
      // 所有的值更新入口在此
      this.$emit('input', value)
      this.$emit('change', value)
    },
    init() {
      this.unwatchValue = this.$watch('value', (v) => {
        if (v) {
          if(!this.nodeKey) {
            throw new Error('[xl-select-tree] nodeKey is required')
          }
          if (this.multiple && !Array.isArray(v)) {
            throw new Error('[xl-select-tree] value must be a Array')
          } else if (this.multiple && v.length === 0) {
            this.$nextTick(() => {
              this.$refs.tree.setCheckedKeys([])
            })
          } else {
            this.getLabelBy(v)
          }
        } else {
          this.selectedValue = []
        }
      }, {
        deep: true,
        immediate: true
      })
    }
  },
  beforeDestory() {
    if (this.unwatchValue && typeof this.unwatchValue === 'function') {
      this.unwatchValue()
    }
  }
}
</script>

<style scoped>
.wrapper {
  border: 1px solid #d9d9d9;
  border-radius: 4px;
}
.inputKey {
  margin-bottom: 6px;
}
.content-wrapper {
  overflow-y: scroll;
}
.content-wrapper::-webkit-scrollbar {
  width: 4px;
  height: 4px;
  background-color: #f0f0f0;
}
.content-wrapper::-webkit-scrollbar-track {
  border-radius: 10px;
  background-color: #f5f5f5;
}
.content-wrapper::-webkit-scrollbar-thumb {
  /*width: 10px;*/
  height: 10px;
  border-radius: 10px;
  box-shadow: inset 0 0 6px rgba(102, 102, 102, 0.3);
}
.tree-wrapper >>> .el-select .el-input .el-select__caret.is-reverse {
  transform: rotateZ(180deg);
}
</style>
