<template>
  <div class="es-flow-group" :class="{ 'is-hide-flow': !isShow }">
    <div class="es-flow-group-main">
      <el-tabs
        class="es-flow-tabs es-tabs"
        type="border-card"
        v-model="activeName"
        ref="tabs"
        :before-leave="handleBefore"
      >
        <template v-for="(items, indexs) in tabs">
          <el-tab-pane
            v-if="handleHide(items.hide)"
            :key="items.id || indexs"
            :immediate="items.label === '流程图' ? false : items.immediate"
            :name="String(indexs)"
            :class="{ 'es-flex-vertical': items.average }"
          >
            <span
              slot="label"
              :style="{
                color:
                  activeName == String(indexs) ? items.activeColor : items.color
              }"
            >
              <template v-if="items.title">
                <template v-if="typeof items.title === 'object'">
                  <i v-if="items.title.icon" :class="items.title.icon"></i>
                  <el-badge
                    v-if="items.title.count"
                    type="primary"
                    :value="items.title.count"
                    :color="items.title.color"
                    :max="99"
                    >{{ items.title.text }}
                  </el-badge>
                  <template v-else>{{ items.title.text }}</template>
                </template>
                <template v-else>{{ items.title }}</template>
              </template>
              <template>{{ items.label }}</template>
            </span>
            <es-tabs-panel v-bind="items" :show="activeName === String(indexs)">
              <template
                slot-scope="{ contents, average, data, title, show, isShow }"
              >
                <template v-if="Array.isArray(contents)">
                  <template v-for="(item, index) in contents">
                    <div class="es-tab-pane-list" :key="index" v-if="average">
                      <div class="es-tab-pane-main">
                        <es-flow-list
                          v-if="
                            item.type === 'flow-list' ||
                            item.type === 'flowList'
                          "
                          :businessId="businessId"
                          v-bind="
                            handleExclAttribute({
                              data: item,
                              attrs: ['events', 'visible', 'type']
                            })
                          "
                          :display="activeName === String(indexs)"
                          :key="index"
                        ></es-flow-list>
                        <es-data-table
                          v-if="
                            item.type === 'data-table' ||
                            item.type === 'dataTable'
                          "
                          :appId="taskExamineAppId"
                          v-bind="
                            handleExclAttribute({
                              data: item,
                              attrs: ['events', 'visible', 'type']
                            })
                          "
                          :class="{
                            'es-flow-group-data-table':
                              item.type === 'data-table' ||
                              item.type === 'dataTable'
                          }"
                          :display="activeName === String(indexs)"
                          v-on="item.events"
                        >
                          <template v-if="item.dialog" slot="dialog">
                            <template v-if="Array.isArray(item.dialog)">
                              <es-dialog
                                v-for="(ele, ids) in item.dialog"
                                :isReload="true"
                                v-bind="ele"
                                :key="ids"
                                :visible.sync="ele.visible"
                                v-on="{ ...ele.events }"
                              >
                              </es-dialog>
                            </template>
                            <es-dialog
                              v-else
                              :isReload="true"
                              v-bind="item.dialog"
                              :visible.sync="item.dialog.visible"
                              v-on="{ ...item.dialog.events }"
                            >
                            </es-dialog>
                          </template>
                        </es-data-table>
                        <es-tree-group
                          v-if="
                            item.type === 'tree-group' ||
                            item.type === 'treeGroup'
                          "
                          :appId="taskExamineAppId"
                          v-bind="
                            handleExclAttribute({
                              data: item,
                              attrs: ['events', 'visible', 'type']
                            })
                          "
                          :display="activeName === String(indexs)"
                          v-on="{ ...item.events }"
                        ></es-tree-group>
                        <iframe
                          v-if="item.type === 'iframe' && !item.blank"
                          :id="item.id || item.name"
                          :name="item.name"
                          frameborder="0"
                          width="100%"
                          height="100%"
                          :src="handleUrlJoinParams(item)"
                        ></iframe>
                        <es-upload
                          v-if="item.type === 'attachment'"
                          :file-count.sync="title.count"
                          height="auto"
                          class="es-attachment"
                          :ownId="businessId"
                          v-bind="
                            handleExclAttribute({
                              data: item,
                              attrs: ['events', 'type']
                            })
                          "
                          :display="activeName === String(indexs)"
                          v-on="{ ...item.events }"
                        ></es-upload>
                      </div>
                    </div>
                    <template v-else>
                      <es-form
                        v-if="item.type === 'form'"
                        ref="esFlowForm"
                        :showMsg="showMsg"
                        v-bind="
                          handleExclAttribute({
                            data: item,
                            attrs: ['events', 'visible', 'type', 'model', 'ref']
                          })
                        "
                        full
                        :key="index"
                        :autoId="true"
                        :show-button="false"
                        :closeDialog="false"
                        :display="activeName === String(indexs)"
                        :model="item.model"
                        :businessId.sync="businessId"
                        v-on="{ ...item.events }"
                      ></es-form>
                      <es-flow-list
                        v-if="
                          item.type === 'flow-list' || item.type === 'flowList'
                        "
                        :businessId="businessId"
                        v-bind="
                          handleExclAttribute({
                            data: item,
                            attrs: ['events', 'visible', 'type']
                          })
                        "
                        :display="activeName === String(indexs)"
                        :key="index"
                      ></es-flow-list>
                      <es-data-table
                        v-if="
                          item.type === 'data-table' ||
                          item.type === 'dataTable'
                        "
                        :appId="taskExamineAppId"
                        v-bind="
                          handleExclAttribute({
                            data: item,
                            attrs: ['events', 'visible', 'type']
                          })
                        "
                        :key="index"
                        :class="{
                          'es-flow-group-data-table':
                            item.type === 'data-table' ||
                            item.type === 'dataTable'
                        }"
                        :display="activeName === String(indexs)"
                        v-on="item.events"
                      >
                        <template v-if="item.dialog" slot="dialog">
                          <template v-if="Array.isArray(item.dialog)">
                            <es-dialog
                              v-for="(ele, ids) in item.dialog"
                              :isReload="true"
                              v-bind="ele"
                              :key="ids"
                              :visible.sync="ele.visible"
                              v-on="{ ...ele.events }"
                            >
                            </es-dialog>
                          </template>
                          <es-dialog
                            v-else
                            :isReload="true"
                            v-bind="item.dialog"
                            :visible.sync="item.dialog.visible"
                            v-on="{ ...item.dialog.events }"
                          >
                          </es-dialog>
                        </template>
                      </es-data-table>
                      <es-tree-group
                        v-if="
                          item.type === 'tree-group' ||
                          item.type === 'treeGroup'
                        "
                        :appId="taskExamineAppId"
                        v-bind="
                          handleExclAttribute({
                            data: item,
                            attrs: ['events', 'visible', 'type']
                          })
                        "
                        :key="index"
                        :display="activeName === String(indexs)"
                        v-on="{ ...item.events }"
                      ></es-tree-group>
                      <iframe
                        v-if="item.type === 'iframe' && !item.blank"
                        frameborder="0"
                        width="100%"
                        height="100%"
                        :key="index"
                        :id="item.id || item.name"
                        :name="item.name"
                        :src="handleUrlJoinParams(item)"
                      ></iframe>
                      <es-upload
                        v-if="item.type === 'attachment'"
                        height="auto"
                        class="es-attachment"
                        :ownId="businessId"
                        v-bind="
                          handleExclAttribute({
                            data: item,
                            attrs: ['events', 'type']
                          })
                        "
                        :key="index"
                        :file-count.sync="title.count"
                        :display="activeName === String(indexs)"
                        v-on="{ ...item.events }"
                      ></es-upload>
                      <es-dialog
                        v-if="
                          item.type === 'dialog' &&
                          activeName === String(indexs)
                        "
                        :isReload="true"
                        v-bind="item"
                        :key="index"
                        :visible.sync="item.visible"
                        v-on="{ ...item.events }"
                      >
                      </es-dialog>
                      <component
                        v-if="item.component || item.type == 'component'"
                        :is="item.is || item.type"
                        show
                        isShow
                        v-bind="
                          handleExclAttribute({
                            data: item,
                            attrs: ['is', 'type']
                          })
                        "
                      ></component>
                    </template>
                  </template>
                </template>
                <template v-else>
                  <component
                    v-if="contents.component || contents.type == 'component'"
                    :is="contents.is || contents.type"
                    show
                    isShow
                    v-bind="
                      handleExclAttribute({
                        data: contents,
                        attrs: ['is', 'type']
                      })
                    "
                  ></component>
                  <es-form
                    v-if="contents.type === 'form'"
                    :show-button="false"
                    ref="esFlowForm"
                    :showMsg="showMsg"
                    v-bind="
                      handleExclAttribute({
                        data: contents,
                        attrs: ['events', 'visible', 'type', 'model', 'ref']
                      })
                    "
                    full
                    :autoId="true"
                    :businessId.sync="businessId"
                    :closeDialog="false"
                    :display="activeName === String(indexs)"
                    :model="contents.model"
                    v-on="{ ...contents.events }"
                  ></es-form>
                  <es-flow-list
                    v-if="
                      contents.type === 'flow-list' ||
                      contents.type === 'flowList'
                    "
                    :businessId="businessId"
                    v-bind="
                      handleExclAttribute({
                        data: contents,
                        attrs: ['events', 'visible', 'type']
                      })
                    "
                    :display="activeName === String(indexs)"
                  ></es-flow-list>
                  <es-data-table
                    v-if="
                      contents.type === 'data-table' ||
                      contents.type === 'dataTable'
                    "
                    :appId="taskExamineAppId"
                    v-bind="
                      handleExclAttribute({
                        data: contents,
                        attrs: ['events', 'visible', 'type']
                      })
                    "
                    :class="{
                      'es-flow-group-data-table':
                        contents.type === 'data-table' ||
                        contents.type === 'dataTable'
                    }"
                    :display="activeName === String(indexs)"
                    v-on="contents.events"
                  >
                    <template v-if="contents.dialog" slot="dialog">
                      <template v-if="Array.isArray(contents.dialog)">
                        <es-dialog
                          v-for="(ele, ids) in contents.dialog"
                          :isReload="true"
                          v-bind="ele"
                          :key="ids"
                          :visible.sync="ele.visible"
                          v-on="{ ...ele.events }"
                        >
                        </es-dialog>
                      </template>
                      <es-dialog
                        v-else
                        :isReload="true"
                        v-bind="contents.dialog"
                        :visible.sync="contents.dialog.visible"
                        v-on="{ ...contents.dialog.events }"
                      >
                      </es-dialog>
                    </template>
                  </es-data-table>
                  <es-tree-group
                    v-if="
                      contents.type === 'tree-group' ||
                      contents.type === 'treeGroup'
                    "
                    :appId="taskExamineAppId"
                    v-bind="
                      handleExclAttribute({
                        data: contents,
                        attrs: ['events', 'visible', 'type']
                      })
                    "
                    :display="activeName === String(indexs)"
                    v-on="{ ...contents.events }"
                  ></es-tree-group>
                  <iframe
                    v-if="contents.type === 'iframe' && !contents.blank"
                    :id="contents.id || contents.name"
                    :name="contents.name"
                    frameborder="0"
                    width="100%"
                    height="100%"
                    :src="handleUrlJoinParams(contents)"
                  ></iframe>
                  <es-upload
                    v-if="contents.type === 'attachment'"
                    :ownId="businessId"
                    v-bind="
                      handleExclAttribute({
                        data: contents,
                        attrs: ['events', 'type']
                      })
                    "
                    :file-count.sync="title.count"
                    :display="activeName === String(indexs)"
                    height="auto"
                    class="es-attachment"
                    v-on="{ ...contents.events }"
                  ></es-upload>
                </template>
              </template>
            </es-tabs-panel>
          </el-tab-pane>
        </template>
      </el-tabs>
    </div>
    <es-flow
      v-if="isShow"
      class="es-group-flow"
      v-bind="_flow"
      :width="width"
      :before-submit="isSubmit ? handleSubmit : undefined"
      :businessId="businessId"
      @startTaskRead="handleTaskRead"
      @success="handleSuccess"
      @save="handleSave"
      @endMessageChange="handleEndMessageChange"
      :closeParent="closeParent"
    ></es-flow>
    <slot></slot>
  </div>
