<template>
  <div class="dc-page-header-container">
    <div class="dc-trademark">
      <div class="dc-logo">
        <div class="dc-logo-svg">
          <img v-if="setting.logoImg" :src="setting.logoImg" />
        </div>
        <div class="dc-logo-text" v-if="setting.logoSlogan">{{ setting.logoSlogan }}</div>
      </div>
      <div class="dc-company" :style="{ 'margin-left': setting.nameOffset + 'px' }">
        <div class="dc-company-zh-cn" v-if="setting.companyZnName">{{ setting.companyZnName }}</div>
        <div class="dc-company-en-us" v-if="setting.companyEnName">{{ setting.companyEnName }}</div>
      </div>
    </div>
    <div class="dc-nav" :style="{ maxWidth: 'calc(100vw - ' + (enableMsgNotice ? '925px' : '805px') + ')' }" v-if="isHideWhenOnlyOne ? navTabsSetup.sysFuiAppRels.length > 1 : navTabsSetup.sysFuiAppRels.length > 0">
      <a-tabs type="card" v-model="navTabsSetup.activeAppId" @tabClick="navTabsSetup.nav($event)">
        <a-tab-pane v-for="item in navTabsSetup.fuiSysAppInfos" :key="item.appId" :tab="item.appName">{{ item.appName }}</a-tab-pane>
        <template #moreIcon>
          <menu-outlined :style="{ color: '#FFFFFF' }" />
        </template>
      </a-tabs>
    </div>
    <div class="dc-opts">
      <div class="dc-message-box" v-if="enableMsgNotice" @click="handleNoticeDrawer">
        <a-badge class="dc-badge" :count="noticeNumSetup.newMsgNum">
          <div class="dc-message-svg-box">
            <img class="dc-message-svg" :src="noticeNumSetup.messageSvg" />
          </div>
        </a-badge>
      </div>
      <div class="dc-role" :title="innerUserLabel" v-if="innerUserLabel && !hiddenUserLabel">{{ innerUserLabel }}</div>
      <div class="dc-user">
        <div class="dc-user-name">
          <a-dropdown :trigger="['click']" v-model:visible="userDropdownVisible" overlayClassName="dc-user-dm-box" :getPopupContainer="getPopupContainer">
            <a class="dc-dropdown-link" @click.prevent>
              <div class="dc-dropdown-link-text">{{ user ? user.userName : "匿名" }}</div>
              <DownOutlined />
            </a>
            <template #overlay>
              <a-menu>
                <template v-if="user">
                  <a-menu-item>
                    <a class="dc-dm-item" href="javascript:;" @click.stop="personalSetup.handlePersonalInfo">个人信息</a>
                  </a-menu-item>
                  <a-menu-item>
                    <a class="dc-dm-item" href="javascript:;" @click.stop="handleChangePassword">修改密码</a>
                  </a-menu-item>
                  <a-menu-item class="dc-dm-item-divider">
                    <a class="dc-dm-item" href="javascript:;" @click.stop="handleMyApp">导航设置</a>
                  </a-menu-item>
                  <a-sub-menu>
                    <template #title>
                      <a class="dc-dm-item" href="javascript:;">主题</a>
                    </template>
                    <a-menu-item>卡布里蓝</a-menu-item>
                    <a-menu-item>红宝石</a-menu-item>
                  </a-sub-menu>
                </template>
                <a-menu-item class="dc-dm-item-divider">
                  <a class="dc-dm-item" href="javascript:;" @click.stop="userDropdownVisible = false">帮助</a>
                </a-menu-item>
                <a-menu-item>
                  <a class="dc-dm-item" href="javascript:;" @click.stop="handleLogout">退出系统</a>
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </div>
      </div>
      <!-- 个人信息-->
      <dc-personal-info-modal v-if="!personalSetup.personalInfoVar.destroy" v-model:visible="personalSetup.personalInfoVar.visible" :personalHeaderExtendedInfo="personalHeaderExtendedInfo" @close="personalSetup.handleModalClose"></dc-personal-info-modal>
      <!-- 我的应用 -->
      <!--      <dc-my-app-modal v-if="!myAppVar.destroy" :visible.sync="myAppVar.visible" :sysAppInfos="allSysAppInfos" :sysFuiAppRels="sysFuiAppRels" @close="handleMyAppModalClose"></dc-my-app-modal>
      &lt;!&ndash; 消息提醒 &ndash;&gt;
      <dc-notice-drawer v-if="!noticeVar.destroy" :visible.sync="noticeVar.visible" @close="handleModalClose" @change="loadNoticeNum"> </dc-notice-drawer>
      &lt;!&ndash; 密码修改 &ndash;&gt;
      <dc-user-change-password-modal v-if="!changePasswordVar.destroy" :visible.sync="changePasswordVar.visible" @close="handleModalClose"></dc-user-change-password-modal>-->
    </div>
  </div>
