<template>
  <div class="mark">
    <div class="mark-header">
      <div class="mark-header-part">
        <template v-if="store.currentTask">
          <div class="header-noun">
            <span>课程名称：</span>
            <span>
              {{ store.currentTask.courseName }}（{{
                store.currentTask.courseCode
              }}）</span
            >
          </div>
          <div class="header-noun">
            <span>试卷编号：</span>
            <span>{{ store.currentTask.paperNumber }}</span>
          </div>
          <div class="header-noun">
            <span>姓名：</span>
            <span>{{ store.currentTask.studentName }}</span>
          </div>
          <div class="header-noun">
            <span>学号：</span>
            <span>{{ store.currentTask?.studentCode }}</span>
          </div>
          <div v-if="studentIds.length > 1" class="header-noun">
            <span>进度：</span>
            <span> {{ currentIndex + 1 }}/{{ studentIds.length }} </span>
          </div>
        </template>
      </div>
      <div class="mark-header-part">
        <template v-if="isMultiStudent">
          <div class="header-text-btn" @click="getPreviousStudent">
            <img
              class="header-icon"
              src="@/assets/icons/icon-left-arrows.svg"
            />上一份
          </div>
          <div class="header-text-btn" @click="getNextStudent">
            下一份<img
              class="header-icon"
              src="@/assets/icons/icon-right-arrows.svg"
            />
          </div>
        </template>
        <div class="header-text-btn header-logout" @click="logout">
          <img class="header-icon" src="@/assets/icons/icon-return.svg" />返回
        </div>
        <a-tooltip v-if="store.isTrackMode" placement="bottomRight">
          <template #title>弹出给分板</template>
          <div
            :class="[
              'header-menu',
              { 'is-toggled': store.isScoreBoardVisible && store.currentTask },
            ]"
            @click="store.toggleScoreBoard"
          >
            <img src="@/assets/icons/icon-right-menu.svg" class="header-icon" />
          </div>
        </a-tooltip>
        <div v-else class="header-menu is-toggled">
          <img src="@/assets/icons/icon-right-menu.svg" class="header-icon" />
        </div>
      </div>
    </div>
    <mark-tool
      :actions="[
        'allPage',
        'minimap',
        'answer',
        'sizeScale',
        'shortCut',
        'specialTag',
        'imgScale',
      ]"
      @allZeroSubmit="allZeroSubmit"
    />
    <div class="mark-main">
      <mark-body @error="removeBrokenTask" />
      <mark-board-track
        v-if="store.isTrackMode"
        isCheckAnswer
        @submit="saveTaskToServer"
      />
      <mark-board-key-board
        v-if="store.shouldShowMarkBoardKeyBoard"
        @submit="saveTaskToServer"
        @allZeroSubmit="allZeroSubmit"
      />
      <mark-board-mouse
        v-if="store.shouldShowMarkBoardMouse"
        @submit="saveTaskToServer"
        @allZeroSubmit="allZeroSubmit"
      />
    </div>
  </div>
  <AnswerModal />
  <MinimapModal />
  <AllPaperModal />
  <SheetViewModal />
  <SpecialTagModal />
  <ShortCutModal />
  <MarkBoardTrackDialog
    v-if="store.isTrackMode"
    isCheckAnswer
    @submit="saveTaskToServer"
    @allZeroSubmit="allZeroSubmit"
  />
</template>

<script setup lang="ts">
import { onMounted, watch, h } from "vue";
import {
  studentSubjectiveConfirmData,
  saveStudentSubjectiveConfirmData,
} from "@/api/checkPage";
import { doLogout, updateUISetting, getSetting } from "@/api/markPage";
import { store } from "@/store/store";
import MarkTool from "../mark/MarkTool.vue";
import MarkBody from "./MarkBody.vue";
import MarkBoardTrack from "../mark/MarkBoardTrack.vue";
import type { Question } from "@/types";
import MarkBoardKeyBoard from "../mark/MarkBoardKeyBoard.vue";
import MarkBoardMouse from "../mark/MarkBoardMouse.vue";
import { debounce, isEmpty, isNumber } from "lodash-es";
import { message } from "ant-design-vue";
import AnswerModal from "../mark/AnswerModal.vue";
import MinimapModal from "../mark/MinimapModal.vue";
import AllPaperModal from "../mark/AllPaperModal.vue";
import SheetViewModal from "../mark/SheetViewModal.vue";
import SpecialTagModal from "../mark/SpecialTagModal.vue";
import ShortCutModal from "../mark/ShortCutModal.vue";
import MarkBoardTrackDialog from "../mark/MarkBoardTrackDialog.vue";
import vls from "@/utils/storage";

