<template>
  <div class="el-tree-node"
       @click.stop="handleClick"
       v-show="node.visible"
       :class="{
      'is-expanded': childNodeRendered && expanded,
      'is-current': tree.store.currentNode === node,
      'is-hidden': !node.visible
    }">
    <div class="el-tree-node__content"
         @mouseenter="eventShow = true"
         @mouseleave="eventShow = false"
         :style="{ 'padding-left': (node.level - 1) * tree.indent + 'px' }"
         style="position: relative;">
      <span class="el-tree-node__expand-icon"
            @click.stop="handleExpandIconClick"
            :class="{ 'is-leaf': node.isLeaf, expanded: !node.isLeaf && expanded }">
      </span>
      <el-checkbox v-if="showCheckbox"
                   v-model="node.checked"
                   :indeterminate="node.indeterminate"
                   :disabled="!!node.disabled"
                   @click.native.stop
                   @change="handleCheckChange">
      </el-checkbox>
      <span v-if="node.loading"
            class="el-tree-node__loading-icon el-icon-loading">
      </span>
      <span v-if="events">
        <span>
          <span style="vertical-align: middle;"
                class="el-tree-node__label">{{ node.label
            }}<span class="tree-des"
                  style="margin-left:30px;font-size:10px;line-height:40px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;course:hand;width:110px;"
                  v-show="remarkShow && eventShow">{{ node.remark }}</span></span>
        </span>
        <span style="display:inline-block;position: absolute; right: 100px;top: -5px;margin-left:100%;"
              v-show="eventShow">
          <mk-button :size="0"
                     :type="4"
                     v-for="oneevent in events"
                     v-if="btnShow(oneevent)"
                     @click="ck(oneevent.fn)"
                     :key="oneevent.btnName"
                     :confirm-text="oneevent.confirmText"
                     :loading="oneevent.loading"
                     :padwidth="0">
            {{ oneevent.btnName }}
          </mk-button>
        </span>
      </span>
      <span class="el-tree-node__label"
            v-else>{{ node.label }}</span>
    </div>
    <el-collapse-transition>
      <div class="el-tree-node__children"
           v-show="expanded">
        <mk-tree-node :render-content="renderContent"
                      v-for="child in node.childNodes"
                      :key="getNodeKey(child)"
                      :node="child"
                      :remark-show="remarkShow"
                      :events="events"
                      @node-expand="handleChildNodeExpand">
        </mk-tree-node>
      </div>
    </el-collapse-transition>
  </div>
</template>

<script type="text/jsx">
import ElCollapseTransition from 'mk-element/src/transitions/collapse-transition';
import ElCheckbox from 'mk-element/packages/checkbox';
import emitter from 'mk-element/src/mixins/emitter';
import MkButton from 'mk-element/packages/mk-button';

export default {
  mixins: [emitter],
  name: 'mk-tree-node',
  componentName: 'mk-tree-node',
  props: {
    node: {
      default() {
        return {};
      }
    },
    remarkShow: { type: Boolean },
    events: { type: Array },
    props: {},
    renderContent: Function
  },
  components: {
    ElCollapseTransition,
    ElCheckbox,
    MkButton
  },
  data() {
    return {
      eventShow: false,
      tree: null,
      expanded: false,
      childNodeRendered: false,
      showCheckbox: false,
      oldChecked: null,
      oldIndeterminate: null
    };
  },
  watch: {
    'node.indeterminate'(val) {
      this.handleSelectChange(this.node.checked, val);
    },

    'node.checked'(val) {
      this.handleSelectChange(val, this.node.indeterminate);
    },

    'node.expanded'(val) {
      this.expanded = val;
      if (val) {
        this.childNodeRendered = true;
      }
    }
  },

  methods: {
    btnShow: function(oneevent) {
      if (oneevent.ignorekey) {
        if (oneevent.ignoreval === 'undefined') {
          return this.node.data[oneevent.ignorekey] !== undefined;
        } else {
          return this.node.data[oneevent.ignorekey] !== oneevent.ignoreval;
        }
      }
      return true;
    },
    getNodeKey(node, index) {
      const nodeKey = this.tree.nodeKey;
      if (nodeKey && node) {
        return node.data[nodeKey];
      }
      return index;
    },
    ck(fn) {
      fn(this.node.data);
    },
    handleSelectChange(checked, indeterminate) {
      if (this.oldChecked !== checked && this.oldIndeterminate !== indeterminate) {
        this.tree.$emit('check-change', this.node.data, checked, indeterminate);
      }
      this.oldChecked = checked;
      this.indeterminate = indeterminate;
    },

    handleClick() {
      const store = this.tree.store;
      store.setCurrentNode(this.node);
      this.tree.$emit('current-change', store.currentNode ? store.currentNode.data : null, store.currentNode);
      this.tree.currentNode = this;
      if (this.tree.expandOnClickNode) {
        this.handleExpandIconClick();
      }
      this.tree.$emit('node-click', this.node.data, this.node, this);
    },

    handleExpandIconClick() {
      if (this.node.isLeaf) return;
      if (this.expanded) {
        this.tree.$emit('node-collapse', this.node.data, this.node, this);
        this.node.collapse();
      } else {
        this.node.expand();
        this.$emit('node-expand', this.node.data, this.node, this);
      }
    },

    handleCheckChange(ev) {
      this.node.setChecked(ev, !this.tree.checkStrictly);
    },

    handleChildNodeExpand(nodeData, node, instance) {
      this.broadcast('ElTreeNode', 'tree-node-expand', node);
      this.tree.$emit('node-expand', nodeData, node, instance);
    }
  },

  created() {
    const parent = this.$parent;

    if (parent.isTree) {
      this.tree = parent;
    } else {
      this.tree = parent.tree;
    }

    const tree = this.tree;
    if (!tree) {
      console.warn("Can not find node's tree.");
    }

    const props = tree.props || {};
    const childrenKey = props['children'] || 'children';
    this.$watch(`node.data.${childrenKey}`, () => {
      this.node.updateChildren();
    });

    this.showCheckbox = tree.showCheckbox;

    if (this.node.expanded) {
      this.expanded = true;
      this.childNodeRendered = true;
    }

    if (this.tree.accordion) {
      this.$on('tree-node-expand', node => {
        if (this.node !== node) {
          this.node.collapse();
        }
      });
    }
  }
};
</script>