</template>
<script>
import util from 'eoss-ui/src/utils/util';
export default {
  name: 'EsFlowGroup',
  inject: {
    esDialog: {
      default: ''
    },
    injector: {
      default: ''
    }
  },
  props: {
    // autoId: {
    //   type: Boolean,
    //   default: true
    // },
    active: {
      type: String,
      default: '0'
    },
    contents: Array,
    closeWindow: Boolean,
    closeDialog: {
      type: Boolean,
      default: true
    },
    otherValidate: Function,
    flow: Object,
    events: Object,
    recordid: String,
    pendingId: String,
    arcurl: String,
    itemname: String,
    show: {
      type: Boolean,
      default: true
    },
    closeParent: {
      type: Boolean,
      default: true
    },
    appId: String,
    zoom: false,
    width: {
      type: String,
      default: '360px'
    },
    refs: String,
    isSubmit: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      activeName: this.active,
      businessId: undefined,
      taskExamineAppId: this.appId,
      showMsg: true,
      formRefs: this.refs,
      submits: null
    };
  },
  computed: {
    tabs() {
      return this.contents ? this.contents : [];
    },
    isShow() {
      if (
        this.flow &&
        Object.prototype.hasOwnProperty.call(this.flow, 'show')
      ) {
        return this.flow.show;
      }
      let flow = util.getParams({ name: 'flow' });
      if (flow == 0) {
        return false;
      }
      return this.show;
    },
    _flow() {
      return !this.flow.pendingId
        ? { ...this.flow, pendingId: this.pendingId }
        : this.flow;
    }
  },
  watch: {
    activeName(val) {
      this.$emit('update:active', val);
    },
    businessId(val) {
      this.handleChangeData({ businessId: val });
    }
  },
  created() {
    if (this.flow.businessId || this.flow.pendingId) {
      this.businessId = this.flow.businessId || this.flow.pendingId;
    }
  },
  mounted() {},
  methods: {
    handleHide(res) {
      return typeof res === 'boolean'
        ? !res
        : typeof res === 'string'
        ? this[res]
        : true;
    },
    handleExclAttribute({ data, attrs }) {
      if (!attrs || !attrs.length) {
        this.ref && (this.formRefs = this.ref);
        return data;
      }
      return util.exclAttribute({
        data: data,
        attrs: attrs
      });
    },
    handleUrlJoinParams(res, flag = true) {
      let url = res.url;
      if (flag) {
        if (res.method) {
          this.submit = {
            id: res.id,
            url: url,
            method: typeof res.method === 'boolean' ? 'submit' : res.method
          };
        }
      }
      let param = util.extend(
        {},
        { id: this.businessId, appId: this.taskExamineAppId },
        res.param || {}
      );
      return util.urlJoinParams({ url, param });
    },
    handleBefore(active, old) {
      return new Promise((resolve, reject) => {
        let n = parseInt(active, 10);
        let item = this.tabs[n];
        let url = null;
        let name = item.name;
        let width = 0;
        let height = 0;
        width = util.win.screen.availWidth - 10;
        height = util.win.screen.availHeight - 60;
        if (item.url) {
          url = this.handleUrlJoinParams(item);
        }
        if (
          item.contents &&
          item.contents.type === 'iframe' &&
          item.contents.blank
        ) {
          item.contents.name && (name = item.contents.name);
          url = this.handleUrlJoinParams(item.contents);
        }
        if (url) {
          reject();
          util.win.open(
            url,
            name,
            `width=${width}px,height=${height}px,resizable=yes,status=yes,menubar=no,scrollbars=yes`
          );
        } else {
          resolve();
        }
      });
    },
    handleSubmit(res) {
      if (this.submit) {
        if (this.submit.id) {
          let iframe = document.getElementById(this.submit.id); //先找到ifram

          if (this.submit.url) {
            let url = new URL(this.submit.url);
            let origin = url.origin;
            let _origin = util.win.location.origin;
            if (origin != _origin) {
              iframe.contentWindow.postMessage({ submit: res }, '*');
              return new Promise((resolve, reject) => {
                window.addEventListener('message', function (obj) {
                  if (obj.origin == origin) {
                    let results = obj.data;
                    if (results.code == 0) {
                      resolve();
                    } else {
                      reject();
                    }
                  }
                });
              });
            }
          }
          return iframe.contentWindow[this.submit.method](res); //用dom对象调用子页面的方法
        }
      }
      let esFlowForm = this.formRefs
        ? this.$refs[this.formRefs]
        : this.$refs.esFlowForm;
      if (Array.isArray(esFlowForm)) {
        esFlowForm = esFlowForm[0];
      }
      esFlowForm;
      this.showMsg = res == 1 ? false : true;

      if (this.otherValidate) {
        return new Promise((resolve, reject) => {
          esFlowForm
            .submitData(undefined, false, res, res === 1)
            .then(() => {
              // 如果submitData验证通过，则执行otherValidate验证
              this.otherValidate(resolve, reject);
            })
            .catch((error) => {
              // 处理submitData可能抛出的错误
              reject(error);
            });
        });
      }
      return esFlowForm.submitData(undefined, false, res, res === 1);
    },
    handleTaskRead(res) {
      if (res.data.taskExamine && res.data.taskExamine.appId) {
        this.taskExamineAppId = res.data.taskExamine.appId;
        this.injector &&
          this.injector.handleChangeData({ appId: this.taskExamineAppId });
      }
    },
    handleEndMessageChange(val) {
      this.$emit('endMessageChange', val);
    },
    handleSuccess() {
      let windowOpenConfig = sessionStorage.getItem('windowOpenConfig');
      if (this.closeWindow && windowOpenConfig) {
        util.busEmit(this, {
          method: 'windowClose',
          ...JSON.parse(windowOpenConfig)
        });
        try {
          const topWin = util.getWinTop();
          topWin.windowClose(JSON.parse(windowOpenConfig));
        } catch (error) {
          console.warn('Failed to call windowClose:', error);
        }
      } else if (this.closeDialog && this.esDialog) {
        this.esDialog.handleClose();
      } else {
        try {
          const topWin = util.getWinTop();
          if (topWin.COOS_SDK) {
            topWin.COOS_SDK.closePopup && topWin.COOS_SDK.closePopup();
          } else if (topWin.opener) {
            topWin.close();
          }
        } catch (error) {
          console.warn('Failed to close window/popup:', error);
        }
      }
      if (this.events && this.events.success) {
        this.events.success();
      }
      this.$emit('success');
    },
    handleSave(id, event) {
      let windowOpenConfig = sessionStorage.getItem('windowOpenConfig');
      if (this.closeWindow && windowOpenConfig) {
        util.busEmit(this, {
          method: 'windowClose',
          ...JSON.parse(windowOpenConfig)
        });
        try {
          const topWin = util.getWinTop();
          topWin.windowClose(JSON.parse(windowOpenConfig));
        } catch (error) {
          console.warn('Failed to call windowClose:', error);
        }
      } else if (this.closeDialog && this.esDialog) {
        this.esDialog.handleClose();
      } else {
        try {
          const topWin = util.getWinTop();
          if (topWin.COOS_SDK) {
            topWin.COOS_SDK.closePopup && topWin.COOS_SDK.closePopup();
          } else if (topWin.opener) {
            topWin.close();
          }
        } catch (error) {
          console.warn('Failed to close window/popup:', error);
        }
      }
      this.events && this.events.save(id, event);
      this.$emit('save', id, event);
    },
    handleChangeId(id) {
      this.businessId = id;
    },
    handleChangeData(res) {
      this.$emit('changeData', res);
      this.$emit('change-data', res);
    }
  }
};
</script>
