<template>
  <div class="es-tree-group" :class="{ 'es-tree-steps-group': steps }">
    <es-steps
      v-if="steps"
      class="es-steps-group"
      v-bind="steps"
      :is-click="false"
    ></es-steps>
    <div class="es-tree-group-left">
      <el-tabs
        v-if="tabs && tabs.length"
        v-model="active"
        type="card"
        class="es-tabs-tree-card"
        :class="{
          'es-tabs-tree-card-plus': mode == 'plus'
        }"
        @tab-click="handleSelect"
      >
        <el-tab-pane
          v-for="(item, index) in tabs"
          :label="item.text"
          :name="String(index)"
          :key="item.name"
        >
          <es-tree
            v-bind="item.tree"
            :ref="item.ref ? item.ref : 'groupTree' + index"
            :class="{
              'es-tabs-tree-plus': mode == 'plus'
            }"
            @node-click="
              (data, node) => {
                handleNodeClick(data, node, item);
              }
            "
            @check-change="
              () => {
                handleCheckChange(...arguments, item);
              }
            "
            @results="
              (res) => {
                handleResults(res, item);
              }
            "
            @sub-results="
              (res) => {
                handleSubResults(res, item);
              }
            "
            @current-first="
              (type, res) => {
                handleCurrentFirst(type, res, item);
              }
            "
            v-on="item.tree && item.tree.events ? item.tree.events : {}"
          >
            <template v-if="item.enterprise" slot="filtrate">
              <es-enterprise
                v-bind="getAttr(item.enterprise)"
                @change="handleChange"
                @confirm="handleConfirm"
                v-on="
                  item.enterprise && item.enterprise.events
                    ? item.enterprise.events
                    : {}
                "
              ></es-enterprise>
            </template>
          </es-tree>
        </el-tab-pane>
      </el-tabs>
      <es-tree
        v-else
        v-bind="tree"
        ref="groupTree"
        :class="{
          'es-tree-plus': mode == 'plus'
        }"
        @node-click="handleNodeClick"
        @check-change="handleCheckChange"
        @results="handleResults"
        @sub-results="handleSubResults"
        @current-first="handleCurrentFirst"
        v-on="tree.events ? tree.events : {}"
      >
        <template v-if="enterprise" slot="filtrate">
          <es-enterprise
            v-bind="getAttr(enterprise)"
            @change="handleChange"
            @confirm="handleConfirm"
            v-on="tree.events ? tree.events : {}"
          ></es-enterprise>
        </template>
        <template v-if="buttons" slot="button">
          <es-button
            v-for="(item, index) in buttons"
            :key="item.id || index"
            size="small"
            v-bind="item"
            v-on="item.events"
          ></es-button>
        </template>
      </es-tree>
    </div>
    <div class="es-tree-group-right">
      <slot name="contents">
        <es-form
          v-if="form"
          v-bind="form"
          :ref="form.ref ? form.ref : 'esForm'"
          v-on="{ ...$listeners, ...form.events }"
        >
        </es-form>
        <es-data-table
          v-else-if="table"
          size="mini"
          :mode="mode"
          v-bind="{ close: true, ...table, param: params }"
          :ref="table.ref ? table.ref : 'esDataTable'"
          v-on="{ ...$listeners, ...table.events }"
        >
          <template v-if="table.dialog" slot="dialog">
            <template v-if="Array.isArray(table.dialog)">
              <es-dialog
                v-for="(ele, ids) in table.dialog"
                :isReload="true"
                v-bind="
                  handleExclAttribute({
                    data: ele,
                    attrs: ['visible']
                  })
                "
                :key="ids"
                :visible.sync="ele.visible"
                v-on="{ ...ele.events }"
              >
              </es-dialog>
            </template>
            <es-dialog
              v-else
              :isReload="true"
              v-bind="
                handleExclAttribute({
                  data: table.dialog,
                  attrs: ['visible']
                })
              "
              :visible.sync="table.dialog.visible"
              v-on="{ ...table.dialog.events }"
            >
            </es-dialog>
          </template>
        </es-data-table>
        <template v-else-if="src">
          <iframe
            v-if="method === 'iframe'"
            :id="name"
            :name="name"
            frameborder="0"
            width="100%"
            height="100%"
            :src="src"
          ></iframe>
          <WujieVue
            v-else-if="method === 'wujie' && refresh"
            v-bind="wjprops"
            width="100%"
            height="100%"
            :name="wujieName"
            :url="getUrl(src)"
          ></WujieVue>
          <router-view
            :name="name"
            v-else-if="method === 'router' && refresh"
          />
        </template>
      </slot>
    </div>
    <slot></slot>
  </div>
</template>

