<template>
  <div class="air-tree-wrappers dg-tree">
    <div class="el-dialog__title">{{ title }}</div>
    <div>
      <el-input
        v-if="screen"
        v-model="filterText"
        class="input"
        :placeholder="placeholder"
        prefix-icon="el-icon-search"
        @input="changeFilterText"
      >
      </el-input>
      <el-tree
        ref="tree"
        class="filter-tree"
        :highlight-current="true"
        :data="treeList"
        :props="defaultProps"
        :show-checkbox="checkbox"
        :expand-on-click-node="expandOnClickNode"
        :default-expand-all="defaultExpandAll"
        :default-checked-keys="defaultCheckedKeys"
        :default-expanded-keys="defaultExpandedKeys"
        :filter-node-method="filterNode"
        :render-content="sonRenderContent"
        :lazy="lazy"
        :check-strictly="checkStrictly"
        :current-node-key="currentNodeKey"
        :load="load"
        :accordion="accordion"
        :draggable="draggable"
        :allow-drop="allowDrop"
        :allow-drag="allowDrag"
        :query-terms="queryTerms"
        :node-key="nodeKey"
        @node-drag-start="handleDragStart"
        @node-drag-enter="handleDragEnter"
        @node-drag-leave="handleDragLeave"
        @node-drag-over="handleDragOver"
        @node-drag-end="handleDragEnd"
        @node-drop="handleDrop"
        @check-change="check"
        @node-click="nodeclick"
        @contextmenu.native="contextmenu"
      >
      </el-tree>
      <dg-contextmenu :context-menu-data="contextMenuData" @createRootNode="createRootNode"> </dg-contextmenu>
      <div class="foot"></div>
    </div>
  </div>
</template>

