<template>
  <div class="flex pd-20">
    <el-card class="box-card flex1">
      <div slot="header" class="flex jc-sb">
        <span>{{leftNum}}项</span>
        <el-checkbox v-if="showAllCheck" v-model="allChecked" @change="checkChang">默认全部引用</el-checkbox>
      </div>
      <div v-loading="leftloading">
        <el-scrollbar :style="scrollbarStyle">
          <el-tree show-checkbox
            :data="leftTreeData" @check-change="checkChange('leftTree')"
            :props="defaultProps" :expand-on-click-node="false"
            highlight-current node-key="id"
            ref="leftTree" @node-expand="nodeExpand">
          </el-tree>
        </el-scrollbar>
      </div>
    </el-card>
    <div class="flex flex-d-c flex-center" style="width:50px;">
      <div style="width: 32px;"><el-button @click="addTree" :type="leftNum <= 0 ? '' : 'success'" :disabled="leftNum <= 0||isNoAdd" size="mini" icon="el-icon-arrow-right"></el-button></div>
      <div style="margin-top: 10px; width: 32px;"><el-button @click="delTree" :type="rightNum <= 0 ? '' : 'success'" :disabled="rightNum <= 0" size="mini" icon="el-icon-arrow-left"></el-button></div>
    </div>
    <el-card class="box-card flex1">
      <div slot="header" class="clearfix">
        <span>{{rightNum}}项</span>
      </div>
      <div v-loading="rightloading">
        <el-scrollbar :style="scrollbarStyle">
          <el-tree show-checkbox
            :data="rightTreeData" @check-change="checkChange('rightTree')"
            :props="rightProps?rightProps:defaultProps" :expand-on-click-node="false"
            highlight-current node-key="id"
            ref="rightTree" :default-expanded-keys="rightExpands">
          </el-tree>
        </el-scrollbar>
      </div>
    </el-card>
  </div>
</template>

