<template>
  <div class="transfer-tree">
    <div :class="prefixCls">
      <transfer-list
        :prefixCls="prefixCls + '-list'"
        :data="leftData"
        :listStyle="listStyle"
        :title="localeTitles[0]"
        :notFoundText="notFoundText"
        @selected="leftSelected"
        ref="left"
      ></transfer-list>

      <transfer-operation
        :prefixCls="prefixCls"
        :operations="operations"
        :leftActive="leftValidKeysCount > 0"
        :rightActive="rightValidKeysCount > 0"
      ></transfer-operation>

      <transfer-list
        :prefixCls="prefixCls + '-list'"
        :data="rightData"
        :listStyle="listStyle"
        :title="localeTitles[1]"
        :notFoundText="notFoundText"
        @selected="rightSelected"
        ref="right"
      ></transfer-list>
    </div>
  </div>
</template>

<script>
import TransferList from "./list.vue";
import TransferOperation from "./operation.vue";

const prefixCls = "ivu-transfer";

export default {
  name: "transfer-tree",
  components: {
    TransferList,
    TransferOperation
  },
  props: {
    data: {
      type: Array,
      default() {
        return [];
      }
    },
    targetKeys: {
      type: Array,
      default() {
        return [];
      }
    },
    listStyle: {
      type: Object,
      default() {
        return {};
      }
    },
    titles: {
      type: Array
    },
    operations: {
      type: Array,
      default() {
        return [];
      }
    },
    notFoundText: {
      type: String
    }
  },
  data() {
    return {
      prefixCls,
      leftData: [],
      rightData: [],
      selectedTitles: [],
      leftCheckedKeys: [],
      rightCheckedKeys: [],
      leftValidKeysCount: 0,
      rightValidKeysCount: 0,
      selectedKeys: []
    };
  },
  computed: {
    classes() {
      return [`${prefixCls}`];
    },
    localeTitles() {
      if (this.titles === undefined) {
        return ["源列表", "目标列表"];
      } else {
        return this.titles;
      }
    }
  },
  mounted() {
    this.selectedKeys = [...this.targetKeys];
    this.updateData();
  },
  methods: {
    leftSelected(count) {
      this.leftValidKeysCount = count;
    },
    rightSelected(count) {
      this.rightValidKeysCount = count;
    },
    updateData() {
      this.selectedTitles = [];
      let [leftData, rightData] = this.splitData(this.data);
      this.leftData = leftData;
      this.rightData = rightData;
    },
    splitData(data) {
      let leftData = [];
      let rightData = [];

      data.forEach(item => {
        if (item.children) {
          let [leftChildren, rightChildren] = this.splitData(item.children);
          if (leftChildren.length) {
            let newitem = { ...item };
            newitem.children = leftChildren;
            leftData.push(newitem);
          }
          if (rightChildren.length) {
            let newitem = { ...item };
            newitem.children = rightChildren;
            rightData.push(newitem);
          }
        } else {
          let newitem = { ...item };
          if (this.selectedKeys.indexOf(item.key) === -1) {
            leftData.push(newitem);
          } else {
            rightData.push(newitem);
            this.selectedTitles.push(newitem.title);
          }
        }
      });
      return [leftData, rightData];
    },
    moveTo(direction) {
      let opposite = direction === "left" ? "right" : "left";
      let moveItems = this.$refs[opposite].selected;
      let moveKeys = this.getSelectKeys(moveItems);
      this.selectedKeys = this.updateSelectedKeys(
        this.selectedKeys,
        direction,
        moveKeys
      );
      this.updateData();
      this.$refs[opposite].select([]);
      this.$emit("on-change", {
        selectedKeys: this.selectedKeys,
        direction,
        moveKeys,
        selectedTitles: this.selectedTitles
      });
    },
    getSelectKeys(moveItems) {
      let keys = [];
      moveItems.map(item => {
        if (!item.children) {
          keys.push(item.key);
        }
      });
      return keys;
    },
    updateSelectedKeys(selectedKeys, direction, moveKeys) {
      let newSelectedKeys = [...selectedKeys];
      if (direction === "left") {
        moveKeys.forEach(item => {
          let ind = newSelectedKeys.indexOf(item);
          newSelectedKeys.splice(ind, 1);
        });
      } else {
        newSelectedKeys = newSelectedKeys.concat(moveKeys);
      }
      return newSelectedKeys;
    }
  }
};
</script>