<script lang="jsx">
export default {
  name: 'DgTree',

  props: {
    treeListData: {
      type: Array,
      default: () => [],
    },
    apiCode: {
      type: String,
      default: () => '',
    },
    root: {
      type: String,
      default: () => '',
    },
    pnodeKey: {
      type: String,
      default: () => '',
    },
    placeholder: {
      type: String,
      default: () => '',
    },
    data: {
      type: Array,
      default: () => [],
    },
    queryTerms: {
      type: [String, Object],
      default: () => '',
    },
    defaults: {
      type: Array,
      default: () => [],
    },
    showCheckbox: {
      type: Boolean,
      default: () => false,
    },
    width: {
      type: String,
      default: () => '',
    },
    title: {
      type: String,
      default: () => '',
    },
    nodeKey: {
      type: String,
      default: () => '',
    },
    label: {
      type: String,
      default: () => '',
    },
    lazy: {
      type: Boolean,
      default: () => false,
    },
    accordion: {
      type: Boolean,
      default: () => false,
    },
    draggable: {
      type: Boolean,
      default: () => false,
    },
    rootVal: {
      type: Boolean,
      default: () => false,
    }, // 是否显示根节点
    load: {
      type: Function,
      default: (node, resolve) => {
        return resolve([])
      },
    },
    showScreen: {
      type: Boolean,
      default: () => false,
    },
    expandOnClickNode: {
      type: Boolean,
      default: () => true,
    },
    defaultExpandAll: {
      type: Boolean,
      default: () => false,
    },
    defaultCheckedKeys: {
      type: Array,
      default: () => [],
    },
    currentNodeKey: {
      type: String,
      default: () => '',
    },
    renderContent: {
      type: Function,
      default: null,
    },
    allowDrop: {
      type: Function,
      default: (draggingNode, dropNode, type) => {
        return true
      },
    },
    allowDrag: {
      type: Function,
      default: (draggingNode) => {
        return true
      },
    },
    nodeButtons: {
      type: Array,
      default: () => [],
    },
    checkStrictly: {
      type: Boolean,
      default: () => false,
    },
    defaultExpandedKeys: {
      type: Array,
      default: () => [],
    },
    // 是否显示全部节点
    showAllnode: {
      type: Boolean,
      default: true,
    },
    // 不是父子结构的平铺数据
    listData: {
      type: Array,
      default: () => [],
    },
    requestData: {
      type: Object,
      default: () => ({}),
    },
    filterChild: {
      type: Boolean,
      default: true,
    },
  },

  data() {
    return {
      treeList: [],
      filterText: '',
      countent: '',
      checkbox: this.showCheckbox,
      defaultProps: {
        children: 'children',
        label: this.label,
        isLeaf: 'leaf',
      },
      data1: [],
      dialogTableVisible: false,
      screen: this.showScreen,
      sonRenderContent: null,
      treeListRes: null,
      contextMenuData: {
        menuName: 'createRoot',
        axis: {
          x: null,
          y: null,
        },
        // Menu options (菜单选项)
        menulists: [
          {
            fnHandler: 'createRootNode', // Binding events(绑定事件)
            btnName: '新建根目录', // The name of the menu option (菜单名称)
          },
        ],
      },
    }
  },

  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    },
    root(val) {
      this.getData()
    },
    // treeListData (val) {
    //   this.treeList = this.treeListData
    // }
    treeListData: {
      deep: true,
      handler(val) {
        this.treeList = val
      },
    },
    treeList: {
      deep: true,
      handler: function (newVal, oldVal) {
        this.$emit('update:treeListData', newVal)
      },
    },
    listData(val) {
      if (!this.apiCode) {
        this.treeList = this.getTreeList(val)
      }
    },
  },

  mounted() {
    this.sonRenderContent = (h, { node, data, store }) => {
      let nodeIcon = ''
      if (data.children) {
        nodeIcon = 'el-icon-folder'
      } else {
        nodeIcon = 'el-icon-document'
      }
      // judge自定义展示与否
      return this.nodeButtons.length && node.key ? (
        <el-popover placement="right" trigger="hover" popper-class="dg-tree__popover">
          <span>
            {this.nodeButtons.map((button) => {
              return (
                <el-button
                  v-show={!button.judge || button.judge(h, { node, data, store })}
                  type="text"
                  size="mini"
                  title={button.title}
                  icon={button.icon}
                  on-click={() => button.fn(h, { node, data, store })}
                ></el-button>
              )
            })}
          </span>
          <span class="custom-tree-node" slot="reference">
            <span>
              <i class={nodeIcon}></i>
              <span style="padding-left:10px; font-size: 12px;">{node.label}</span>
            </span>
          </span>
        </el-popover>
      ) : (
        <span class="custom-tree-node" slot="reference">
          <span>
            <i class={nodeIcon}></i>
            <span style="padding-left:10px; font-size: 12px;">{node.label}</span>
          </span>
        </span>
      )
    }
    if (this.renderContent) this.sonRenderContent = this.renderContent
  },

  created() {
    if (this.apiCode != '') {
      this.getData()
    } else if (this.treeListData.length > 0) {
      this.treeList = this.treeListData
    } else if (this.listData.length > 0) {
      this.treeList = this.getTreeList(this.listData)
    }
  },

  methods: {
    // 获取数据
    async getData() {
      let queryTermsObj = {}
      if (this.queryTerms) {
        queryTermsObj =
          typeof this.queryTerms === 'string'
            ? this.queryTerms.split('&').reduce((obj, item) => {
                if (item) {
                  const [key, value] = item.split('=')
                  if (key) {
                    obj[key] = value
                  }
                }
                return obj
              }, {})
            : this.queryTerms
      }

      let data = {
        apiCode: this.apiCode,
        params: {
          command: 'init',
          limit: -1,
          start: 0,
          root: this.root,
          para_order: 'order_num',
          ...queryTermsObj,
        },
        ...this.requestData,
      }
      let res = await this.$api.DgJsonStore(data)
      this.treeListRes = res.root
      // let newChildren = this.rootVal
      //   ? res.root.filter((list) => list[this.nodeKey] === this.root)
      //   : res.root.filter((list) => list[this.pnodeKey] === this.root)
      // this.treeList = this.parseTreeList(res.root, newChildren)

      // // 默认加上全部节点
      // if (this.treeListRes.length && this.showAllnode) {
      //   this.treeList.unshift({ [this.label]: '全部', [this.pnodeKey]: this.root })
      // }

      this.treeList = this.getTreeList(res.root)
    },
    getTreeList(data) {
      let treeList = []
      let newChildren = this.rootVal
        ? data.filter((list) => list[this.nodeKey] === this.root)
        : data.filter((list) => list[this.pnodeKey] === this.root)

      treeList = this.parseTreeList(data, newChildren)

      // 默认加上全部节点
      if (data.length && this.showAllnode) {
        treeList.unshift({ [this.label]: '全部', [this.pnodeKey]: this.root })
      }
      return treeList
    },
    changeFilterText(val) {
      this.$emit('changeFilterText', val)
    },
    // 递归函数将取到的数据转变为带children的数据结构
    parseTreeList(treeList, children) {
      let newChildren = []
      return children.map((list) => {
        newChildren = treeList.filter((child) => child[this.pnodeKey] === list[this.nodeKey])
        if (newChildren && newChildren.length > 0) {
          list.children = this.parseTreeList(treeList, newChildren)
        }
        return list
      })
    },
    filterNode(value, data, node) {
      if (!value) {
        this.$emit('filterNode', value, data)
        return true
      } else if (this.filterChild) {
        return data[this.label].indexOf(value) !== -1
      } else {
        node.__filter = false
        let parent = node.parent
        while (parent) {
          if (parent.__filter) return true
          parent = parent.parent
        }
        return (node.__filter = data[this.label].indexOf(value) !== -1)
      }
      // if (!value) return true
      // return data[this.label].indexOf(value) !== -1
    },
    // 传回父组件
    check(data, checked, indeterminate) {
      this.$emit('check-change', data, checked, indeterminate)
      // 获取所有被选中的data的数组
      let takeDate = this.$refs.tree.getCheckedNodes()
      this.$emit('check', takeDate)
      // 获取所有被选中的key的数组
      let keyDate = this.$refs.tree.getCheckedKeys()
      this.$emit('checkkey', keyDate)
    },
    // 点击节点时的回调
    nodeclick(obj, node, data) {
      // let key = this.$refs.tree.getCurrentKey()
      this.$emit('click', obj, node, data)
    },
    // 节点开始拖拽时触发的事件回调
    handleDragStart(node, ev) {
      this.$emit('dragStart', node, ev)
    },
    // 拖拽进入其他节点时触发的事件回调
    handleDragEnter(draggingNode, dropNode, ev) {
      this.$emit('treeDragEnter', draggingNode, dropNode, ev)
    },
    // 拖拽离开某个节点时触发的事件回调
    handleDragLeave(draggingNode, dropNode, ev) {
      this.$emit('treeDragLeave', draggingNode, dropNode, ev)
    },
    // 在拖拽节点时触发的事件回调
    handleDragOver(draggingNode, dropNode, ev) {
      this.$emit('treeDragOver', draggingNode, dropNode, ev)
    },
    // 拖拽结束时（可能未成功）触发的事件回调
    handleDragEnd(draggingNode, dropNode, dropType, ev) {
      this.$emit('treeDragEnd', draggingNode, dropNode, dropType, ev)
    },
    // 拖拽成功完成时触发的事件回调
    handleDrop(draggingNode, dropNode, dropType, ev) {
      this.$emit('treeDrop', draggingNode, dropNode, dropType, ev)
    },
    createRootNode() {
      this.$emit('createRootNode')
    },
    contextmenu(e) {
      // 右键单击事件
      e.preventDefault()
      if (this.treeList.length > 0) return
      var x = e.clientX
      var y = e.clientY
      // Get the current location
      this.contextMenuData.axis = {
        x,
        y,
      }
    },
  },
}
</script>
