<style scoped>
.tree-wrap {
  position: absolute;
  z-index: 10000;
  top: 42px;
  left: 1px;
  right: 1px;
  width: 100%;
  background-color: #fff;
  color: #444;
  border: 1px solid #d1dbe5;
  border-radius: 3px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}

.search-bar {
  cursor: auto;
  width: 100%;
  padding: 5px;
  border-bottom: 1px solid #f5f5f5;
  /* background-color: #f5f5f5; */
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: nowrap;
}
.search-name {
  width: 52px;
}

.tree-body {
  overflow: auto;
  width: 100%;
  margin: 5px 0;
}

@media (min-height:768px){
  .tree-body {
    max-height: 600px;
  }
}

@media (max-height: 768px){
  .tree-body {
    max-height: 400px;
  }
}

.popper__arrow_top {
    top: -13px;
    left: 60% !important;
    margin-right: 3px;
    border-top-width: 0;
    border-bottom-color: #ebeef5;
    border-width: 6px;
}

.popper__arrow_bottom {
    bottom: -13px;
    left: 40% !important;
    margin-right: 3px;
    border-bottom-width: 0;
    border-top-color: #ebeef5;
    border-width: 6px;
}

.popper__arrow_top::after {
    top: 1px;
    margin-left: -6px;
    border-top-width: 0;
    border-bottom-color: #fff;
}
.popper__arrow_bottom::after {
    bottom: 1px;
    margin-left: -6px;
    border-bottom-width: 0;
    border-top-color: #fff;
}
</style>

<style>
.tree-body .el-tree-node.is-current > .el-tree-node__content {
  color: #28b06e;
}
.el-select-dropdown.el-popper{
  z-index: 99999 !important
}
</style>

<template>
  <div class="tree-wrap el-popper" @click.stop="" v-show="isOpen" :style="{
    top: top + 'px',
    left: left + 'px',
    width: width + 'px'
  }">
    <div x-arrow :class="`popper__arrow ${isTop ? 'popper__arrow_bottom' : 'popper__arrow_top'}`">
    </div>
    <dim-select :dim-info="dimInfo" @callback="callback"></dim-select>
    <div class="search-bar" @mouseenter="isSearch = true" @mouseleave="isSearch = false" v-show="items.length">
      <span class="search-name"></span>
      <el-input v-model="filterText" placeholder="请输入要搜索的内容"></el-input>
    </div>
    <el-tree ref="catalogTree"
        :data="items"
        :props="itemsOptions"
        :node-key="itemsOptions.key"
        :current-node-key="nodeKey"
        :default-expand-all="true"
        :expand-on-click-node="false"
        :highlight-current="true"
        :render-content="renderContent"
        :filter-node-method="filterNode"
        @node-click="treeNodeClickHandler"
        v-loading="loading"
        class="tree-body">
    </el-tree>
  </div>
</template>