<script>
import util from 'eoss-ui/src/utils/util';
const systemMode = util.getWinTopProperty('systemMode', 'default');
export default {
  name: 'EsTreeGroup',
  inheritAttrs: false,
  props: {
    mode: {
      type: String,
      default: systemMode
    },
    host: {
      type: String,
      default: ''
    },
    steps: Object,
    defaultActive: [String, Number],
    formData: {
      type: Object,
      default() {
        return {};
      }
    },
    tree: {
      type: Object,
      default() {
        return {
          title: '成员树'
        };
      }
    },
    syncKeys: {
      type: [Object, Boolean],
      default: true
    },
    triggerType: Array,
    enterprise: [Object, Boolean],
    buttons: Array,
    table: Object,
    form: Object,
    tabs: Array,
    src: String,
    name: String,
    onNodeClick: Function,
    onCheckChange: Function,
    props: Object,
    empty: {
      type: String,
      default: '#/empty'
    },
    zoom: false,
    iframe: Boolean,
    //点击节点作为table参数
    clickedAsSearch: {
      type: Boolean,
      default: true
    },
    //选择节点作为table参数
    checkedAsSearch: {
      type: Boolean,
      default: true
    },
    //点击节点清空table搜索参数
    clickeResetSearch: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    wujieName() {
      return this.name ? this.name : util.uuid(16);
    },
    method() {
      let src = this.src;
      this.refresh = false;
      if (src) {
        if (src.indexOf('//:') === 0) {
          return 'wujie';
        } else if (
          src.indexOf('dhtml') > -1 ||
          (src.indexOf('html') > -1 && src.indexOf('html#') === -1) ||
          this.iframe
        ) {
          return 'iframe';
        } else {
          const routes = this.$router.options.routes;
          if (routes) {
            let path = this.hasRouter(routes, src);
            if (path) {
              this.refresh = true;
              let index = decodeURI(src).indexOf('?');
              path = path + (index > -1 ? src.slice(index) : '');
              this.$router.push(path);
              return 'router';
            }
          }
          this.refresh = true;
          return 'wujie';
        }
      }
    }
  },
  watch: {
    defaultActive: {
      immediate: true,
      handler(val) {
        if (val !== undefined && this.tabs && this.tabs.length) {
          if (typeof val === 'string') {
            for (let i = 0; i < this.tabs.length; i++) {
              if (val === this.tabs[i].name) {
                this.active = String(i);
              }
            }
          } else {
            this.active = String(val);
          }
        }
      }
    },
    'table.param': {
      immediate: true,
      deep: true,
      handler(val, old) {
        if (!util.isObjectEqual(val, old)) {
          this.params = JSON.parse(JSON.stringify(val || {}));
        }
      }
    },
    checkeds: {
      deep: true,
      handler() {
        let params = this.setParams();
        if (params) {
          this.params = { ...this.params, ...params };
        }
      }
    }
  },
  data() {
    return {
      active: '0',
      checkeds: null,
      params: null,
      wjprops: {}
    };
  },
  created() {},
  mounted() {},
  methods: {
    handleExclAttribute({ data, attrs }) {
      return util.exclAttribute({
        data: data,
        attrs: attrs
      });
    },
    getUrl(url, param, res) {
      let urls = url.split('?');
      if (urls[0].indexOf('.js') > 0) {
        let props = util.extend(true, this.props || {}, res.props || {}, {
          _dialog: true,
          _dialogId: this.wujieName
        });
        this.wjprops = util.extend(
          true,
          { props: props },
          {
            plugins: [
              {
                jsBeforeLoaders: [{ src: url }]
              }
            ]
          }
        );
        this.show = true;
        return './primary.html' + urls[1] ? `?${urls[1]}` : '';
      }
    },
    setParams() {
      if (this.syncKeys === false) {
        return null;
      }
      if (
        (this.enterprise && JSON.stringify(this.enterprise) != '{}') ||
        (this.tabs &&
          this.tabs.length &&
          this.tabs[Number(this.active)].enterprise)
      ) {
        if (this.checkeds) {
          if (Array.isArray(this.checkeds)) {
            let creditCodes = [];
            this.checkeds.forEach((item) => {
              if (item.creditCode && item.creditCode !== 'undefined') {
                creditCodes.push(item.creditCode);
              } else {
                let data = JSON.parse(item.data.objdata);
                if (data.creditCode && data.creditCode !== 'undefined') {
                  creditCodes.push(data.creditCode);
                }
              }
            });
            return { creditCode: creditCodes.join(',') };
          } else {
            return { creditCode: this.checkeds.creditCode };
          }
        }
        return null;
      } else {
        if (this.checkeds) {
          let params = {};
          if (Array.isArray(this.checkeds)) {
            if (this.syncKeys && util.isObject(this.syncKeys)) {
              const syncKeys =
                this.tabs && this.tabs.length
                  ? this.syncKeys[Number(this.active)] || this.syncKeys
                  : this.syncKeys;
              for (let i in syncKeys) {
                params[i] = this.checkeds
                  .map((item) => {
                    if (
                      Object.prototype.hasOwnProperty.call(item, syncKeys[i])
                    ) {
                      return item[syncKeys[i]];
                    } else {
                      let data = JSON.parse(item.data.objdata);
                      return data[syncKeys[i]];
                    }
                  })
                  .join(',');
              }
            } else {
              params.id = this.checkeds
                .map((item) => {
                  return item.id;
                })
                .join(',');
            }
          } else {
            if (this.syncKeys && util.isObject(this.syncKeys)) {
              const syncKeys =
                this.tabs && this.tabs.length
                  ? this.syncKeys[Number(this.active)] || this.syncKeys
                  : this.syncKeys;
              for (let i in syncKeys) {
                params[i] = this.checkeds[syncKeys[i]];
              }
            } else {
              params.id = this.checkeds.id;
            }
          }
          return params;
        }
        return null;
      }
    },
    getAttr(res) {
      return typeof res === 'boolean' ? {} : res;
    },
    handleText(res) {
      if (typeof res === 'string') {
        return res;
      } else {
        return res.name || res.text || res.label;
      }
    },
    //数据表刷新
    reload(obj, first, tree) {
      if (this.table.ref) {
        this.$refs[this.table.ref].reload(obj, first);
      } else {
        this.$refs.esDataTable.reload(obj, first);
      }
      if (tree) {
        let ref =
          this.tabs && this.tabs.length
            ? this.tabs[Number(this.active)].ref
              ? this.tabs[Number(this.active)].ref
              : 'groupTree' + this.active
            : 'groupTree';
        const tree =
          this.$refs[ref] && this.$refs[ref][0]
            ? this.$refs[ref][0]
            : this.$refs[ref];
        tree && tree.getTreeData();
      }
    },
    //页签切换
    handleSelect() {
      this.$emit('tab-click', this.tabs[parseInt(this.active, 10)]);
    },
    handleNodeClick(data, node, tabs) {
      if (this.clickeResetSearch) {
        let ref = table.ref ? table.ref : 'esDataTable';
        this.$refs[ref].reset();
      }
      if (this.clickedAsSearch) {
        this.checkeds = data;
      }
      if (this.onNodeClick) {
        this.onNodeClick(this, data, node, tabs);
      } else {
        this.$emit('node-click', this, data, node, tabs);
      }
    },
    handleCheckChange() {
      let ref =
        this.tabs && this.tabs.length
          ? this.tabs[Number(this.active)].ref
            ? this.tabs[Number(this.active)].ref
            : 'groupTree' + this.active
          : 'groupTree';
      let checkeds = this.$refs[ref].getCheckedNodes();
      if (this.checkedAsSearch) {
        this.checkeds = checkeds;
      }
      if (this.onCheckChange) {
        this.onCheckChange(checkeds, ...arguments, this);
      } else {
        this.$emit('check-change', checkeds, ...arguments, this);
      }
    },
    handleChange(res) {
      this.$emit('enterprise-change', res);
    },
    handleConfirm(res) {
      this.checkeds = res;
      this.$emit('enterprise-confirm', res);
    },
    handleResults(res, tabs) {
      if (
        (this.tree.showCheckbox &&
          this.tree.checkedFirst &&
          this.checkedAsSearch) ||
        this.tree.currentFirst
      ) {
        this.checkeds = res[0];
      }
      this.$emit('results', res, tabs);
    },
    handleSubResults(res, tabs) {
      this.$emit('sub-results', res, tabs);
    },
    setCurrentKey(keys, leafOnly) {
      let ref =
        this.tabs && this.tabs.length
          ? this.tabs[Number(this.active)].ref
            ? this.tabs[Number(this.active)].ref
            : 'groupTree' + this.active
          : 'groupTree';
      this.$nextTick(() => {
        this.$refs[ref].setCurrentKey(keys, leafOnly);
      });
    },
    getTree() {
      let ref =
        this.tabs && this.tabs.length
          ? this.tabs[Number(this.active)].ref
            ? this.tabs[Number(this.active)].ref
            : 'groupTree' + this.active
          : 'groupTree';
      return this.$refs[ref];
    },
    handleCurrentFirst(type, res, tabs) {
      this.$emit('current-first', type, res, tabs);
    },
    hasRouter(res, url) {
      if (!url) {
        return false;
      }
      if (Array.isArray(res)) {
        for (let i in res) {
          let path = this.hasRouter(res[i], url);
          if (path) {
            return path;
          }
        }
      } else {
        let path = res.path;
        if (path !== '/' && path !== '/404') {
          path = path.replace(path[1], path[1].toLowerCase());
        }
        let pathname = url.substring(url.indexOf('#/') + 1);
        pathname = pathname
          .replace(pathname[1], pathname[1].toLowerCase())
          .split('?')[0];
        if (res.path !== '/' && pathname == path) {
          return pathname;
        }
        if (res && Object.prototype.hasOwnProperty.call(res, 'children')) {
          let path = this.hasRouter(res.children, url);
          if (path) {
            return path;
          }
        }
      }
      return false;
    }
  }
};
</script>
