<template>
  <div class="es-main-box" v-if="isLogin">
    <simplicity
      ref="main"
      v-if="layoutType == 'simplicity'"
      :appCode="appCode"
      :old-version="multiple"
      v-bind="$attrs"
      v-on="$listeners"
      @chang-layout="changLayout"
      @bus-emit="busEmit"
    ></simplicity>
    <simplicityTop
      ref="main"
      v-else-if="layoutType == 'simplicityTop'"
      :appCode="appCode"
      :old-version="multiple"
      v-bind="$attrs"
      v-on="$listeners"
      @chang-layout="changLayout"
      @bus-emit="busEmit"
    ></simplicityTop>
    <main-default
      v-else
      :new-version="multiple"
      :appCode="appCode"
      :scene="layout"
      v-bind="$attrs"
      ref="main"
      v-on="$listeners"
      @chang-layout="changLayout"
      @bus-emit="busEmit"
      @getOriginParentMenu="$emit('getOriginParentMenu', $event)"
    ></main-default>

    <!-- 公用弹窗 -->
    <es-dialog
      class="es-main-public-dialog"
      v-for="(item, index) in dialogs"
      :custom-class="
        'es-public-dialog' +
        (item.customClassNames ? ` ${item.customClassNames}` : '')
      "
      modal-class="es-main-public-dialog-modal"
      :class="item.classNames"
      :visible.sync="item.visible"
      :key="item.appCode || item.id || item.name || index"
      :title="item.name || item.title"
      :width="item.width"
      :height="item.height"
      :size="item.size"
      @close="handleClosed(item, index)"
    >
      <template v-if="item.visible">
        <es-wujie
          v-if="item.openModel === 'wujie' && !isIE"
          :host="host"
          :show="true"
          :name="item.appCode"
          :url="item.url"
          :props="item"
        ></es-wujie>
        <iframe
          v-else
          width="100%"
          height="100%"
          frameborder="0"
          :id="item.appCode || item.id"
          :src="item.url"
          @load="(event) => handleIframeLoad(event.target, item)"
        ></iframe>
      </template>
    </es-dialog>
    <!-- 公用弹窗 end -->
  </div>