<script>
import util from '../common/util.js'
import DimSelect from './DimSelect.vue'
import emitter from '../mixins/emitter.js'
export default {
  mixins: [emitter],
  components: {
    'dim-select': DimSelect
  },
  props: {
    isOpen: {
      type: Boolean,
      default: false
    },
    inputValue: {
      type: String,
      default: ''
    },
    nodeKey: {
      type: [String, Number],
      default: ''
    },
    items: {
      type: Array,
      default: function() {
        return []
      }
    },
    itemsOptions: {
      type: Object,
      default: function() {
        return { key: 'ID', label: 'name', children: 'children' }
      }
    },
    screenWidth: {
      type: Number,
      default: window.screen.width
    },
    offsetTop: {
      type: Number,
      default: 0
    },
    offsetLeft: {
      type: Number,
      default: 0
    },
    loading: {
      type: Boolean,
      default: false
    },
    disableRoot: {
      type: Boolean,
      default: true
    },
    dimInfo: {
      type: Object,
      default: function() {
        return {
          enable: false,
          catalogId: 0,
          contentId: 0,
          contentType: ''
        }
      }
    }
  },
  data() {
    return {
      isTop: false,
      top: 0,
      filterText: '',
      isSearch: false,
      width: 280,
      triggerHeight: 0,
      timer: false
    }
  },
  watch: {
    filterText(val) {
      this.$refs.catalogTree.filter(val)
    },
    isOpen(val) {
      if (!val) {
        this.filterText = ''
      } else {
        this.resetPosition()
        this.$refs['catalogTree'].setCurrentKey(this.nodeKey)
      }
    },
    nodeKey(val) {},
    // 监听当前浏览器可视窗口大小
    screenWidth(val) {
      this.screenWidth = val
    }
  },
  computed: {
    left() {
      let left = this.offsetLeft - 5
      if (this.screenWidth && this.offsetLeft + this.width > this.screenWidth) {
        left = this.screenWidth - this.width // 限制在可视范围
      }
      return left
    }
  },
  methods: {
    async resetPosition() {
      console.log('resetPosition -------- in')
      await this.$nextTick()
      // 弹出列表的高度
      let panelHieght = this.$refs.catalogTree.$parent.$el.clientHeight
      console.log('panelHieght -------- ' + panelHieght)
      let clientHeight = document.documentElement.clientHeight
      console.log('clientHeight -------- ' + clientHeight)
      // 滚动条距离上面的高度
      let scrollTop = document.documentElement.scrollTop
      console.log('scrollTop -------- ' + scrollTop)
      // 目标元素距离上面的可视高度
      let targetTop = this.offsetTop - scrollTop
      console.log('targetTop -------- ' + targetTop)
      // 目标元素距离下面的可视高度
      let targetBottom = clientHeight - targetTop
      console.log('targetBottom -------- ' + targetBottom)
      if (targetTop > targetBottom) {
        console.log('targetTop > targetBottom ------------- in')
        this.isTop = true
        console.log('isTop ------------- ' + this.isTop)
        this.top = this.offsetTop - panelHieght
        console.log('top ------------- ' + this.top)
        if (targetTop < panelHieght) {
          console.log('targetTop < panelHieght ------------- in')
          // 高度不够时，修正
          let fixHeight = panelHieght - targetTop + 5
          console.log('fixHeight ------------- ' + fixHeight)
          this.top += fixHeight
          console.log('top ------------- ' + this.top)
        } else {
          this.top -= 8
          console.log('else - top ------------- ' + this.top)
        }
      } else {
        console.log('外层else - top ------------- in')
        this.isTop = false
        console.log('isTop ------------- ' + this.isTop)
        this.top = this.offsetTop + this.triggerHeight
        console.log('外层else - top ------------- ' + this.top)
        if (targetBottom - this.triggerHeight < panelHieght) {
          console.log('外层else - if ------------- in')
          // 高度不够时，修正
          let fixHeight = panelHieght - (targetBottom - this.triggerHeight) + 5
          console.log('外层else - if - fixHeight ------------- ' + fixHeight)
          this.top -= fixHeight
          console.log('外层else - if - top ------------- ' + this.top)
        } else {
          this.top -= 3
          console.log('外层else - else - top ------------- ' + this.top)
        }
      }
    },
    treeNodeClickHandler(data) {
      // 遇到不能选择的树节点时直接返回
      if (data.hasOnClick && data.hasOnClick === 'N') {
        return
      }
      if (data[this.itemsOptions.key] > 0 || (!this.disableRoot && data[this.itemsOptions.key] === 0)) {
        let val = {}
        val[this.itemsOptions.label] = data[this.itemsOptions.label]
        val[this.itemsOptions.key] = data[this.itemsOptions.key]
        this.$emit('update:inputValue', val)
        this.$emit('update:isOpen', false)
        // this.isOpenTree = false
        // 选中节点后返回回调函数click-change并附带选中节点的数据对象
        this.$emit('click-change', Object.assign({}, data))
      }
    },
    filterNode(value, data) {
      if (!value) return true
      value = value.toLowerCase()
      let name = data[this.itemsOptions.label].toLowerCase()
      return name.indexOf(value) !== -1 || window.util.getSpell(name, true).indexOf(value) !== -1
    },
    renderContent: function(createElement, { node, data, store }) {
      let params = {
        h: createElement,
        treeObj: { node, data, store }
      }
      return util.renderTreeContent(params)
    },
    setCurrentKey(key) {
      key && this.$refs.catalogTree.setCurrentKey(key)
    },
    callback(val) {
      this.$emit('callback', val)
      //  this.dispatch('TreeSelect' 'load-catalogtree',{data:val})
    }
  },
  created() {},
  mounted() {
    document.body.appendChild(this.$el)
    this.width = this.$refs.catalogTree.$el.offsetWidth || this.width
    this.triggerHeight = 45

    util.mousewheel(this.$el, e => {
      e.stopPropagation()
    })

    util.mousewheel(document, () => {
      this.$emit('update:isOpen', false)
    })
  },
  destroyed() {
    this.$el.parentNode.removeChild(this.$el)
  }
}
</script>
