<template>
  <div class="sy-select-tree" :style="widthObj" v-clickoutside="handleClickOutside">
    <el-input
      v-bind:value="selectedNode.nodeName"
      @click.native="toggleVisible"
      :disabled="disabled"
      size="small"
      :placeholder="placeholder"
      clearable
      @clear="clearSelectedNode"
    />
    <div class="tree-wrapper" :style="heightObj" v-show="visible">
      <sy-search-tree
        ref="ztreeRef"
        :setting="ztreeSetting"
        :nodes="nodes"
        :placeholder="searchPlaceholder"
        @onClick="onClick"
        @onCreated="handleCreated"
        @searchTree="searchTree"
        :beforeClickFn="beforeClickFn"
      />
    </div>
  </div>
</template>

<script>
import merge from 'deepmerge'
import searchTree from '../../search-tree'
import Clickoutside from 'element-ui/src/utils/clickoutside'

export default {
  name: 'SySelectTree',
  components: {
    SySearchTree: searchTree
  },
  directives: { Clickoutside },
  data() {
    const defaultSetting = {
      check: {
        enable: false
      },
      data: {
        // 设置图标库(采用iconfont class形式)
        iconMap: {
          1: 'icon-jituan',
          2: 'icon-quyufengongsi',
          3: 'icon-fengongsi',
          4: 'icon-guanlichu',
          5: 'icon-xiangmujiedian',
          6: 'icon-quyujiedian',
          7: 'icon-loudong',
          8: 'icon-danyuan',
          9: 'icon-fangjian'
        },
        // 设置对应每个节点的节点类型，与数据中customType对应(25行)
        key: {
          idKey: 'nodeId',
          nodeType: 'customType',
          name: 'nodeName',
          title: 'nodeName',
          children: 'childList'
        }
      },
      view: {
        // 开启图标显示功能
        showIcon: true
      }
    }
    const mergeSetting = merge(defaultSetting, this.setting)
    return {
      visible: false,
      selectedNode: {
        nodeId: '',
        nodeName: ''
      },
      ztreeObj: null,
      ztreeSetting: mergeSetting
    }
  },
  props: {
    disabled: {
      type: Boolean,
      default: false
    },
    width: {
      type: [Number, String],
      default: () => {
        return '100%'
      }
    },
    height: {
      type: [Number, String],
      default: () => {
        return '200px'
      }
    },
    setting: {
      type: Object,
      required: false,
      default: () => ({})
    },
    nodes: {
      type: Array,
      default: () => []
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    searchPlaceholder: {
      type: String,
      default: '请输入搜索关键字'
    },
    beforeClick: { type: Function } // 选中节点之前的处理事件，如不允许选择nodeType='2'的节点
  },
  computed: {
    widthObj() {
      if (this.width === '100%') {
        return { width: '100%' }
      }
      const width = parseInt(this.width)
      return { width: width + 'px' }
    },
    heightObj() {
      if (this.height === '100%') {
        return { height: '100%' }
      }
      const height = parseInt(this.height)
      return { height: height + 'px' }
    }
  },
  methods: {
    toggleVisible() {
      if (this.disabled) return
      this.visible = !this.visible
    },
    beforeClickFn(arg) {
      return this.beforeClick(arg)
    },
    onClick: function(evt, treeId, treeNode) {
      this.selectedNode = { ...treeNode }
      this.visible = false
      this.$emit('click', this.selectedNode)
    },
    onCheck: function(evt, treeId, treeNode) {
      // 选中事件
      console.log(evt.type, treeNode)
    },
    handleCreated: function(ztreeObj) {
      this.ztreeObj = ztreeObj
      // onCreated 中操作ztreeObj对象展开第一个节点
      ztreeObj.expandNode(ztreeObj.getNodes()[0], true)
    },
    searchTree(keyword) {
      // 关键字搜索
      this.$emit('search', keyword)
    },
    setSelectedNode(selectedKey) {
      // 设置默认选中的节点
      setTimeout(() => {
        this.$refs.ztreeRef.setSelectedNode(selectedKey)
      }, 20)
    },
    setCheckedNodes(checkedKeys) {
      setTimeout(() => {
        this.$refs.ztreeRef.setCheckedNodes(checkedKeys)
      }, 20)
    },
    clearSelectedNode() {
      this.selectedNode = {
        nodeId: '',
        nodeName: ''
      }
      this.$refs.ztreeRef.cancelAllSelectedNode()
      this.$emit('click', this.selectedNode)
    },
    handleClickOutside() {
      this.visible = false
    }
  }
}
</script>

<style lang="scss" scoped>
.sy-select-tree {
  position: relative;
  z-index: 20;
  .tree-wrapper {
    position: absolute;
    left: 0;
    right: 1px;
    top: 34px;
    border: 1px solid #ccc;
    background: #fff;
    padding-bottom: 8px;
  }
}
</style>
