<template>
  <div class="tree-select" v-clickoutside="onClickOutside">
    <!--<Input  :placeholder="placeholder" v-model="str"  @on-focus="onFocus"  />-->
    <div class="ivu-select ivu-select-single" @click="onFocus">
      <div class="ivu-select-selection">
        <input ref="input" type="hidden" v-model="str" />
        <span class="ivu-select-selected-value" v-if="str">
          {{ str }}
        </span>
        <span class="ivu-select-placeholder" v-else>{{
          placeholder || ""
        }}</span>
      </div>
    </div>
    <Icon type="md-close" @click="onClear" v-show="str"></Icon>
    <i class="ivu-icon ivu-icon-ios-arrow-down ivu-select-arrow"></i>
    <div class="tree-select__block" :class="{ expand: expand }">
      <div ref="tree" :id="id" class="ztree"></div>
    </div>
  </div>
</template>

<script>
import clickoutside from "../directives/clickoutside";
import emitter from "../libs/emitter";
import { uuid } from "../common";

export default {
  directives: { clickoutside },
  mixins: [emitter],
  props: {
    placeholder: {
      default: "请选择",
      type: String
    },
    treeData: {
      default: () => [],
      type: Array
    },
    value: {
      default: "",
      type: [String, Number]
    },
    simpleData: {
      default: true,
      type: Boolean
    },
    defaultName: {
      type: String,
      default: "根节点"
    }
  },
  data() {
    return {
      expand: false,
      str: "",
      id: uuid(),
      isClick: false
    };
  },
  name: "f-tree-select",
  watch: {
    treeData() {
      if (this.treeData.length > 0) {
        this.renderTree();
      }
    },
    value() {
      if (this.value == null) {
        this.str = this.defaultName;
        if (!this.isClick && this.zTree) {
          this.zTree.cancelSelectedNode();
        }
      }
      this.update();
    }
  },
  methods: {
    update() {
      if (this.isClick) {
        this.isClick = false;
        const target = this.zTree.getSelectedNodes();
        this.str = target.length > 0 ? target[0].name : "";
        return this.zTree.cancelSelectedNode();
      }
      if (this.value == "" || this.value == null) {
        this.str = this.defaultName;
      } else {
        const target = this.treeData.find(d => d.id == this.value);
        if (target) {
          this.str = target.name;
          const node = this.zTree.getNodeByParam("id", target.id, null);
          this.zTree.selectNode(node);
        }
      }
      this.dispatch("FormItem", "on-form-change", this.value);
    },
    onFocus() {
      this.expand = true;
    },
    onClickOutside() {
      this.expand = false;
    },
    renderTree() {
      const setting = {
        data: {
          simpleData: {
            enable: this.simpleData,
            pIdKey: "parent"
          }
        },
        view: {
          showIcon: true
        },
        callback: {
          onClick: (event, treeId, treeNode) => {
            this.$emit("input", treeNode.id);
            this.str = treeNode.name;
            this.onClickOutside();
            this.isClick = true;
            this.$emit("on-select", treeNode);
          }
        }
      };
      this.zTree = $.fn.zTree.init($(this.$refs.tree), setting, this.treeData);
    },
    onClear() {
      this.str = this.defaultName;
      this.isClick = false;
      this.zTree.cancelSelectedNode();
      this.expand = false;
      this.$emit("input", null);
    }
  },
  mounted() {
    if (this.treeData.length > 0) {
      this.renderTree();
      this.update();
    }
    this.isClick = false;
  }
};
</script>

<style lang="less">
.tree-select {
  position: relative;
  .ivu-icon-md-close {
    position: absolute;
    right: 25px;
    top: 9px;
    font-size: 14px;
    cursor: pointer;
    color: #808695;
  }
  &__block {
    position: absolute;
    height: 0;
    border: 1px solid #ccc;
    width: 100%;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
    overflow: auto;
    background-color: #fff;
    transition: height 0.25s ease;
    opacity: 0;
    z-index: 1000;
    &.expand {
      height: 220px;
      opacity: 1;
    }
  }
}
</style>
