<template>
  <div :class="_class">
    <div :class="_contentClass" @click="handleExpand">
      <div :class="_expandClassNames">
        <Icon v-if="data.children" :icon="data.loading ? 'loading_gradient_primary': 'carret_right'" :class="data.loading ? 'loading_gradient' : ''"></Icon>
      </div>
      <div :class="_checkbox" v-if="selectable">
        <Checkbox
          :checked="data.checked"
          :value="data.key"
          :indeterminate="data.indeterminate"
          @click.stop
          @change="onCheck"
        ></Checkbox>
      </div>
      {{ data.text }}
    </div>
    <div :class="_childrenClass">
      <template v-if="data.expand">
        <hive-tree-node
          v-for="(item, index) in children"
          :key="index"
          :data="item"
          :selectable="selectable"
          :children-key="childrenKey"
          :nodeKey="nodeKey"
        ></hive-tree-node>
      </template>
    </div>
  </div>
</template>

<script>
  import Emitter from 'utils-lib/dist/emitter';

  import Checkbox from '../checkbox';
  import Icon from '../icon';
  import Loading from '../loading';

  const name = 'hive-tree-node';

  export default {
    name,
    components: {
      Checkbox,
      Icon,
      Loading,
    },
    mixins: [Emitter],
    inject: ['tree'],
    props: {
      data: {
        type: Object,
        default() {
          return {};
        },
      },
      childrenKey: String,
      selectable: Boolean,
      nodeKey: {
        type: [String, Boolean, Number],
        default: null,
      },
    },
    data() {
      return {};
    },
    computed: {
      _class() {
        return [`${name}`];
      },
      _checkbox() {
        return [`${name}__checkbox`];
      },
      _expandClassNames() {
        return [
          `${name}__expand`,
          {
            [`${name}__expand--children`]: this.data.children,
            [`${name}__expand--expanded`]: this.data.expand,
          },
        ];
      },
      _titleClass() {
        return [
          `${name}-title`,
          {
            [`${name}-title-selected`]: this.data.selected,
          },
        ];
      },
      nodeType() {
        const { data, children } = this;

        // 枝
        if (children.length || data.loading === false) {
          return 'branch';
        }

        // 叶
        return 'leaf';
      },
      _contentClass() {
        return [
          `${name}__content`,
          {
            [`${name}__content--active`]: this.nodeKey === this.data.nodeKey,
          },
        ];
      },
      _childrenClass() {
        return [`${name}__children`];
      },
      node() {
        const {
          data,
          tree: { flatState = [] },
        } = this;
        return [flatState, flatState.find(item => item.nodeKey === data.nodeKey)];
      },
      children() {
        return this.data[this.childrenKey] || [];
      },
    },

    methods: {
      handleExpand() {
        const { data, children, tree, childrenKey } = this;

        if (data.disabled) return;

        // 异步加载
        if (!children.length) {
          if (tree && tree.onLoad) {
            this.$set(data, 'loading', true);
            tree.onLoad(data, children => {
              // children为空
              if (children == null) {
                return this.$set(data, 'loading', false);
              }

              let loading = false;
              // 空数据
              if (children.length === 0) {
                loading = undefined;
              }
              this.$set(data, 'loading', loading);

              if (children.length) {
                this.$set(data, childrenKey, children);
                this.$nextTick(() => this.handleExpand());
              }
            });
            return;
          }
        }

        if (children.length) {
          this.$set(data, 'expand', !data.expand);
        }
        this.dispatch('hive-tree', 'expandtoggle', data);
      },
      onCheck() {
        const { data } = this;

        if (data.disabled) return;

        const changes = {
          checked: !data.checked && !data.indeterminate,
          nodeKey: data.nodeKey,
        };
        this.dispatch('hive-tree', 'check', changes);
      },
    },
  };
</script>