</template>
<script>
import { dayImg, nightImg } from 'eoss-ui/src/config/image';
import Simplicity from './simplicity/index.vue';
import SimplicityTop from './simplicityTop/index.vue';
import MainDefault from './default/index.vue';
import util from 'eoss-ui/src/utils/util';
import WujieVue from 'wujie-vue2';
export default {
  name: 'EsMain',
  inheritAttrs: false,
  provide() {
    return {
      reLogin: this.handleReLogin
    };
  },
  components: {
    Simplicity,
    SimplicityTop,
    MainDefault
  },
  props: {
    scene: String,
    launch: Boolean,
    type: String,
    launchImage: {
      type: [String, Object],
      default() {
        return {
          day: dayImg,
          night: nightImg
        };
      }
    },
    launchTime: {
      type: Number,
      default: 3000
    },
    multiple: Boolean,
    changeThemeReload: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    _launchImage() {
      let img = util.isObject(this.launchImages)
        ? this.launchImages[this.launchKey]
        : this.launchImages;
      return { 'background-image': `url(${img})` };
    }
  },
  data() {
    return {
      sysCode: '',
      appCode: '',
      params: {},
      dialogs: [],
      visibles: [],
      isLogin: false,
      layoutType: this.type,
      layout: this.scene,
      isIE: /MSIE|Trident/.test(navigator.userAgent)
    };
  },
  created() {
    const layoutType = localStorage.getItem('layoutType');
    if (layoutType) {
      this.layoutType = layoutType;
    }
    this.params = util.getParams() || {};
    this.sysCode = this.params.sysCode;
    this.appCode = this.params.appCode || this.params.appcode;
    if (
      this.params.cookie &&
      (this.params.cookie == true || this.params.cookie == 1)
    ) {
      this.isLogin = true;
    }
  },
  mounted() {
    const token = util.getStorage('token') || util.getStorage('Authorization');
    this.isLogin = token ? true : this.isLogin;
    if (
      !token &&
      Object.prototype.hasOwnProperty.call(this.params, 'serverId') &&
      Object.prototype.hasOwnProperty.call(this.params, 'authType')
    ) {
      return false;
    }
    this.$nextTick(() => {
      // 当主题变化时，重新绑定一次事件 防止事件丢失 或者绑定错误
      this.bindEvent();
    });
  },
  methods: {
    /**
     * @desc: 绑定事件
     **/
    bindEvent() {
      // 先解绑事件,以免弹出多次
      this.unbindEvent();
      if (this.isLogin) {
        if (util.win.$wujie) {
          util.win.$wujie.bus.$on('changeTheme', (res) => {
            util.updateTheme(res);
          });
        }
        this.$nextTick(() => {
          this.getConfig();
          const bus = this.bus || this.$root.Bus;
          if (bus) {
            bus.$on('reLogin', this.handleReLogin);
            bus.$on('refresh', this.$refs.main.handleRefresh);
            bus.$on('menuRefresh', this.$refs.main.handleRefresh);
            bus.$on('windowOpen', this.winOpen);
            bus.$on('windowClose', this.winClose);
            bus.$on('jumpMenu', this.$refs.main.jumpMenu);
            bus.$on('emit', (method, args) => {
              // 主应用发送事件
              bus.$emit(method, args);
            });
          }
          util.win.reLogin = this.handleReLogin;
          util.win.windowOpen = this.winOpen;
          util.win.windowClose = this.winClose;
          util.win.refresh = this.$refs.main.handleRefresh;
          util.win.menuRefresh = this.$refs.main.handleRefresh;
          util.win.jumpMenu = this.$refs.main.jumpMenu;
          WujieVue.bus.$on('reLogin', this.handleReLogin);
          WujieVue.bus.$on('refresh', this.$refs.main.handleRefresh);
          WujieVue.bus.$on('menuRefresh', this.$refs.main.handleRefresh);
          WujieVue.bus.$on('jumpMenu', this.$refs.main.jumpMenu);
          WujieVue.bus.$on('windowOpen', this.winOpen);
          WujieVue.bus.$on('windowClose', this.winClose);
          WujieVue.bus.$on('emit', (method, args) => {
            // 主应用发送事件
            WujieVue.bus.$emit(method, args);
          });

          window.addEventListener('message', this.handleMessage);
        });
      } else {
        const loginPage =
          util.getStorage('login') || util.getStorage('loginPage');
        if (loginPage) {
          window.location.replace(loginPage);
        } else if (document.referrer) {
          const referrerUrl = new URL(document.referrer);
          if (referrerUrl.host !== window.location.host) {
            window.location.replace(document.referrer);
          } else if (
            window.location.href.indexOf('main.html') > -1 ||
            window.location.href.indexOf('index.html') > -1 ||
            document.referrer.indexOf('main.html') > -1 ||
            document.referrer.indexOf('index.html') > -1
          ) {
            window.location.href = './login.html';
          } else {
            this.$router.replace('/login');
          }
        } else if (window.location.href.indexOf('main.html') > -1) {
          window.location.href = './login.html';
        } else {
          this.$router.replace('/login');
        }
      }
    },
    /**
     * @desc: 解绑事件
     **/
    unbindEvent() {
      window.removeEventListener('message', this.handleMessage);
      const bus = this.bus || this.$root.Bus;
      if (bus) {
        bus.$off('reLogin');
        bus.$off('refresh');
        bus.$off('menuRefresh');
        bus.$off('windowOpen');
        bus.$off('windowClose');
        bus.$off('jumpMenu');
        bus.$off('emit');
      }
      WujieVue.bus.$off('reLogin');
      WujieVue.bus.$off('refresh');
      WujieVue.bus.$off('menuRefresh');
      WujieVue.bus.$off('jumpMenu');
      WujieVue.bus.$off('emit');
    },
    /**
     * @desc: 切换布局风格
     * @author huangbo
     * @date 2024年9月7日
     **/
    changLayout(res, active) {
      this.layoutType = res;
      localStorage.setItem('layoutType', res);
      if (active) {
        this.layout = active;
      }
      // 重新加载页面，刷新布局风格配置信息
      // 如果不刷新,会导致事件绑定出现问题，导致事件丢失
      if (this.changeThemeReload) {
        window.location.reload();
        return;
      }

      let mainConfig = util.getStorage('mainConfig');
      // 切换布局风格后，重新绑定事件
      this.$nextTick(() => {
        this.bindEvent();
        if (mainConfig) {
          mainConfig = JSON.parse(mainConfig);
          this.$refs.main.init(mainConfig, true);
          util.getMainConfig((res) => {
            this.$refs.main.init(res, false);
          });
        } else {
          util.getMainConfig((res) => {
            this.$refs.main.init(res, true);
          });
        }
      });
    },
    /**
     * @desc:重新登录
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleReLogin(res) {
      if (res && typeof res == 'string') {
        res = JSON.parse(res);
      }
      let msg = '提示';
      let btn = {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        closeOnClickModal: false,
        type: 'warning'
      };
      if (res) {
        if (res.rCode === 69) {
          msg = '该账号在其他地方已登陆!';
          btn = {
            confirmButtonText: '确定',
            closeOnClickModal: false,
            type: 'warning'
          };
        } else {
          msg = '登录已过期，请重新登录！';
        }
      }
      cl;
      let remind = sessionStorage.getItem('remind');
      if (!remind) {
        clearTimeout(this.timer);
        this.timer = setTimeout(() => {
          console.log('handleReLogin');
          sessionStorage.setItem('remind', 1);
          this.$confirm(msg, btn)
            .then(() => {
              util.removeStorage([
                'Authorization',
                'token',
                'ssId',
                'userId',
                'userName',
                'auth',
                'deviceUnique',
                'menus',
                'useCaseCodes',
                'mainConfig',
                'jump'
              ]);
              const loginPage =
                util.getStorage('login') || util.getStorage('loginPage');
              try {
                const topWin = util.getWinTop();
                if (loginPage) {
                  let src;
                  if (!util.startWith(loginPage, ['http', '/'], true)) {
                    let pathname = topWin.location.pathname;
                    if (pathname !== '/') {
                      pathname = pathname.split('/');
                      pathname.splice(pathname.length - 1);
                      pathname = pathname.join('/');
                      src = pathname + '/' + loginPage.replace('./', '');
                    } else {
                      src = pathname + loginPage.replace('./', '');
                    }
                  } else {
                    src = loginPage;
                  }
                  topWin.location.href = src;
                } else if (topWin.location.href.indexOf('main.html') > -1) {
                  topWin.location.href = './login.html';
                } else {
                  const hash = topWin.location.hash;
                  if (hash) {
                    const len = topWin.location.href.indexOf(hash);
                    topWin.location.href =
                      util.win.location.href.slice(0, len) + '#/login';
                  } else {
                    topWin.location.href = '/login.html';
                  }
                }
              } catch (error) {}
            })
            .catch((e) => {
              sessionStorage.removeItem('remind');
            });
        }, 2000);
      }
    },
    /**
     * @desc:获取系统配置
     * @author huangbo
     * @date 2024年9月7日
     **/
    getConfig() {
      let mainConfig = util.getStorage('mainConfig');
      if (mainConfig) {
        mainConfig = JSON.parse(mainConfig);
        this.$refs.main.init(mainConfig, true);
        util.getMainConfig((res) => {
          this.$refs.main.init(res, false);
        });
      } else {
        util.getMainConfig((res) => {
          this.$refs.main.init(res, true);
        });
      }
    },
    /**
     * @desc:打开dialog页面
     * @author huangbo
     * @date 2024年9月7日
     **/
    winOpen({
      url,
      name,
      width = '100%',
      height = '100%',
      appCode,
      id,
      size,
      ...config
    }) {
      url = typeof arguments[0] === 'string' ? arguments[0] : url;
      id = id ? id : appCode ? undefined : 'iframe' + this.dialogs.length;
      const openModel = util.getStorage('openModel');
      let src = url;
      if (!util.startWith(url, ['http', '/'], true)) {
        let pathname = window.location.pathname;
        if (pathname !== '/') {
          pathname = pathname.split('/');
          pathname.splice(pathname.length - 1);
          pathname = pathname.join('/');
        }
        src = pathname + url.replace('./', '/');
      }
      if (openModel && openModel == 'dialog') {
        let dialog = {
          id,
          url: src,
          name,
          width,
          height,
          appCode,
          visible: false,
          size,
          ...config
        };
        let n = this.dialogs.push(dialog);
        this.$nextTick(() => {
          this.$set(dialog, 'index', n - 1);
          this.$set(dialog, 'visible', true);
        });
        return dialog;
      }

      if (name) {
        let w = 0;
        let h = 0;
        w = width ? width : util.win.screen.availWidth - 10;
        h = height ? height : util.win.screen.availHeight - 60;
        return util.win.open(
          src,
          name,
          `width=${w}px,height=${h}px,resizable=yes,status=yes,menubar=no,scrollbars=yes`
        );
      } else {
        return util.win.open(src);
      }
    },

    /**
     * @desc:关闭dialog页面
     * @author huangbo
     * @date 2024年9月7日
     **/
    winClose({
      url,
      appCode,
      id,
      index,
      refresh,
      menuRefresh,
      jumpMenu,
      callback
    }) {
      if (!appCode && !id) {
        console.error('参数错误，缺少appCode或者id');
        return;
      }
      if (index) {
        this.$set(this.dialogs, 'visible', false);
        this.dialogs.splice(dialog.index, 1);
      } else {
        let dialog = this.dialogs.find(
          (item) => item.url == url || item.appCode == appCode || item.id == id
        );

        if (dialog) {
          this.$set(dialog, 'visible', false);
          this.dialogs.splice(dialog.index, 1);
        }
      }
      if (callback) {
        const bus = this.bus || this.$root.Bus;
        if (bus) {
          // 主应用发送事件
          bus.$emit(callback, arguments[0]);
        }
      } else {
        refresh && this.$refs.main.handleRefresh(refresh);
        menuRefresh && this.$refs.main.handleRefresh(menuRefresh);
        jumpMenu &&
          (Array.isArray(jumpMenu)
            ? this.$refs.main.jumpMenu(...jumpMenu)
            : this.$refs.main.jumpMenu(jumpMenu));
      }
    },

    /**
     * @desc:postMessage消息处理
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleMessage(e) {
      const { method, args } = e.data;
      switch (method) {
        case 'reLogin':
          this.handleReLogin(args);
          break;
        case 'refresh':
          this.$refs.main.handleRefresh(args);
          break;
        case 'menuRefresh':
          this.$refs.main.handleRefresh(args);
          break;
        case 'jumpMenu':
          Array.isArray(args)
            ? this.$refs.main.jumpMenu(...args)
            : this.$refs.main.jumpMenu(args);
          break;
        case 'emit':
          const { origin, appCode, id, ...data } = args;
          let iframe = document.getElementById(appCode || id);
          iframe.contentWindow.postMessage(data, origin ? origin : '*');
          break;
        case 'openDialog': //打开弹窗
          this.winOpen(args);
          break;
        case 'closeDialog': //关闭弹窗
          this.winClose(args);
          break;
        case 'windowOpen': //打开弹窗
          this.winOpen(args);
          break;
        case 'windowClose': //关闭弹窗
          this.winClose(args);
          break;
      }
    },

    /**
     * @desc:dialog页面加载完成后通讯
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleIframeLoad(iframe, data) {
      iframe = iframe
        ? iframe
        : document.getElementById(data.appCode || data.id);
      const origin = new URL(iframe.src).origin;
      iframe.contentWindow.postMessage(
        { ...data, method: 'windowOpen' },
        origin
      );
    },

    /**
     * @desc:排除属性
     * @author huangbo
     * @date 2024年9月7日
     **/
    exclAttribute({ data, attrs }) {
      return util.exclAttribute({ data, attrs });
    },
    /**
     * @desc:关闭dialog
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleClosed(res, index) {
      // 在关闭弹窗后更新数量
      if (this.layoutType == 'simplicityTop') {
        this.$refs.main.getNums();
      }
      this.$nextTick(() => {
        this.dialogs.splice(index, 1);
      });
    },
    /**
     * @desc:主应用向子应用发送事件
     * @author huangbo
     * @date 2024年9月7日
     **/
    busEmit(event, args) {
      console.log('busEmit', event, args);
      WujieVue.bus.$emit(event, args);
      const iframes = document.getElementsByTagName('iframe');
      for (let i = 0; i < iframes.length; i++) {
        let src = iframes[i] ? iframes[i].src : null;
        let origin = util.win.location.origin;
        if (src && util.startWith(src, 'http') && src.indexOf(origin) === -1) {
          iframes[i] &&
            iframes[i].contentWindow.postMessage(
              { method: event, query: args },
              '*'
            );
        }
      }
      const bus = this.bus || this.$root.Bus;
      bus && bus.$emit(event, args);
      this.$emit('busEvent', event, args);
    }
  },

  beforeDestroy() {
    this.unbindEvent();
  }
};
</script>
