/*
 * @Author: Anmin
 * @Email:changanmin1@crc.com.hk
 * @Date: 2019-08-09 16:26:42
 * @Last Modified by: Anmin
 * @Last Modified time: 2019-08-20 12:07:23
 * @description:  选择组织组件
 * 1.支持通过传递ID 默认展示name
 * 2.支持multiple
 * 3.支持checkbox
 * 4.支持单选
 */
<template>
  <Row :gutter="20">
    <Col :span="12">
    <div>
      <!-- <p slot="title">
        {{$t("组织树")}}
      </p> -->
      <div
        v-if="isShowSearchInput"
        slot="extra"
        @keydown.enter="orgSearch"
      >
      <div class="split-y-line"></div>
        <Input
          v-model="formSearch.searchVal"
          :placeholder="inputPlaceholder"
          @input="orgSearch"
          @on-search="orgSearch()"
          clearable
          search
        >
        </Input>
      </div>
      <div class="fill-available-h">
        <Tree
          v-show="!formSearch.searchVal"
          ref="mainTree"
          :multiple="multiple"
          :show-checkbox="showCheckbox"
          :children-key="childrenKey"
          :empty-text="emptyText"
          :data="treeDataMain"
          @on-check-change="handleCheckChange"
          @on-select-change="handleSelectChange"
        ></Tree>
        <Tree
          v-show="formSearch.searchVal"
          ref="searchTree"
          :multiple="multiple"
          :show-checkbox="showCheckbox"
          :children-key="childrenKey"
          :empty-text="emptyText"
          :data="treeDataSearch"
          @on-check-change="handleCheckChangeSearch"
          @on-select-change="handleSelectChangeSearch"
        ></Tree>
        <Spin
          v-if="isShowLoading"
          fix
        ></Spin>
      </div>
    </div>
    </Col>
    <Col :span="12">
    <div>
      <p slot="title" class="fill_title">
        {{$t('选择的组织')}}
      </p>
      <div class="fill-available-h">
        <Tree :data="treeDataSelect"></Tree>
      </div>
    </div>
    </Col>
  </Row>
</template>
<script>
/**
 * 考虑场景
 * 1.checkbox 多选 传checkbox
 * 2.节点单选 只返回选择的节点 不传任何 multiple showCheckbox
 * 3.multiple 节点多选，返回每个点击的节点，不区分 父子节点
 */
