<template>
  <div class="my-container">
    <mark-header @should-reload-history="shouldReloadFunc" />
    <div class="tw-flex tw-gap-1">
      <mark-history :should-reload="shouldReloadHistory" />
      <mark-body @error="removeBrokenTask" />
      <mark-board-track
        v-if="showMarkBoardTrack"
        @submit="saveTaskToServer"
        @allZeroSubmit="allZeroSubmit"
      />
      <mark-board-key-board
        v-if="showMarkBoardKeyBoard"
        @submit="saveTaskToServer"
        @allZeroSubmit="allZeroSubmit"
      />
      <mark-board-mouse
        v-if="showMarkBoardMouse"
        @submit="saveTaskToServer"
        @allZeroSubmit="allZeroSubmit"
      />
    </div>
  </div>
  <AnswerModal />
  <PaperModal />
  <MinimapModal />

  <AllPaperModal />
  <SheetViewModal />
  <SpecialTagModal />
</template>

<script lang="ts">
import { computed, defineComponent, onMounted, ref, watch } from "vue";
import {
  clearMarkTask,
  getGroup,
  getSetting,
  getStatus,
  getTask,
  saveTask,
  updateUISetting,
} from "@/api/markPage";
import {
  findCurrentTaskMarkResult,
  removeCurrentMarkResult,
  removeOldPreviousMarkResult,
  store,
} from "./store";
import MarkHeader from "./MarkHeader.vue";
import MarkBody from "./MarkBody.vue";
import { useTimers } from "@/setups/useTimers";
import MarkHistory from "./MarkHistory.vue";
import MarkBoardTrack from "./MarkBoardTrack.vue";
import { ModeEnum, Setting } from "@/types";
import MarkBoardKeyBoard from "./MarkBoardKeyBoard.vue";
import MarkBoardMouse from "./MarkBoardMouse.vue";
import { isEmpty, isNumber } from "lodash";
import { message } from "ant-design-vue";
import AnswerModal from "./AnswerModal.vue";
import PaperModal from "./PaperModal.vue";
import MinimapModal from "./MinimapModal.vue";
import AllPaperModal from "./AllPaperModal.vue";
import SheetViewModal from "./SheetViewModal.vue";
import SpecialTagModal from "./SpecialTagModal.vue";

