<template>
  <es-tabs
    v-model="activeName"
    class="es-selector-panel"
    mold="border-card"
    :style="styles"
    @tab-click="handleClick"
  >
    <el-tab-pane
      v-for="items in trees"
      :key="items.label"
      :label="items.label"
      :name="items.name"
      class="es-selector-content"
    >
      <div class="es-selector-view">
        <tree
          v-if="isShowTree"
          :data="items.data"
          :loading="loading"
          @loadsub="loadsub"
          @search="searchTree"
        ></tree>
        <div class="es-selector-selection">
          <el-form
            ref="form"
            @submit.native.prevent
            :inline="true"
            :model="form"
            class="es-selector-selection-toolbar"
            v-if="multiple || isShowTree"
          >
            <el-form-item>
              <es-switch v-model="showDisabled" :data="options"></es-switch>
            </el-form-item>
            <el-form-item>
              <el-checkbox
                v-show="multiple && !max"
                v-model="checkAll"
                @change="handleCheckAll"
              >
                全选
              </el-checkbox>
            </el-form-item>
            <div class="es-float-right" v-if="isShowTree">
              <el-form-item v-if="showSelect && activeName == 'enterprise'">
                <es-select
                  v-model="selectValue"
                  placeholder="请选择"
                  @change="handleSelect"
                >
                  <el-option
                    v-for="item in filtrate.options"
                    :key="item.value"
                    :label="item.name"
                    :value="item.value"
                  ></el-option>
                </es-select>
              </el-form-item>
              <el-form-item>
                <el-input
                  v-model="search"
                  placeholder="请输入搜索关键字"
                  @change="handleChangeSearch"
                >
                  <template slot="append">
                    <el-button
                      icon="el-icon-search"
                      type="primary"
                      @click="handleSearch"
                    ></el-button>
                  </template>
                </el-input>
              </el-form-item>
            </div>
          </el-form>
          <selection
            v-model="checkeds"
            :data="checkboxs"
            :value-key="valueKey"
            :label-key="labelKey"
            :multiple="mix ? mix : multiple"
            :max="max"
            :showTooltip="showTooltip"
            :showDisabled="showDisabled"
            :disableds="disableds"
          ></selection>
          <selection
            v-model="checkeds"
            genre="delete"
            :data="Array.isArray(checkeds) ? checkeds : [checkeds]"
            :value-key="valueKey"
            :label-key="labelKey"
            :showTooltip="showTooltip"
            :multiple="multiple"
            :max="max"
            :mix="mix"
            :isSort="true"
            @sort="handleSort"
          ></selection>
        </div>
      </div>
      <div class="es-selector-handle">
        <span v-if="multiple && checkeds.length > 0" style="margin-right: 20px;color:red">
          已选 {{ checkeds.length }}
        </span>
        <el-button type="primary" size="small" @click="handleConfirm"
          >确定</el-button
        >
        <el-button size="small" @click="handleCancel">取消</el-button>
      </div>
    </el-tab-pane>
  </es-tabs>