</template>

<script lang="ts">
import { Options, Vue, setup } from "vue-class-component";
import { oauthService } from "../../services/oauth.service";
import { RestApi } from "../../model/domain/RestApi";
import { RestfulResponse } from "../../model/domain/RestfulResponse";
import { SysAppInfo } from "../../model/entity/SysAppInfo";
import { Code } from "../../constants/enum/code.enum";
import { apiService } from "../../services/api.service";
import sysAppInfoApi from "../../constants/api/sys-app-info.api";
import { routerService } from "../../services/router.service";
import { MESSAGE_SVG_XML } from "../../constants/encode-assets/svg";
import { SysFuiAppRel } from "../../model/entity/SysFuiAppRel";
import sysFuiAppRelApi from "../../constants/api/sys-fui-app-rel.api";
import { AppLink } from "../../constants/enum/app-link.enum";
import { SysUserInfo } from "../../model/entity/SysUserInfo";
import { userStore } from "../../stores/user.store";
import { PageHeaderSetting } from "../../model/domain/PageHeaderSetting";
import sysMsgApi from "../../constants/api/sys-msg.api";
import { ModalVar } from "../../model/domain/ModalVar";
import { computed, getCurrentInstance, onMounted, reactive, ref } from "vue";
import { onUnmounted } from "@vue/runtime-core";
import PersonalInfoModal from "./PersonalInfoModal.vue";
import { message } from "ant-design-vue";
import { Prop } from "vue-property-decorator";

interface Props {
  setting: PageHeaderSetting; // 配置项
  dynamic: boolean; // 是否动态加载系统信息
  staticAllSysAppInfos: SysAppInfo[]; // 配置项
  enableMsgNotice: boolean; // 启用消息通知
  userLabel: string; // 自定义用户标签
  hiddenUserLabel: boolean; // 隐藏角色名称
  isHideWhenOnlyOne: boolean; // 只有一个时隐藏
  personalHeaderExtendedInfo: string; // 个人信息头部扩展信息
}

@Options({
  name: "PageHeader",
  components: {
    "dc-personal-info-modal": PersonalInfoModal,
  },
})
export default class PageHeader extends Vue {
  @Prop({ default: new PageHeaderSetting() }) readonly setting!: PageHeaderSetting; // 配置项
  @Prop({ default: false }) readonly dynamic!: boolean; // 是否动态加载系统信息
  @Prop({ default: [] }) readonly staticAllSysAppInfos!: SysAppInfo[]; // 静态全量应用信息
  @Prop({ default: false }) readonly enableMsgNotice!: boolean; // 启用消息通知
  @Prop({ default: null }) readonly userLabel!: string; // 自定义用户标签
  @Prop({ default: false }) readonly hiddenUserLabel!: boolean; // 隐藏角色名称
  @Prop({ default: false }) readonly isHideWhenOnlyOne!: boolean; // 只有一个时隐藏
  @Prop({ default: "" }) readonly personalHeaderExtendedInfo!: string; // 个人信息头部扩展信息

  noticeVar: ModalVar = { visible: false, destroy: true }; // 消息通知模态框变量
  myAppVar: ModalVar = { visible: false, destroy: true }; // 我的应用弹窗模态框变量
  changePasswordVar: ModalVar = { visible: false, destroy: true }; // 修改密码弹窗模态框变量

