<template>
  <li>
    <span v-if="node.children && node.children.length>0" :class="switcherCls" @click="onExpand"></span>
    <span v-else="node.children && node.children.length>0" :class="[`${this.prefixCls}-switcher ${this.prefixCls}-switcher-noop ${this.prefixCls}-switcher-noop-${this.iconType}`]"></span>    
    <span v-if="(this.showIcon || this.loadData && this.dataLoading)" :class="iconEleCls"></span>
    <span ref="selectHandle" 
      :title="typeof this.title === 'string' ? this.title : ''" 
      :class="wrapCls" 
      @mouseenter.prevent="onMouseEnter" 
      @mouseleave.prevent="onMouseLeave" 
      @contextmenu.prevent="onContextMenu"
      @click.prevent="onSelect">
      <span></span>     
      <node-content></node-content>      
    </span>
    <ul :class="cls" v-if="expanded" :data-expanded="expanded">
      <treeNode 
        v-for="item in node.children" 
        :key="item.eventKey"
        :node="item"
        :title="item.title"
        :pos="item.pos"
        :showIcon="item.showIcon"
        :loadData="item.loadData"
        :prefixCls="item.prefixCls"
        :expanded="item.expanded"
        :selected="item.selected"
        :eventKey="item.eventKey"
        :root="item.root"
        :disabled="item.disabled"
        :iconType="iconType"
        ></treeNode>
    </ul>
  </li>
</template>

<script>
  import classNames from 'classnames'

  export default {
    name: 'treeNode',
    components: {
      NodeContent: {
        render (h) {
          const parent = this.$parent
          return (
            parent.root.titleRender
              ? parent.root.titleRender.call(parent._renderProxy, h, { _self: parent.root.$vnode.context, node: parent })
              : <span class={`${parent.prefixCls}-title`}>{ parent.title }</span>
          )
        }
      }
    },
    props: {
      node: {
        type: Object,
        default () {
          return {}
        }
      },
      title: {
        type: String,
        default: '---'
      },
      pos: {
        type: String,
        default: ''
      },
      eventKey: {
        type: String,
        default: ''
      },
      showIcon: { // 是否展示 TreeNode title 前的图标，没有默认样式，如设置为 true，需要自行定义图标相关样式
        type: Boolean,
        default: true
      },
      loadData: {
        type: Function
      },
  
      prefixCls: {
        type: String,
        default: 'v-tree'
      },
      disabled: {
        type: Boolean,
        default: false
      },
      disableCheckbox: {
        type: Boolean,
        default: true
      },
      expanded: {
        type: Boolean,
        default: true
      },
      selected: {
        type: Boolean,
        default: false
      },
      isLeaf: {
        type: Boolean,
        default: true
      },
      root: {
        type: Object,
        default () {
          return {}
        }
      },
      iconType: {
        type: String,
        default: 'file'
      }
  
    },
    computed: {
      switcherCls () {
        const expandedState = this.expanded ? 'open' : 'close'
        return classNames(
        `${this.prefixCls}-switcher`,
        `${this.prefixCls}-switcher_${expandedState}`, {
          [`${this.prefixCls}-switcher-disabled`]: this.disabled
        })
      },
      cls () {
        return classNames(`${this.prefixCls}-child-tree`, {
          [`${this.prefixCls}-child-tree-open`]: this.expanded
        })
      },
      wrapCls () {
        const expandedState = this.expanded ? 'open' : 'close'
        let iconState = expandedState
        if (this.node.children && this.node.children.length === 0) {
          if (!this.loadData || this.isLeaf) {
            iconState = 'docu'
          }
        }
        const wrap = `${this.prefixCls}-node-content-wrapper`
        let className = `${wrap} ${wrap}-${iconState === expandedState ? iconState : 'normal'} `
        if (!this.disabled) {
          if (this.selected || !this._dropTrigger && this.dragNodeHighlight) {
            className += `${this.prefixCls}-node-selected`
          }
        }
        return className
      },
      iconEleCls () {
        const expandedState = this.expanded ? 'open' : 'close'
        let iconState = expandedState
        if (this.node.children.length === 0) {
          if (!this.loadData || this.isLeaf) {
            iconState = 'docu'
          }
        }
        const iconEleCls = {
          [`${this.prefixCls}-iconEle`]: true,
          [`${this.prefixCls}-icon_loading`]: this.dataLoading,
          [`${this.prefixCls}-icon__${iconState}`]: true
        }
        return classNames(iconEleCls)
      }
    },
    data () {
      return {
        dataLoading: false
      }
    },
    methods: {
      onExpand () {
        const callbackPromise = this.node.root.onExpand(this)
        if (callbackPromise && typeof callbackPromise === 'object') {
          this.dataLoading = true
          callbackPromise.then(() => {
            this.dataLoading = false
          }, () => {
            this.dataLoading = false
          })
        }
      },
      onSelect () {
        if (this.disabled) return
        this.root.onSelect(this)
      },
      onMouseEnter (e) {
        this.root.onMouseEnter(e, this)
      },
      onMouseLeave (e) {
        this.root.onMouseLeave(e, this)
      },
      onContextMenu (e) {
        this.root.onContextMenu(e, this)
      }
    }
  }
</script>