export default defineComponent({
  name: "Mark",
  components: {
    MarkHeader,
    MarkBody,
    MarkHistory,
    MarkBoardTrack,
    MarkBoardKeyBoard,
    MarkBoardMouse,
    AnswerModal,
    PaperModal,
    MinimapModal,
    AllPaperModal,
    SheetViewModal,
    SpecialTagModal,
  },
  setup: () => {
    const { addInterval } = useTimers();

    async function updateMarkTask() {
      const settingRes = await clearMarkTask();
    }

    async function updateSetting() {
      const settingRes = await getSetting();
      // 初次使用时，重置并初始化uisetting
      if (isEmpty(settingRes.data.uiSetting)) {
        settingRes.data.uiSetting = {
          "answer.paper.scale": 1,
          "score.board.collapse": false,
          "normal.mode": "keyboard",
        } as Setting["uiSetting"];
      }
      store.setting = settingRes.data;
    }
    async function updateStatus() {
      const res = await getStatus();
      store.status = res.data;
    }
    async function updateGroups() {
      const res = await getGroup();
      store.groups = res.data;
    }
    async function updateTask() {
      const res = await getTask();
      if (res.data.libraryId) {
        store.tasks.push(res.data);
        if (!store.historyOpen) {
          // 回评中，不能替换task
          // TODO: 疑似替换多次引起重新渲染
          if (store.currentTask?.studentId !== store.tasks[0].studentId)
            store.currentTask = store.tasks[0];
        }

        // 如果是评完后，再取到的任务，则此时要更新一下status
        if (store.status.totalCount - store.status.markedCount === 0) {
          await updateStatus();
        }
      } else {
        store.message = res.data.message;
      }
    }

    // 5秒更新一次tasks
    addInterval(() => {
      // console.log("get task", store.tasks);
      if (store.tasks.length < (store.setting.prefetchCount ?? 3)) {
        // 回看打开时，停止取任务
        if (!store.historyOpen) updateTask();
      }
    }, 5 * 1000);

    // TODO: 后续改掉，不需要
    addInterval(() => {
      updateStatus();
    }, 5 * 60 * 1000);

    onMounted(async () => {
      await updateMarkTask();
      await updateSetting();
      await updateStatus();
      await updateGroups();
      await updateTask();
    });

    watch(
      () => [store.setting.uiSetting, store.setting.mode],
      () => {
        updateUISetting(store.setting.mode, store.setting.uiSetting);
      },
      { deep: true }
    );

    // 切换currentTask的同时，切换currentMarkResult
    watch(
      () => store.currentTask,
      () => {
        // 回评切换任务，先删除之前回评任务的markResult
        if (store.historyOpen) {
          removeOldPreviousMarkResult();
        }
        store.currentMarkResult = findCurrentTaskMarkResult();

        // 重置当前选择的quesiton和score
        store.currentQuestion = undefined;
        store.currentScore = undefined;
      }
    );

    const showMarkBoardTrack = computed(() => {
      return store.setting.mode === ModeEnum.TRACK;
    });

    const showMarkBoardKeyBoard = computed(() => {
      return (
        store.setting.mode === ModeEnum.COMMON &&
        store.setting.uiSetting["normal.mode"] === "keyboard"
      );
    });

    const showMarkBoardMouse = computed(() => {
      return (
        store.setting.mode === ModeEnum.COMMON &&
        store.setting.uiSetting["normal.mode"] === "mouse"
      );
    });

    const removeBrokenTask = () => {
      removeCurrentMarkResult();
      store.currentTask = undefined;

      if (!store.historyOpen) {
        store.tasks.shift();
      } else {
        store.currentTask = store.historyTasks[0];
      }
    };

    const shouldReloadHistory = ref(0);

    const shouldReloadFunc = () => {
      shouldReloadHistory.value = Date.now();
    };

    const allZeroSubmit = async () => {
      const markResult = findCurrentTaskMarkResult();
      if (!markResult) return;

      markResult.markerScore = 0;
      const ss = new Array(store.currentTask?.questionList.length);
      markResult.scoreList = ss.fill(0);
      markResult.trackList = [];

      await saveTaskToServer();
    };
    const saveTaskToServer = async () => {
      const markResult = findCurrentTaskMarkResult();
      if (!markResult) return;

      if (
        markResult.scoreList.length !==
          store.currentTask?.questionList.length ||
        !markResult.scoreList.every((s) => isNumber(s))
      ) {
        console.error("markResult格式不正确，缺少分数");
        return;
      }

      if (
        markResult.scoreList.length !==
          store.currentTask?.questionList.length &&
        markResult.scoreList.every((s) => isNumber(s))
      ) {
        // 轨迹回评普通打分时，有分数无轨迹，导致markResult的scoreList计算不准确
        if (store.currentTask?.questionList.every((q) => isNumber(q.score))) {
          let question;
          for (const q of store.currentTask?.questionList) {
            const valid = markResult.trackList.some(
              (t) =>
                q.mainNumber === t.mainNumber && q.subNumber === t.subNumber
            );
            if (!valid) {
              question = q;
              break;
            }
          }
          if (question) {
            message.error({
              content: `${question.mainNumber}-${question.subNumber} 没有轨迹。`,
              duration: 5,
            });
          } else {
            message.error({ content: "少有人见过的错误" });
          }
        } else {
          message.error({ content: "还有题目没有评分。", duration: 5 });
        }
        return;
      }
      if (store.setting.mode !== ModeEnum.TRACK) {
        markResult.trackList = [];
      }
      if (store.setting.forceSpecialTag) {
        if (
          markResult.trackList.length === 0 &&
          markResult.specialTagList.length === 0
        ) {
          message.error({
            content: "强制标记已开启，请至少使用一个标记。",
            duration: 5,
          });
          return;
        }
      }
      console.log("save task to server");
      const mkey = "save_task_key";
      message.loading({ content: "保存评卷任务...", key: mkey });
      const res = (await saveTask()) as any;
      updateStatus();
      if (res.data.success && store.currentTask) {
        message.success({ content: "保存成功", key: mkey, duration: 2 });
        if (!store.historyOpen) {
          removeCurrentMarkResult();
          store.currentTask = undefined;
          store.tasks.shift();
        } else {
          shouldReloadHistory.value = Date.now();
        }
      } else {
        console.log(res.data.message);
        message.error({ content: res.data.message, key: mkey, duration: 10 });
      }
    };

    return {
      store,
      updateTask,
      allZeroSubmit,
      saveTaskToServer,
      showMarkBoardTrack,
      showMarkBoardKeyBoard,
      showMarkBoardMouse,
      shouldReloadHistory,
      shouldReloadFunc,
      removeBrokenTask,
    };
  },
});
</script>

<style scoped>
.my-container {
  width: 100%;
}
a {
  color: #42b983;
}

label {
  margin: 0 0.5em;
  font-weight: bold;
}

code {
  background-color: #eee;
  padding: 2px 4px;
  border-radius: 4px;
  color: #304455;
}
</style>