  static readonly NOTICE_INTERVAL: number = 3 * 1000 * 60; // 查询通知间隔

  userDropdownVisible = false; // 用户下拉框展示
  observationRefreshMark: any = new Date().getTime(); // 观察刷新标志

  getPopupContainer = (triggerNode: any) => {
    return triggerNode;
  }; // 下拉面板位置

  // 用户信息
  get user(): SysUserInfo | undefined {
    this.observationRefreshMark = userStore.refreshMark;
    return userStore.user;
  }

  // 用户标签
  get innerUserLabel(): string {
    if (this.userLabel != null) {
      return this.userLabel;
    } else {
      const user = this.user;
      return user && user.sysRoleInfos && user.sysRoleInfos.length > 0 ? user.sysRoleInfos[0].roleName : "";
    }
  }

  /**
   * @description: ----------------------------顶部导航-功能代码聚合-START----------------------------
   * @author ChenRui
   * @date 2022/5/26 20:43
   */
  navTabsSetup = setup(() => {
    const { dynamic } = this.$props as Props;

    const vueIns = getCurrentInstance()!.appContext.config.globalProperties;
    // 变量部分
    const activeAppId = ref<string>(""); // 当前激活导航
    const allSysAppInfos = ref<SysAppInfo[]>([]); // 全部导航列表
    const sysFuiAppRels = ref<SysFuiAppRel[]>([]); // 常用导航关联列表

    // 常用导航列表
    const fuiSysAppInfos = computed<SysAppInfo[]>(() => {
      return sysFuiAppRels.value?.map((item) => allSysAppInfos.value.find((it) => it.appId === item.appId)!)?.filter((item) => item != null) || [];
    });

    onMounted(() => {
      if (dynamic) {
        loadSysInfo();
      } else {
        onStaticAllSysAppInfosChange(this.staticAllSysAppInfos);
      }
    });

    /**
     * @description: 加载常用系统及所有系统
     * @author ChenRui
     * @date 2021/3/31 17:13
     */
    const loadSysInfo = (): Promise<any> => {
      return Promise.all([loadAllSysInfo(), loadFuiAppRels()]).then(([resAll, resCom]: any[]) => {
        if (resAll.code === Code.SUCCESS.code && resCom.code === Code.SUCCESS.code) {
          toggleActiveNavMenus();
        } else {
          message.error({ duration: 1, content: "系统错误，请联系管理员" });
        }
      });
    };

    /**
     * @description: 加载所有应用
     * @author ChenRui
     * @date 2021/8/10 15:49
     */
    const loadAllSysInfo = (): Promise<RestfulResponse> => {
      const restApi: RestApi = new RestApi(sysAppInfoApi.queryAuthorizedApp);
      restApi.url = vueIns.$dc.baseApi + sysAppInfoApi.queryAuthorizedApp.url;
      return apiService.general(restApi).then((res: RestfulResponse) => {
        if (res.code === Code.SUCCESS.code) {
          allSysAppInfos.value = res.data || [];
        }
        return res;
      });
    };

    /**
     * @description: 加载常用应用
     * @author ChenRui
     * @date 2021/8/10 15:56
     */
    const loadFuiAppRels = (): Promise<RestfulResponse> => {
      const restApi: RestApi = new RestApi(sysFuiAppRelApi.queryByUserId);
      restApi.url = vueIns.$dc.baseApi + sysFuiAppRelApi.queryByUserId.url;

      const query = {
        userId: vueIns.$userStore.user?.userId,
      };
      return apiService.general(restApi, query).then((res: RestfulResponse) => {
        if (res.code === Code.SUCCESS.code) {
          sysFuiAppRels.value = res.data || [];
        }
        return res;
      });
    };

    /**
     * @description: 激活当前系统对应的选项卡
     * @author ChenRui
     * @date 2020/12/18 22:24
     */
    const toggleActiveNavMenus = (): void => {
      const pathName: string = window.document.location.pathname;
      if (pathName && pathName.length > 0) {
        const projectName: string = pathName.substring(1, pathName.substr(1).indexOf("/") + 1);
        if (projectName && projectName.length > 0) {
          let systemNav: SysAppInfo | undefined = fuiSysAppInfos.value.find((item) => item.mountName === projectName);
          if (systemNav == null && allSysAppInfos.value != null && allSysAppInfos.value.length > 0) {
            systemNav = allSysAppInfos.value.find((item) => item.mountName === projectName);
            if (systemNav) {
              sysFuiAppRels.value.push(new SysFuiAppRel({ appId: systemNav.appId }));
            }
          }
          if (systemNav) {
            activeAppId.value = systemNav?.appId || "";
          }
        }
      }
    };

    /**
     * @description: 静态数据变更处理
     * @author ChenRui
     * @date 2021/9/15 16:08
     */
    const onStaticAllSysAppInfosChange = (sysAppInfos: SysAppInfo[]) => {
      if (!this.dynamic) {
        allSysAppInfos.value = this.staticAllSysAppInfos || [];
        sysFuiAppRels.value = [];
        allSysAppInfos.value.forEach((item) => {
          sysFuiAppRels.value.push(
            new SysFuiAppRel({
              appId: item.appId,
            })
          );
        });
      }
    };

    /**
     * @description: 跨应用导航
     * @author ChenRui
     * @date 2021/8/10 16:00
     */
    const nav = (event: any): void => {
      const sysAppInfo: SysAppInfo | undefined = allSysAppInfos.value.find((item) => item.appId === event);
      if (sysAppInfo && sysAppInfo.appUrl) {
        if (sysAppInfo.isLink === AppLink.OUT.code) {
          window.open(sysAppInfo.appUrl, "_blank");
        } else {
          const appUrl: string = sysAppInfo.appUrl.toLowerCase();
          const regex = /(http|https):\/\/([\w.]+\/?)\S*/;
          if (regex.test(appUrl)) {
            routerService.push(sysAppInfo.appUrl);
          } else {
            const url = window.location.protocol + "//" + location.host + sysAppInfo.appUrl;
            routerService.push(url);
          }
        }
      }
    };
    return { activeAppId, fuiSysAppInfos, allSysAppInfos, sysFuiAppRels, loadFuiAppRels, nav };
  });
  /** ----------------------------顶部导航-功能代码聚合-END---------------------------- **/