const { examId, paperNumber, studentIds } = vls.get("check-students", {
  examId: "",
  paperNumber: "",
  studentIds: [],
});
vls.set("mark", {
  examId,
  paperNumber,
  groupNumber: 1,
});

let currentStudentId = $ref("");
const currentIndex = $computed(() => studentIds.indexOf(currentStudentId));
const isFirst = $computed(() => currentIndex === 0);
const isLast = $computed(() => currentIndex === studentIds.length - 1);
const isMultiStudent = $computed(() => studentIds.length > 1);

onMounted(async () => {
  if (studentIds.length === 0) {
    void message.info("没有需要处理的考生，请返回。");
    return;
  }
  await updateSetting();
  await getNextStudent();
});

const logout = () => {
  doLogout();
};

async function getNextStudent() {
  if (isLast) {
    void message.warning("已经是最后一份！");
    return;
  }
  await updateTask(studentIds[currentIndex + 1]);
}

async function getPreviousStudent() {
  if (isFirst) {
    void message.warning("已经是第一份！");
    return;
  }
  await updateTask(studentIds[currentIndex - 1]);
}

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",
      "score.fontSize.scale": 1,
      "paper.modal": false,
      "answer.modal": false,
      "minimap.modal": false,
      "specialTag.modal": false,
      "shortCut.modal": false,
    };
  } else {
    settingRes.data.uiSetting = JSON.parse(settingRes.data.uiSetting);
  }
  settingRes.data.doubleTrack = true;
  store.setting = settingRes.data;
}

let taskQuestionInfo = {};
function updateTaskGroupInfo() {
  taskQuestionInfo = {};
  if (!store.currentTask) return;

  store.currentTask.questionList.forEach((question) => {
    const qno = `${question.mainNumber * 1000}${question.subNumber}`;
    taskQuestionInfo[qno] = {
      groupNumber: question.groupNumber,
      score: question.score,
    };
  });
}
async function updateTask(studentId) {
  const res = await studentSubjectiveConfirmData(studentId);
  if (!res.data) {
    store.message = res.message || "数据错误";
    return;
  }
  res.data.taskId = res.data.studentId;
  const newTask = res.data;
  newTask.sheetUrls = newTask.sheetUrls || [];
  // newTask.sheetUrls = ["/1-1.jpg", "/1-2.jpg"];
  newTask.sliceUrls = [...newTask.sheetUrls];
  store.currentTask = newTask;
  currentStudentId = studentId;
  updateTaskGroupInfo();
}

const __debounceUpdate = debounce(() => {
  updateUISetting(store.setting.mode, store.setting.uiSetting).catch((e) =>
    console.log("保存设置出错", e)
  );
}, 3000);
watch(
  () => [store.setting.uiSetting],
  () => {
    __debounceUpdate();
  },
  { deep: true }
);

const removeBrokenTask = () => {
  console.log("removeBrokenTask");

  // store.currentTask = undefined;
};

const allZeroSubmit = async () => {
  const markResult = store.currentTask?.markResult;
  if (!markResult) return;

  const { markerScore, scoreList, trackList, specialTagList } = markResult;
  markResult.markerScore = 0;
  const ss = new Array(store.currentTaskEnsured.questionList.length);
  markResult.scoreList = ss.fill(0);
  markResult.trackList = [];

  try {
    await saveTaskToServer();
  } catch (error) {
    console.log("error restore");
  } finally {
    // console.log({ markerScore, scoreList, trackList });
    markResult.markerScore = markerScore;
    markResult.scoreList = scoreList;
    markResult.trackList = trackList;
    markResult.specialTagList = specialTagList;
  }
};

