<template>
  <div class="remain-time">剩余时间 {{ remainTimeFormatted }}</div>
</template>

<script>
import moment from "moment";
import { createNamespacedHelpers } from "vuex";
const { mapMutations } = createNamespacedHelpers("examingHomeModule");

export default {
  name: "RemainTime",
  data() {
    return {
      remainTime: null,
    };
  },
  computed: {
    remainTimeFormatted: function() {
      return moment.utc(this.remainTime).format("HH:mm:ss");
    },
  },
  watch: {
    remainTime(val) {
      if (val !== null && val === 0) {
        this.setShouldSubmitPaper();
      }
      this.updateRemainTime(val);
    },
  },
  async mounted() {
    this.heartbeatErrorNum = 0;
    this.getRemainTimeFromServer();
    this.heartbeatInterval = setInterval(() => {
      this.getRemainTimeFromServer();
    }, 60 * 1000);
    this.remainTimeInterval = setInterval(() => {
      if (this.remainTime > 0) {
        this.remainTime = this.remainTime - 1000;
      }
    }, 1000);
  },
  beforeDestroy() {
    this.clearIntervals();
  },
  methods: {
    ...mapMutations(["setShouldSubmitPaper", "updateRemainTime"]),
    async getRemainTimeFromServer() {
      if (this.$route.name !== "OnlineExamingHome") {
        // 非考试页，不继续发心跳。可能退出后再进，导致心跳多发一次。可能会话已过期。
        return;
      }
      try {
        const res = await this.$http.get(
          "/api/ecs_oe_student/examControl/examHeartbeat"
        );
        if (/\d+/.test(res.data)) {
          if (res.data <= 0) {
            this.setShouldSubmitPaper();
          }
          if (this.remainTime === null) {
            // 仅当剩余考试时间没有被初始化才使用服务器时间。否则使用本机时间。
            this.remainTime = res.data;
          }
          this.heartbeatErrorNum = 0;
        } else {
          this.$Message.error({
            content: "服务器返回的心跳结果不是数字",
            duration: 15,
            closable: true,
          });
        }
      } catch (error) {
        if (
          error.response &&
          error.response.data &&
          error.response.data.desc &&
          error.response.data.desc.includes("会话已过期,请离开考试")
        ) {
          window._hmt.push([
            "_trackEvent",
            "正在考试页面",
            "心跳",
            "失败-会话过期",
          ]);
          this.serverLog(
            "debug/S-008002",
            `心跳失败-会话过期 => 考试剩余时间：${this.remainTime / 1000}`
          );
        } else {
          window._hmt.push(["_trackEvent", "正在考试页面", "心跳", "失败"]);
          this.serverLog(
            "debug/S-008003",
            `心跳失败 => 考试剩余时间：${this.remainTime / 1000} => ${error}`
          );
        }
        this.heartbeatErrorNum++;
        if (this.heartbeatErrorNum >= 10) {
          // 心跳异常10次则退出考试
          clearInterval(this.heartbeatInterval);
          clearInterval(this.remainTimeInterval);
          window._hmt.push([
            "_trackEvent",
            "正在考试页面",
            "心跳",
            "失败10次-退出",
          ]);
          const redirectUrl = sessionStorage.getItem("redirectUrl");
          this.$Modal.error({
            title: "网络连接异常",
            content: "退出考试",
            onOk: () => {
              if (redirectUrl) {
                window.location = redirectUrl;
              } else {
                this.$router.push(
                  "/login/" +
                    localStorage.getItem("domain") +
                    "?LogoutReason=心跳失败10次-退出"
                );
              }
            },
          });
          return;
        }
        this.retryHeartbeatTimeout = setTimeout(
          () => this.getRemainTimeFromServer(),
          10 * 1000
        );
      }
    },
    clearIntervals() {
      clearInterval(this.heartbeatInterval);
      clearInterval(this.remainTimeInterval);
      clearTimeout(this.retryHeartbeatTimeout);
    },
  },
};
</script>