  /**
   * @description: ----------------------------消息数-功能代码聚合-START----------------------------
   * @author ChenRui
   * @date 2022/5/26 21:27
   */
  noticeNumSetup = setup(() => {
    const { enableMsgNotice } = this.$props as Props;

    const messageSvg: any = MESSAGE_SVG_XML; // 消息图标
    const vueIns = getCurrentInstance()!.appContext.config.globalProperties;

    let noticeNumInterval: any = undefined; // 定时任务标记
    const newMsgNum = ref<number>(0); // 消息数量

    onMounted(() => {
      if (enableMsgNotice) {
        initNoticeNumScheduled();
      }
    });

    onUnmounted(() => {
      if (noticeNumInterval) {
        clearInterval(noticeNumInterval);
      }
    });

    /**
     * @Description: 定时调用通知总数查询
     * @author LiuBo
     * @date 2021/11/12
     * @time 11:46
     */
    const initNoticeNumScheduled = (): void => {
      loadNoticeNum();
      noticeNumInterval = setInterval(() => {
        loadNoticeNum();
      }, PageHeader.NOTICE_INTERVAL);
    };

    /**
     * @Description: 调用查询任务总数接口
     * @author SunJQi
     * @date 2021/11/12
     * @time 11:46
     */
    const loadNoticeNum = (): void => {
      const restApi: RestApi = new RestApi(sysMsgApi.querySysMsgCount);
      restApi.url = vueIns.$dc.baseApi + sysMsgApi.querySysMsgCount.url;
      apiService.general(restApi, undefined).then((res: RestfulResponse) => {
        if (res.code === Code.SUCCESS.code) {
          newMsgNum.value = res.data;
        }
      });
    };

    return { messageSvg, newMsgNum };
  });
  /** ----------------------------消息数-功能代码聚合-END---------------------------- **/