import extend from 'extend';
import { FetchQueryInitializationOrgs } from '../server.js';
export default {
  name: 'SelectOrg',
  props: {
    showCheckbox: {
      // 是否显示复选框
      type: Boolean,
      default: false
    },
    multiple: {
      // 是否多选
      type: Boolean,
      default: false
    },
    emptyText: {
      type: String,
      default() {
        return this.$t('暂无数据')
      }
    },
    childrenKey: {
      type: String,
      default: 'children'
    },
    // 展开层级
    expand: {
      type: Number,
      default: 3
    },
    // 弹出框标题
    title: {
      type: String,
      default() {
        return this.$t('请选择')
      }
    },
    inputPlaceholder: {
      type: String,
      default() {
        return this.$t('请输入')
      }
    },
    // 部门ID  如果有传入，则只能选择该部门下的员工
    departmentId: {
      type: String,
      default: ''
    },
    // 是否显示搜索框
    isShowSearchInput: {
      type: Boolean,
      default: true
    },
    itemKey: {
      type: String,
      default: 'id' // code
    },
    itemVal: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      isShowLoading: true,
      formSearch: {
        searchVal: ''
      },
      // 主组织树-数据
      treeDataMain: [], // 当前存储的所有数据，并且已经操作过了是否选择
      treeDataSearch: [], // 当前搜索出的数据结果
      // 选择组织树-数据
      treeDataSelect: [] // 当前已经选择的组织
    };
  },
  mounted() {
    this.queryInitializationOrgs();
    this.$emit('SetTitle', this.title);
    this.$emit('SetPageActions', [
      {
        text: this.$t('确定'),
        theme: 'warning',
        handle: this.saveSelect
      },
      {
        text: this.$t('关闭'),
        type: 'default',
        handle: this.cancel
      }
    ]);
  },
  destroyed() {
    this.orgTree = null;
  },
  methods: {
    // 根据code 找出所有ID
    getIdsByCode(data) {
      // code 代表 itemVal 的内容为 code内容
      if (this.itemKey === 'code') {
        const vals = this.itemVal.length > 0 ? this.itemVal.split(',') : [];
        const selectItems = [];
        const mapFunc = arrs => {
          arrs.map(arr => {
            if (vals.includes(arr[this.itemKey])) {
              selectItems.push(arr.id);
            }
            if (arr.children.length > 0) {
              mapFunc(arr.children);
            }
          });
        };
        mapFunc(data);
        return selectItems;
      } else {
        return this.itemVal ? this.itemVal.split(',') : [];
      }
    },
    queryInitializationOrgs() {
      this.isShowLoading = true; // loading...
      this.getOrgs(_data => {
        // data => 获取组织数据
        if (this.showCheckbox) {
          this.treeDataMain = this.checkedTreeNode(this.elTreeExpand(_data)); /// /初始化展示几级数据 并 赋值给选择树使用
        } else {
          // 单选还是多选
          if (this.multiple) {
            // let ids = this.item && this.item.length > 0 ? this.item.map(item => item.id) : [];
            this.treeDataMain = this.selectedTreeNode(this.elTreeExpand(_data)); /// /初始化展示几级数据 并 赋值给选择树使用
          } else {
            // let id = this.item && this.item.id ? this.item.id : [];
            this.treeDataMain = this.selectedTreeNode(this.elTreeExpand(_data)); /// /初始化展示几级数据 并 赋值给选择树使用
          }
        }
        this.isShowLoading = false; // 关闭loading
      });
    },
    selectedTreeNode(data) {
      const ids = this.getIdsByCode(data);
      const selectItems = [];
      const mapFun = cs => {
        return cs.map(item => {
          if (ids.includes(item.id)) {
            item.selected = true;
            selectItems.push(item);
          }
          if (item.children.length > 0) {
            item.children = mapFun(item.children);
          }
          return item;
        });
      };
      const datas = mapFun(data);
      const _selectItems = extend(true, [], selectItems);
      this.treeDataSelect = _selectItems.map(item => {
        item.children = [];
        return item;
      });
      return datas;
    },
    checkedTreeNode(_data) {
      const ids = this.getIdsByCode(_data);
      if (ids.length <= 0) {
        return _data;
      }
      const selectEls = []; // 需要选中的数据
      const mapFun = cs => {
        return cs.map(item => {
          if (ids.includes(item.id)) {
            selectEls.push(item);
            item.checked = true;
          }
          if (item.children.length > 0) {
            item.children = mapFun(item.children);
          }
          return item;
        });
      };
      const result = mapFun(_data); // 过滤数据
      this.treeDataSelect = extend(true, [], selectEls);
      return result;
    },
    // 根据传递的展开树的层级（props.expand） 来决定展示到第几层
    elTreeExpand(data) {
      return data.map(item => {
        if (item.orgPath.match(/\//g).length <= this.expand) {
          console.log(item.orgPath);
          if (item.children.length > 0) {
            item.children = this.elTreeExpand(item.children);
          }
          item.expand = true;
        }
        return item;
      }, this);
    },
    cancel() {
      this.$emit('Close');
    },
    orgSearch() {
      if (this.formSearch.searchVal == '') {
        return;
      }
      this.$nextTick(()=>{        
        this.formSearch.searchVal = this.formSearch.searchVal.trim()
      })
      this.isShowLoading = true;
      const results = this.searchDataByFiled(extend(true, [], this.treeDataMain), 'title', this.formSearch.searchVal);
      this.treeDataSearch = extend(true, [], results);
      this.isShowLoading = false;
    },
    searchDataByFiled(arr = [], key = '', val = '') {
      const selectItems = [];
      const searchOfKey = (datas, key, val) => {
        datas.filter(item => {
          if (item[key].indexOf(val) > -1) {
            selectItems.push(item);
            return true;
          } else {
            if (item.children.length > 0) {
              searchOfKey(item.children, key, val);
            }
          }
          return item;
        });
      };
      if (arr.length > 0 && key && val) {
        // 执行搜索后，过滤数据
        searchOfKey(arr, key, val);

        return selectItems;
      } else {
        return [];
      }
    },

    saveSelect() {
      if (this.multiple || this.showCheckbox) {
        this.$emit('Close', extend(true, [], this.treeDataSelect));
      } else {
        this.$emit('Close', extend(true, {}, this.treeDataSelect[0]));
      }
    },
    /**
     * 展示当前通过Checkbox 勾选的数据
     */
    handleCheckChange(data) {
      this.formatCheckData(data);
    },
    // 查询选中的数据
    handleCheckChangeSearch() {
      // data :搜索结果中选择了多少条数据,  data 为平级数据，选择多少有多少，不用取children
      this.autoCheckedTree(this.treeDataSearch);
      this.formatCheckData(this.$refs.mainTree.getCheckedNodes());
    },
    // 点击元素的选择
    handleSelectChange(data) {
      if (this.showCheckbox) return;
      const _data = extend(true, [], data);
      const _getSingleEle = function(data) {
        return data.map(item => {
          if (item.children.length > 0) {
            item.children = [];
          }
          return item;
        });
      };
      this.treeDataSelect = _getSingleEle(_data);
    },
    // 点击元素搜索的选择
    handleSelectChangeSearch(data) {
      if (this.showCheckbox) return;
      if (this.multiple) {
        this.autoSelectTree(this.treeDataSearch);
        this.handleSelectChange(this.$refs.mainTree.getSelectedNodes());
      } else {
        this.autoSelectTreeSingle(data);
        const result = this.$refs.mainTree.getSelectedNodes();
        this.handleSelectChange(result);
      }
    },
    autoSelectTreeSingle(arr) {
      const result = extend(true, [], arr);
      const single = result.length > 0 ? result[0] : null;
      const self = this;
      const flatState = self.$refs.mainTree.flatState;
      const currentSelectedKey = flatState.findIndex(obj => obj.node.selected);
      if (currentSelectedKey >= 0) {
        self.$refs.mainTree.flatState[currentSelectedKey].node.selected = false;
      }
      if (single) {
        const selectKey = flatState.findIndex(obj => obj.node.id === single.id);
        self.$refs.mainTree.handleSelect(selectKey);
      }
    },
    autoSelectTree(data) {
      const self = this;
      const flatState = self.$refs.mainTree.flatState;
      // 数据比对
      const mapFun = params => {
        params.map(item => {
          const selectKey = flatState.filter(obj => obj.node.id === item.id);
          if (selectKey && selectKey.length > 0) {
            const sk = selectKey[0];
            const node = sk.node;
            self.$refs.mainTree.$set(node, 'selected', !!item.selected);
          }
          if (item.children.length > 0) {
            mapFun(item.children);
          }
        });
      };
      mapFun(data);
    },
    autoCheckedTree(data) {
      const self = this;
      const funcGetChild = arr => {
        arr.forEach(item => {
          const flatState = self.$refs.mainTree.flatState;
          for (let i = 0; i < flatState.length; i++) {
            const node = flatState[i].node;
            const id = node.id;
            if (item.id == id) {
              self.$refs.mainTree.handleCheck({ checked: item.checked, nodeKey: flatState[i].nodeKey });
              break;
            }
          }
          if (item.children.length > 0) {
            funcGetChild(item.children);
          }
        });
      };
      funcGetChild(data);
    },
    /**
     * 格式化选中的数据
     */
    formatCheckData(data) {
      const ids = this.getSelectIds(data);
      if (ids.length > 0) {
        const _data = data.filter(({ id } = {}) => {
          if (ids.includes(id)) {
            return false;
          }
          return true;
        }, this);
        this.treeDataSelect = extend(true, [], _data);
      } else {
        this.treeDataSelect = extend(true, [], data);
      }
    },
    /**
     * 根据选中的数据，筛选是否已经存在某个父级值中
     * 返回选中数据的二级和之下的数据内容
     */
    getSelectIds(data) {
      const ids = [];
      const mapFun = arr => {
        arr.forEach(item => {
          ids.push(item.id);
          if (item.children.length > 0) {
            mapFun(item.children);
          }
        });
      };
      // 只获取有children的数据
      data.forEach(item => {
        if (item.children.length > 0) {
          mapFun(item.children);
        }
      });
      return ids;
    },
    /**
     * 拉取组织树数据
     */
    getOrgs(cb) {
      // 缓存?
      let OrgtreeDatasSt = window.localStorage.getItem('OrgtreeDatas');
      if (OrgtreeDatasSt) {
        let orgtreeDatas = JSON.parse(OrgtreeDatasSt);
        // 缓存每12个小时更新一次
        if (new Date().getTime() - orgtreeDatas.exprie < 12 * 60 * 60 * 1000) {
          cb && cb(orgtreeDatas.data);
          OrgtreeDatasSt = null;
          return false;
        } else {
          OrgtreeDatasSt = null;
          orgtreeDatas = null;
          window.localStorage.removeItem('OrgtreeDatas');
        }
      }
      /**
       * 查询初始化的三层组织信息
       */
      FetchQueryInitializationOrgs().then(response => {
        // 数据量太大 缓存一下
        window.localStorage.setItem('OrgtreeDatas', JSON.stringify({ data: response, exprie: new Date().getTime() }));
        cb && cb(response);
      });
    }
  }
};
</script>
<style scoped>
.ivu-tree{
  font-size: 12px;
}
.fill_title{
  line-height: 30px;
}
.ivu-tree-empty{
  line-height: 30px;
}
.split-y-line {
  width: 1px;
  opacity: 0.08;
  background: #424656;
  position: absolute;
  right: 4px;
  top: 0;
  height: 100%;
}
</style>