<script>
export default {
  name: "treeTree",
  props: {
    leftTreeData: {
      type: Array,
      default: function () {
        return [];
      }
    },
    scrollbarStyle:{
      type:String,
      default:'height:calc(100vh - 400px)'
    },
    showAllCheck:{
      type:Boolean,
      default:false
    },
    rightProps:{
      type:Object,
      default: function () {
        return null;
      }
    },
    leftloading:{
      type:Boolean,
      default:false,
    },
    rightloading:{
      type:Boolean,
      default:false,
    },
    isNoAdd:{
      type:Boolean,
      default:false,
    },//不准添加树
  },
  computed: {

  },
  data(){
    return{
      defaultProps: {
        children: 'children',
        label: 'title',
      },
      leftNum:0,
      rightTreeData:[],
      rightNum:0,
      rightExpands:[],
      allChecked:false,
    }
  },

  methods:{
    addTree(){
    console.log(11111,'添加');
    
      if(this.rightTreeData.length < 1){
        //直接把左边勾选的树复制到右侧

        //console.log(this.$refs.leftTree.getCheckedNodes())
        let allTree = JSON.parse(JSON.stringify(this.leftTreeData));

        //把半选和选中的数组key合并
        let keys = this.$refs.leftTree.getCheckedKeys().concat(this.$refs.leftTree.getHalfCheckedKeys());
        //console.log(keys,'keys');
        //console.log(allTree,'allTree');
        this.getRightTree(allTree,keys);
        this.rightTreeData = allTree;
        this.$emit('onAddTree',this.rightTreeData);
      }else{
        //只增加右侧树没有的节点，不会覆盖右侧树多余的节点

        let checkNodes = this.$refs.leftTree.getCheckedNodes(false,true);
        //console.log(checkNodes)
        let rIdMap = new Map();
        checkNodes.forEach((data)=>{
          rIdMap.set(data.id,data)
        })

        let lIdSet = new Set();
        this.getRightTreeData(lIdSet,this.rightTreeData);

        //在右侧id减去左侧有的id，剩下的就是新增的id
        lIdSet.forEach((id)=>{
          rIdMap.delete(id);
        })

        //console.log(rIdSet)
        let addMap = new Map();
        rIdMap.forEach((data)=>{
          if(data.parentId != '0'){
            //在左侧树能找到父节点的，新增
            let lNode = this.$refs.rightTree.getNode(data.parentId);
            if(lNode){
              addMap.set(data,lNode.data.id);
            }
          }
        })

           //把半选和选中的数组key合并
        let keys = this.$refs.leftTree.getCheckedKeys().concat(this.$refs.leftTree.getHalfCheckedKeys());
        const myArray = Array.from(addMap.keys());
        let myright= JSON.parse(JSON.stringify(myArray));
        this.getRightTree(myright,keys);
        myright.forEach((data)=>{
                  this.$refs.rightTree.append(data,data.parentId);
          })


        // addMap.forEach((value,key)=>{
        //   this.$refs.rightTree.append(key,value);
        // })

      }

      
    },
    getRightTree(arr,keys){
      //对比所有的node和选中的key
      for (let i = arr.length-1; i >= 0; i--) {
        let isIn = false;
        if(this.rightProps){
          //名称使用传入的字段
          arr[i][this.rightProps.label] = arr[i].title;
        }
        for (let j = keys.length-1; j >= 0; j--) {
          if(keys[j] == arr[i].id){
            isIn = true;
            //已经匹配到的key移除，节省性能
            keys.splice(j,1);
            break;
          }
        }
        if(isIn){
          //包含在选中的节点，如果有childer继续递归判断
          if(arr[i].children && arr[i].children.length){
            this.getRightTree(arr[i].children,keys);
          }
        }else{
          //不包含在选中key的node删除
          arr.splice(i,1);
        }
      }
    },
   
    getRightTreeData(set,arr){
      arr.forEach((data)=>{
        set.add(data.id);
        if(data.children && data.children.length){
          this.getRightTreeData(set,data.children);
        }
      })
    },

    delTree(){
      let delNodes = this.$refs.rightTree.getCheckedNodes();
      //只把选中的节点移除
      delNodes.forEach((node)=>{
        //console.log(node)
        this.$refs.rightTree.remove(node);
        this.$refs.leftTree.setChecked(node.id,false);
      })
      this.getRightNum();
      this.getLeftNum();

      this.$emit('onDelTree',delNodes);
    },

    nodeExpand(data){
      this.rightExpands = this.rightExpands.concat([data.id]);
    },

    checkChange(treeName){
      switch (treeName) {
        case 'leftTree':
          this.getLeftNum();
          break;
        case 'rightTree':
          this.getRightNum();
          break;
      }
    },

    setRightTree(data){
      this.rightTreeData = data;

      let ids = [];
      for (let i = 0; i < data.length; i++) {
        this.getLeafIds(ids,data[i])
      }
      //在左边把右边的节点勾选上
      this.$nextTick(()=>{
        this.$refs.leftTree.setCheckedKeys(ids,true);
      })
    },

    getTreeAllId(treeName){
      let tree = this.$refs[treeName];
      if(this.allChecked){
        tree = this.$refs.leftTree;
      }
      //console.log(tree.data);
      let ids = [];
      for (let i = 0; i < tree.data.length; i++) {
        this.getIds(ids,tree.data[i]);
      }
      //console.log(obj)
      return ids.join(',');
    },
    getIds(ids,data){
      ids.push(data.id);
      if(data.children && data.children.length){
        for (let i = 0; i < data.children.length; i++) {
          this.getIds(ids,data.children[i]);
        }
      }
    },

    getLeafIds(ids,data){
      if(data.children && data.children.length){
        for (let i = 0; i < data.children.length; i++) {
          this.getLeafIds(ids,data.children[i]);
        }
      }else{
        ids.push(data.id)
      }
    },

    checkChang(){
      this.$emit('onCheckAll');
    },

    getLeftNum(){
      let checkNum = this.$refs.leftTree.getCheckedKeys().length;
      let halfNum = this.$refs.leftTree.getHalfCheckedKeys().length;
      this.leftNum = checkNum+halfNum;
    },
    getRightNum(){
      let checkNum = this.$refs.rightTree.getCheckedKeys().length;
      let halfNum = this.$refs.rightTree.getHalfCheckedKeys().length;
      this.rightNum = checkNum+halfNum;
    }
  }
};
</script>