  /**
   * @description: ----------------------------个人信息弹窗-功能代码聚合-START----------------------------
   * @author ChenRui
   * @date 2022/5/26 21:27
   */
  personalSetup = setup(() => {
    const personalInfoVar: ModalVar = reactive({ visible: false, destroy: true }); // 个人信息框模态框变量

    /**
     * @description: 个人信息
     * @author ChenRui
     * @date 2022/2/12 17:56
     */
    const handlePersonalInfo = (): void => {
      this.userDropdownVisible = false;
      personalInfoVar.destroy = false;
      personalInfoVar.visible = true;
    };

    /**
     * @description: 模态框关闭
     * @author Zhang Qishan
     * @date 2021/8/28 2:36
     */
    const handleModalClose = (response: RestfulResponse): void => {
      setTimeout(() => {
        personalInfoVar.destroy = true;
      }, 300);
    };
    return { personalInfoVar, handlePersonalInfo, handleModalClose };
  });
  /** ----------------------------消息数-功能代码聚合-END---------------------------- **/

  /**
   * @description: 无权访问
   * @author ChenRui
   * @date 2021/4/20 11:30
   */
  noAccessHandler(event: any): void {
    this.$emit("no-access", event);
  }

  /**
   * @description: 我的应用
   * @author ChenRui
   * @date 2021/8/16 10:48
   */
  handleMyApp(): void {
    this.myAppVar.destroy = false;
    this.myAppVar.visible = true;
  }

  /**
   * @description: 消息通知
   * @author ChenRui
   * @date 2022/2/12 17:57
   */
  handleNoticeDrawer(): void {
    this.noticeVar.destroy = false;
    this.noticeVar.visible = true;
  }

  /**
   * @description: 修改密码
   * @author ChenRui
   * @date 2021/10/11 17:42
   */
  handleChangePassword(): void {
    this.changePasswordVar.destroy = false;
    this.changePasswordVar.visible = true;
  }

  /**
   * @description: 关闭我的应用模态框
   * @author ChenRui
   * @date 2022/2/12 15:55
   */
  handleMyAppModalClose(response: RestfulResponse): void {
    setTimeout(() => {
      this.myAppVar.destroy = true;
    }, 500);
    if (response && response.code === Code.SUCCESS.code) {
      this.navTabsSetup.loadFuiAppRels().then();
    }
  }

  /**
   * @description: 用户登出
   * @author ChenRui
   * @date 2021/8/10 15:54
   */
  handleLogout(): void {
    oauthService.logOut().then((res: RestfulResponse) => {
      this.$emit("logout", res);
    });
    this.userDropdownVisible = false;
  }
}
</script>