const getMarkData = () => {
  if (!store.currentTask?.markResult) return {};

  let markResult = store.currentTask.markResult;

  let commomData = {
    status: markResult.status,
    spent: Date.now() - store.currentTask.__markStartTime,
  };

  let groupMap = {};
  markResult.trackList.forEach((track) => {
    const { groupNumber } =
      taskQuestionInfo[`${track.mainNumber * 1000}${track.subNumber}`];
    if (!groupMap[groupNumber]) {
      groupMap[groupNumber] = {
        groupNumber,
        trackList: [],
        specialTagList: [],
      };
    }
    groupMap[groupNumber].trackList.push(track);
  });
  markResult.specialTagList.forEach((track) => {
    const { groupNumber } = track;
    if (!groupMap[groupNumber]) {
      groupMap[groupNumber] = {
        groupNumber,
        trackList: [],
        specialTagList: [],
      };
    }
    groupMap[groupNumber].specialTagList.push(track);
  });

  const modifiedQuestions = Object.keys(store.currentTaskModifyQuestion).filter(
    (k) => store.currentTaskModifyQuestion[k]
  );

  let groups = Object.values(groupMap).map((item) => {
    let qScore = {};
    const trackList = item.trackList.filter((track) =>
      modifiedQuestions.includes(`${track.mainNumber}_${track.subNumber}`)
    );
    if (!trackList.length && !item.specialTagList.length) return null;

    trackList.forEach((track) => {
      const qno = `${track.mainNumber * 1000}${track.subNumber}`;
      if (!qScore[qno]) {
        qScore[qno] = {
          mainNumber: track.mainNumber,
          subNumber: track.subNumber,
          score: 0,
        };
      }
      qScore[qno].score += track.score;
    });

    return {
      ...commomData,
      ...item,
      trackList,
      markerScore: Object.values(qScore),
      studentId: store.currentTask.studentId,
    };
  });
  groups = groups.filter((group) => group);

  return {
    studentId: store.currentTask.studentId,
    groups,
  };
};

const saveTaskToServer = async () => {
  if (!store.currentTask) return;
  const markResult = store.currentTask.markResult;
  if (!markResult) return;

  const mkey = "save_task_key";

  type SubmitError = {
    question: Question;
    index: number;
    error: string;
  };

  const errors: SubmitError[] = [];
  markResult.scoreList.forEach((score, index) => {
    if (!store.currentTask) return;
    const question = store.currentTask.questionList[index]!;
    let error;
    if (!isNumber(score)) {
      error = `${question.mainNumber}-${question.subNumber}${
        question.questionName ? "（" + question.questionName + "）" : ""
      } 没有给分，不能提交。`;
    } else if (isNumber(question.maxScore) && score > question.maxScore) {
      error = `${question.mainNumber}-${question.subNumber}${
        question.questionName ? "（" + question.questionName + "）" : ""
      } 给分大于最高分不能提交。`;
    } else if (isNumber(question.minScore) && score < question.minScore) {
      error = `${question.mainNumber}-${question.subNumber}${
        question.questionName ? "（" + question.questionName + "）" : ""
      } 给分小于最低分不能提交。`;
    }
    if (error) {
      errors.push({ question, index, error });
    }
  });
  if (errors.length !== 0) {
    console.log(errors);
    const msg = errors.map((v) => h("div", `${v.error}`));
    void message.warning({
      content: h("span", ["校验失败", ...msg]),
      duration: 10,
      key: mkey,
    });
    return;
  }

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

  // if (!store.isTrackMode) {
  //   markResult.trackList = [];
  // } else {
  //   const trackScores =
  //     markResult.trackList
  //       .map((t) => Math.round((t.score || 0) * 100))
  //       .reduce((acc, s) => acc + s, 0) / 100;
  //   // console.log(markResult.trackList);
  //   // console.log(trackScores, markResult.markerScore);

  //   if (trackScores !== markResult.markerScore) {
  //     void message.error({
  //       content: "轨迹分与总分不一致，请检查。",
  //       duration: 3,
  //       key: mkey,
  //     });
  //     return;
  //   }
  // }

  const data = getMarkData();
  const res = await saveStudentSubjectiveConfirmData(data).catch(() => false);
  if (!res) return;
  if (!res.data.success) {
    console.log(res.data.message);
    void message.error({ content: res.data.message, key: mkey, duration: 5 });
    return;
  }

  if (!isMultiStudent) {
    void message.success({
      content: "保存成功，页面将在3秒钟之后关闭",
      key: mkey,
      duration: 2,
    });
    setTimeout(() => {
      window.close();
    }, 3000);
    return;
  } else {
    void message.success({ content: "保存成功", key: mkey, duration: 2 });
  }

  store.currentTask = undefined;
  await getNextStudent();
};
</script>