</template>
<script>
import tree from './tree.vue';
import selection from './selection.vue';
import {
  getSelectorOrgTree,
  getSelectorOrgDetail
} from 'eoss-ui/src/config/api.js';
import { debounce } from 'throttle-debounce';
import util from 'eoss-ui/src/utils/util.js';
export default {
  name: 'EsSelectorPanel',
  inheritAttrs: false,
  components: {
    tree,
    selection
  },
  props: {
    isShowLevel3: {
      type: Boolean,
      default: true
    },
    method: {
      type: String,
      default: 'get'
    },
    host: {
      type: String,
      default: ''
    },
    value: [Array, Object, String],
    width: {
      type: String,
      default: '900px'
    },
    height: {
      type: String,
      default: '560px'
    },
    //树结构
    tree: {
      type: Boolean,
      default: true
    },
    type: {
      type: Array,
      default() {
        return ['enterprise', 'person'];
      }
    },
    active: String,
    //是否替换页签
    replace: {
      type: Boolean,
      default: false
    },
    showTooltip: {
      type: Boolean,
      default: true
    },
    //页签
    tabs: Object,
    filtrate: {
      type: [Boolean, Object],
      default() {
        return {
          show: true,
          value: '1',
          options: [
            {
              value: '1',
              name: '直接下级'
            },
            {
              value: '2',
              name: '所有下级'
            }
          ]
        };
      }
    },
    selection: {
      type: [String, Array],
      default: getSelectorOrgDetail
    },
    param: {
      type: Object,
      default() {
        return {};
      }
    },
    valueKey: {
      type: String,
      default: 'showid'
    },
    labelKey: {
      type: String,
      default: 'showname'
    },
    form: {
      type: Object,
      default() {
        return {};
      }
    },
    multiple: {
      type: Boolean,
      default: true
    },
    max: Number,
    mix: Boolean,
    disableds: {
      type: Array,
      default() {
        return [];
      }
    }
  },
  data() {
    return {
      styles: { width: this.width, height: this.height },
      loading: true,
      search: '',
      defaults: '',
      trees: '',
      checkAll: false,
      selectValue: this.filtrate.value,
      orgpath: false,
      nodeData: '',
      activeName: '',
      selections: [],
      checkboxs: [],
      checkeds: null,
      showDisabled: true,
      options: [
        {
          value: true,
          name: '展示'
        },
        {
          value: false,
          name: '过滤'
        }
      ]
    };
  },
  computed: {
    //是否显示树结构
    isShowTree() {
      if (typeof this.selection === 'object' && Array.isArray(this.selection)) {
        return false;
      } else {
        return this.tree;
      }
    },
    showSelect() {
      if (typeof this.filtrate === 'object') {
        return this.filtrate.show;
      } else {
        return false;
      }
    },
    actived: {
      get() {
        return this.active ? this.active : this.type[0];
      },
      set(val) {
        return val;
      }
    },
    newTabs() {
      const orgId = util.getStorage('orgId');
      const tabs = {
        enterprise: {
          label: '选择单位',
          name: 'enterprise',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 1,
            id: 0,
            filid: 'all'
          }
        },
        department: {
          label: '选择部门',
          name: 'department',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 0,
            id: 0,
            filid: 'all'
          }
        },
        employee: {
          label: '选择用户',
          name: 'employee',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 0,
            id: 0,
            filid: 'all'
          }
        },
        myemployee: {
          label: '本单位用户',
          name: 'myemployee',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 2,
            id: 0,
            filid: orgId
          }
        },
        otheremployee: {
          label: '外单位用户',
          name: 'otheremployee',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 0,
            id: 0,
            filid: 'all'
          }
        },
        person: {
          label: '选择人员',
          name: 'person',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 0,
            id: 0,
            filid: 'all'
          }
        },
        otherperson: {
          label: '外单位人员',
          name: 'otherperson',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 0,
            id: 0,
            filid: 'all'
          }
        },
        persongroup: {
          label: '选择群组成员',
          name: 'persongroup',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 3,
            id: 0,
            filid: 'all'
          }
        },
        filgroup: {
          label: '单位群组成员',
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          name: 'filgroup',
          url: getSelectorOrgTree,
          param: {
            showarea: 4,
            id: 0,
            filid: 'all'
          }
        },
        depgroup: {
          label: '部门群组成员',
          name: 'depgroup',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 5,
            id: 0,
            filid: 'all'
          }
        },
        persongroupobj: {
          label: '人员群组',
          name: 'persongroupobj',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 11,
            id: 0,
            filid: 'all'
          }
        },
        filgroupobj: {
          label: '单位群组',
          name: 'filgroupobj',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 13,
            id: 0,
            filid: 'all'
          }
        },
        depgroupobj: {
          label: '部门群组',
          name: 'depgroupobj',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 14,
            id: 0,
            filid: 'all'
          }
        },
        role: {
          label: '选择角色',
          name: 'role',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 6,
            id: 0,
            filid: 'all'
          }
        },
        post: {
          label: '选择岗位',
          name: 'post',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 8,
            id: 0,
            filid: 'all'
          }
        },
        codetable: {
          label: '代码表',
          name: 'codetable',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 10,
            id: 0,
            filid: 'all'
          }
        },
        topcontacts: {
          label: '常用联系人',
          name: 'topcontacts',
          url: getSelectorOrgTree,
          data: [],
          nodeData: '',
          selection: [],
          value: [],
          param: {
            showarea: 9,
            id: 0,
            filid: 'all'
          }
        }
      };
      if (this.tabs) {
        if (this.replace) {
          return this.tabs;
        } else {
          return util.extend(true, tabs, this.tabs);
        }
      }
      return tabs;
    }
  },
  watch: {
    type: {
      immediate: true,
      deep: true,
      handler(val, old) {
        if (
          old === undefined ||
          new Set([...val, ...old]).size !== val.length
        ) {
          var obj = {};
          this.activeName = this.actived;
          if (this.isShowTree) {
            for (let i in val) {
              obj[val[i]] = this.newTabs[val[i]];
            }
          } else {
            obj[this.activeName] = this.newTabs[this.activeName];
          }
          this.trees = obj;
          this.defaults = JSON.parse(JSON.stringify(obj));
        }
      }
    },
    activeName: {
      handler(val) {
        this.ajaxActive(val);
      }
    },
    tabs: {
      deep: true,
      handler() {
        this.loading = true;
        this.getTreeData(
          this.host + this.newTabs[this.activeName].url,
          this.newTabs[this.activeName].param
        );
      }
    },
    value: {
      immediate: true,
      handler(val) {
        if (val !== undefined) {
          this.trees[this.activeName].value = JSON.parse(JSON.stringify(val));
        } else {
          this.trees[this.activeName].value = '';
        }
        this.checkeds = this.trees[this.activeName].value || [];
      }
    },
    checkboxs(val) {
      let flag = this.checkboxs.length ? true : false;
      this.checkboxs.forEach((item) => {
        if (util.isObject(item)) {
          if (util.indexOfObj(this.checkeds, item) === -1) {
            flag = false;
            return;
          }
        } else {
          if (this.checkeds.indexOf(item) === -1) {
            flag = false;
            return;
          }
        }
      });
      this.checkAll = flag;
    },
    checkeds(res, old) {
      let val = res;
      // if (!Array.isArray(val)) {
      //   this.checkeds = [res];
      //   return;
      // }
      if (old.length > 0) {
        if (val.length < old.length) {
          this.checkAll = false;
        } else {
          let flag = true;
          this.checkboxs.forEach((item) => {
            if (util.isObject(item)) {
              if (util.indexOfObj(val, item) === -1) {
                flag = false;
                return;
              }
            } else {
              if (val.indexOf(item) === -1) {
                flag = false;
                return;
              }
            }
          });
          this.checkAll = flag;
        }
      }
      this.trees[this.activeName].value = val;
    }
  },
  beforeCreate() {
    this.ajaxActive = debounce(500, (active) => {
      this.getAjaxActive(active);
    });
  },
  created() {},
  mounted() {
    this.ajaxActive(this.activeName);
  },
  methods: {
    getAjaxActive(active) {
      if (this.isShowTree) {
        if (
          (!this.trees[active].data ||
            (this.trees[active].data &&
              this.trees[active].data.length === 0)) &&
          this.newTabs[active].url
        ) {
          this.loading = true;
          this.getTreeData(
            this.host + this.newTabs[active].url,
            this.newTabs[active].param
          );
        }
        if (
          !this.trees[active].value ||
          (this.trees[active].value && this.trees[active].value.length === 0)
        ) {
          if (this.value !== undefined) {
            this.trees[active].value = JSON.parse(JSON.stringify(this.value));
          }
        }
        this.checkboxs = this.trees[active].selection || [];
        if (!this.mix) {
          this.checkeds = this.trees[active].value || [];
        }
        this.nodeData = this.trees[active].nodeData;
      } else {
        if (typeof this.selection === 'string') {
          let params = this.param[this.activeName]
            ? this.param[this.activeName]
            : this.param;
          util
            .ajax({
              method: this.method,
              url: this.host + this.selection,
              params: params,
              data: params
            })
            .then((res) => {
              if (res.rCode === 0) {
                this.selections = JSON.parse(JSON.stringify(res.results));
                this.checkboxs = JSON.parse(JSON.stringify(res.results)) || [];
              }
            })
            .catch((err) => {
              if (err.message && err.message !== 'canceled') {
                this.$message.error(err.message);
              }
            });
        } else {
          this.selections = this.selection;
          this.checkboxs = this.selection || [];
        }
      }
    },
    getTreeData(url, params, id) {
      let data = util.extend(
        {},
        params,
        this.param[this.activeName] ? this.param[this.activeName] : this.param
      );
      if (id !== undefined) {
        data.id = id;
      }
      util
        .ajax({ method: this.method, url: url, params: data, data: data })
        .then((res) => {
          if (res.rCode === 0) {
            this.loading = false;
            if (!Object.prototype.hasOwnProperty.call(params, 'seachkey')) {
              this.$set(
                this.defaults[this.activeName],
                'data',
                JSON.parse(JSON.stringify(res.results))
              );
            }
            if (res.results.length && res.results[0].name === '无搜索数据') {
              this.$set(this.trees[this.activeName], 'data', null);
            } else {
              this.$set(
                this.trees[this.activeName],
                'data',
                JSON.parse(JSON.stringify(res.results))
              );
            }
          }
        })
        .catch((err) => {
          if (err.message && err.message !== 'canceled') {
            this.$message.error(err.message);
          }
        });
    },
    loadsub(data, node, flag) {
      node;
      if (flag) {
        if (data.selection === undefined || data.selection.length === 0) {
          this.checkAll = false;
          let params = util.extend(
            {},
            this.param[this.activeName]
              ? this.param[this.activeName]
              : this.param
          );
          params.type = this.activeName;
          params.mid = data.id;
          if (this.activeName === 'enterprise') {
            params.querymode = this.selectValue;
            if (this.selectValue === '2' || this.selectValue === 2) {
              params.orgpath =
                data.attributes && data.attributes.orgpath
                  ? data.attributes.orgpath
                  : '';
            }
          }
          // if (this.activeName === 'department') {
          //   params.querymode = 0;
          // }
          util
            .ajax({
              method: this.method,
              url: this.host + this.selection,
              params: params,
              data: params
            })
            .then((res) => {
              if (res.rCode === 0) {
                data.selection = JSON.parse(JSON.stringify(res.results));
                this.$set(
                  this.trees[this.activeName],
                  'selection',
                  JSON.parse(JSON.stringify(res.results))
                );
                this.$set(this.trees[this.activeName], 'nodeData', data);
                this.nodeData = this.trees[this.activeName].nodeData;
                this.checkboxs = this.trees[this.activeName].selection;
              }
            })
            .catch((err) => {
              if (err.message && err.message !== 'canceled') {
                this.$message.error(err.message);
              }
            });
        } else {
          this.trees[this.activeName].selection = data.selection;
          this.trees[this.activeName].nodeData = data;
          this.nodeData = this.trees[this.activeName].nodeData;
          this.checkboxs = this.trees[this.activeName].selection;
        }
      } else {
        if (!this.isShowLevel3) {
          data.state = '';
        }
        if (
          data.state !== '' &&
          (!data.children || data.children.length === 0)
        ) {
          let params = util.extend(
            {},
            this.newTabs[this.activeName].param,
            this.param[this.activeName]
              ? this.param[this.activeName]
              : this.param
          );
          params.id = data.id;
          util
            .ajax({
              method: this.method,
              url: this.host + this.newTabs[this.activeName].url,
              data: params,
              params: params
            })
            .then((res) => {
              if (res.rCode === 0) {
                this.loading = false;
                this.$set(
                  data,
                  'children',
                  JSON.parse(JSON.stringify(res.results))
                );
                this.$set(
                  this.defaults[this.activeName],
                  'data',
                  JSON.parse(JSON.stringify(this.trees[this.activeName].data))
                );
              }
            })
            .catch((err) => {
              if (err.message && err.message !== 'canceled') {
                this.$message.error(err.message);
              }
            });
        }
      }
    },
    searchTree(res) {
      if (res) {
        this.loading = true;
        let params = util.extend({}, this.newTabs[this.activeName].param, {
          seachkey: res
        });
        this.getTreeData(this.host + this.newTabs[this.activeName].url, params);
      } else {
        this.$set(
          this.trees[this.activeName],
          'data',
          this.defaults[this.activeName].data
        );
      }
    },
    handleCheckAll(res) {
      if (this.checkboxs.length > 0) {
        let isObject = util.isObject(this.checkboxs[0]);
        if (res) {
          if (this.isShowTree) {
            this.nodeData.checkAll = true;
            let checkeds = this.checkeds.concat(
              this.checkboxs.filter((item) => {
                return item.disabled !== true;
              })
            );
            if (checkeds.length > 0) {
              this.checkeds = util.arrUnique(
                checkeds,
                isObject ? this.valueKey : undefined
              );
            }
          } else {
            this.checkeds = this.checkboxs;
          }
        } else {
          if (this.isShowTree) {
            this.nodeData.checkAll = false;
            this.checkboxs.forEach((element) => {
              for (let i in this.checkeds) {
                if (
                  (isObject &&
                    this.checkeds[i][this.valueKey] ===
                      element[this.valueKey]) ||
                  this.checkeds[i] === element
                ) {
                  this.checkeds.splice(i, 1);
                  break;
                }
              }
            });
          } else {
            this.checkeds = [];
          }
        }
      }
    },
    handleSelect(res) {
      if (this.nodeData) {
        this.nodeData.selection = '';
        this.loadsub(this.nodeData, '', true);
      }
      this.$emit('filtratechage', this.trees, this.activeName);
    },
    handleChangeSearch() {
      if (this.search === '') {
        if (this.isShowTree) {
          this.checkboxs = this.nodeData.selection;
        } else {
          this.checkboxs = this.selections;
        }
      } else {
        if (this.isShowTree) {
          if (this.nodeData && this.nodeData.selection) {
            let arry = [];
            this.nodeData.selection.forEach((item) => {
              if (util.isObject(item)) {
                if (item[this.labelKey].indexOf(this.search) > -1) {
                  arry.push(item);
                }
              } else {
                if (item.indexOf(this.search) > -1) {
                  arry.push(item);
                }
              }
            });
            this.checkboxs = arry;
          }
        } else {
          let arry = [];
          this.selections.forEach((item) => {
            if (util.isObject(item)) {
              if (item[this.labelKey].indexOf(this.search) > -1) {
                arry.push(item);
              }
            } else {
              if (item.indexOf(this.search) > -1) {
                arry.push(item);
              }
            }
          });
          this.checkboxs = arry;
        }
      }
    },
    handleSearch() {
      if (this.isShowTree) {
        if (this.nodeData && this.nodeData.selection) {
          if (this.search !== '') {
            let arry = [];
            this.nodeData.selection.forEach((item) => {
              if (util.isObject(item)) {
                if (item[this.labelKey].indexOf(this.search) > -1) {
                  arry.push(item);
                }
              } else {
                if (item.indexOf(this.search) > -1) {
                  arry.push(item);
                }
              }
            });
            this.checkboxs = arry;
          }
        } else {
          let mid = '0-0-0-0-0';
          if (this.nodeData) {
            mid = this.nodeData.id;
          }
          util
            .ajax({
              url: this.selection,
              params: {
                mid: mid,
                querymode: this.selectValue,
                type: this.activeName,
                namelike: this.search
              }
            })
            .then((res) => {
              if (res.rCode === 0) {
                this.checkboxs = JSON.parse(JSON.stringify(res.results));
              }
            })
            .catch((err) => {
              if (err.message && err.message !== 'canceled') {
                this.$message.error(err.message);
              }
            });
        }
      } else {
        if (this.search !== '') {
          let arry = [];
          this.selections.forEach((item) => {
            if (util.isObject(item)) {
              if (item[this.labelKey].indexOf(this.search) > -1) {
                arry.push(item);
              }
            } else {
              if (item.indexOf(this.search) > -1) {
                arry.push(item);
              }
            }
          });
          this.checkboxs = arry;
        }
      }
    },
    handleClick() {
      this.$emit('tabschage', this.trees, this.activeName);
    },
    handleChange() {},
    handleConfirm() {
      if (!this.checkeds || (this.multiple && this.checkeds.length === 0)) {
        this.$message({
          message: '请选择',
          type: 'warning'
        });
      } else {
        this.$emit('input', this.checkeds);
        this.$emit('confirm', this.checkeds);
      }
    },
    handleCancel() {
      this.$emit('cancel', false);
    },
    handleSort(res) {
      let oldIndex = res.oldIndex;
      let newIndex = res.newIndex;

      this.checkeds.splice(newIndex, 0, this.checkeds[oldIndex]);
      if (oldIndex > newIndex) {
        this.checkeds.splice(oldIndex + 1, 1);
      } else {
        this.checkeds.splice(oldIndex, 1);
      }
    }
  }
};
</script>