<style scoped lang="scss">
.dc-page-header-container {
  display: flex;
  align-items: center;
  background: linear-gradient(100.867407580473deg, rgba(2, 86, 155, 1) 0%, rgba(19, 124, 221, 1) 102%);
  height: 50px;
  padding: 0 10px;
  font-family: "lucida grande", "lucida sans unicode", lucida, helvetica, "Hiragino Sans GB", "MicrosoftYaHei", "WenQuanYi Micro Hei", sans-serif !important;
  .dc-trademark {
    display: flex;
    align-items: center;
    width: 235px;
    padding-top: 3px;
    .dc-logo {
      display: flex;
      flex-direction: column;
      .dc-logo-svg {
        display: flex;
        justify-content: center;
        img {
          width: 27px;
          height: 22px;
          display: block;
        }
      }
      .dc-logo-text {
        font-weight: 600;
        font-size: 12px;
        width: 100%;
        text-align: center;
        transform: scale(0.8);
        color: #ffffff;
      }
    }
    .dc-company {
      color: #ffffff;
      .dc-company-zh-cn {
        letter-spacing: 4px;
        text-align: center;
        font-size: 12px;
        font-weight: 600;
        margin-bottom: -3px;
        transform: scale(0.95);
        padding-left: 3px;
      }
      .dc-company-en-us {
        font-size: 12px;
        font-weight: 600;
        transform: scale(0.8);
      }
    }
  }
  .dc-nav {
    flex-grow: 1;
    height: 100%;
    :deep(.ant-tabs) {
      height: 50px;
      .ant-tabs-nav {
        height: 100%;
        margin-bottom: 0;
        border-bottom: 0;
        &::before {
          display: none;
        }
        .ant-tabs-nav-list {
          transform: none;
          .ant-tabs-tab {
            border: 0;
            background-color: initial;
            .ant-tabs-tab-btn {
              font-family: "PingFangSC-Regular", "苹方-简";
              font-size: 14px;
              color: #ffffff;
            }
            &:hover {
              background-color: rgba(255, 255, 255, 0.2);
            }
            &.ant-tabs-tab-active {
              font-weight: bold;
              background-color: rgba(255, 255, 255, 0.2);
              border-bottom: 2px solid #ffffff;
            }
          }
        }
        .ant-tabs-nav-operations {
        }
      }
      .ant-tabs-content {
        display: none;
      }
    }
  }
  .dc-opts {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    margin-left: auto;
    padding: 0 15px;
    .dc-message-box {
      margin: 0 30px 0 20px;
      .dc-badge {
        display: block;
        cursor: pointer;
        .dc-message-svg-box {
          width: 25px;
          height: 25px;
          border-radius: 12.5px;
          background-color: #5e94d4;
          display: flex;
          align-items: center;
          justify-content: center;
          .dc-message-svg {
            width: 22px;
            height: 22px;
            color: white;
          }
        }
        :deep {
          .ant-badge-count {
            right: -1px;
            top: -3px;
            transform: scale(0.5);
          }
        }
      }
    }
    .dc-role {
      text-align: center;
      margin-right: 5px;
      color: white;
      max-width: 90px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .dc-user {
      display: flex;
      align-items: center;
      margin: 0 10px;
      .dc-user-name {
        font-family: "MicrosoftYaHei", "Microsoft YaHei";
        text-align: right;
        .dc-dropdown-link {
          color: white;
          display: flex;
          align-items: center;
          .dc-dropdown-link-text {
            max-width: 55px;
            white-space: nowrap;
            text-overflow: ellipsis;
            overflow: hidden;
            word-break: break-all;
          }
          :deep {
            .anticon {
              display: block;
              margin-left: 5px;
              svg {
                transform: scale(1.2);
              }
            }
            .ant-dropdown {
              position: absolute !important;
              width: initial !important;
            }
          }
        }
        :deep(.dc-user-dm-box) {
          border-radius: 4px;
          .ant-dropdown-content {
            .ant-dropdown-menu-item {
              width: 160px;
              .ant-dropdown-menu-title-content {
                display: flex;
                align-items: center;
                height: 34px;
                padding: 0 10px;
                .anticon {
                  margin-right: 8px;
                }
                .dc-dm-item {
                  display: block;
                  font-size: 13px;
                  color: #333333;
                }
              }
              &:hover {
                background-color: initial;
                .ant-dropdown-menu-title-content {
                  background-color: rgba(236, 242, 254, 1);
                  .dc-dm-item {
                    color: rgb(64, 148, 243);
                  }
                }
              }
            }
            .ant-dropdown-menu-submenu {
              .ant-dropdown-menu-submenu-title {
                padding-right: 12px;
                .ant-dropdown-menu-title-content {
                  padding: 0 10px;
                  height: 34px;
                  display: flex;
                  align-items: center;
                  font-size: 13px;
                }
                .ant-dropdown-menu-submenu-arrow {
                  top: 17px;
                  right: 20px;
                  display: block;
                }
                &:hover {
                  background-color: #ffffff;
                  .ant-dropdown-menu-title-content {
                    color: rgb(64, 148, 243);
                    background-color: rgba(236, 242, 254, 1);
                  }
                }
              }
            }
            .dc-dm-item-divider:before {
              content: "";
              position: absolute;
              left: 10px;
              top: 0;
              right: auto;
              height: 2px;
              transform: scaleY(0.7);
              width: calc(100% - 20px);
              background-color: #e8e8e8;
            }
          }
        }
      }
    }
  }
}
</style>
