import { Setting, MarkStore, AdminPageSetting, Task } from "@/types";
import { watch } from "vue";
import { defineStore } from "pinia";

const initState: MarkStore = {
  setting: {
    mode: "TRACK",
    examType: "SCAN_IMAGE",
    forceMode: false,
    sheetView: false,
    autoScroll: false,
    sheetConfig: [],
    enableAllZero: false,
    enableSplit: true,
    fileServer: "",
    userName: "",
    subject: <Setting["subject"]>{},
    forceSpecialTag: false,
    uiSetting: {
      "answer.paper.scale": 1,
      "score.board.collapse": false,
      "normal.mode": "keyboard",
      "paper.modal": false,
      "answer.modal": false,
      "minimap.modal": false,
      "specialTag.modal": false,
      "shortCut.modal": false,
      "score.fontSize.scale": 1,
    },
    statusValue: null,
    problemTypes: [],
    groupNumber: -987654, // 默认不可能的值
    groupTitle: "",
    topCount: 0,
    splitConfig: [],
    prefetchCount: 3,
    startTime: 0,
    endTime: 0,
    selective: false,
  },
  status: <MarkStore["status"]>{},
  groups: [],
  tasks: [],
  message: null,
  currentTask: undefined,
  currentQuestion: undefined,
  currentScore: undefined,
  currentSpecialTag: undefined,
  historyOpen: false,
  historyTasks: [],
  removeScoreTracks: [],
  focusTracks: [],
  maxModalZIndex: 1020,
  minimapScrollToX: 0,
  minimapScrollToY: 0,
  allPaperModal: false,
  sheetViewModal: false,
  globalMask: false,
};

const useMarkStore = defineStore("mark", {
  state: () => {
    return initState;
  },
  getters: {
    /** 获得statusValue的中文名 */
    getStatusValueName() {
      const st = store.setting.statusValue;
      if (!st) return "";
      if (st === "FORMAL") return "正评";
      if (st === "TRIAL") return "试评";
      return "";
    },
    /** 当前任务。确保不为空，需在上文已经检查过 store.currentTask 不为空 */
    currentTaskEnsured(): Task {
      return store.currentTask;
    },
    /** 是否是评卷端的轨迹模式 */
    isTrackMode(): boolean {
      return store.setting.mode && store.setting.mode === "TRACK";
    },
    /** 评卷端的轨迹模式显示轨迹 && 管理后台都显示轨迹 */
    shouldShowTrack(): boolean {
      // FIXME: 不是最优雅的方式来判断是否是阅卷端
      const isWebMark = location.pathname === "/web/mark";
      return !isWebMark || this.isTrackMode;
    },
    /* 是否是扫描阅卷 */
    isScanImage(): boolean {
      return this.setting.examType === "SCAN_IMAGE";
    },
    isMultiMedia(): boolean {
      return this.setting.examType === "MULTI_MEDIA";
    },
    /* 返回正在评卷的状态 '' | 回评 | 打回 */
    getMarkStatus(): string {
      if (!this.currentTask) return "";
      if (this.currentTask.previous) return "回评";
      if (this.currentTask.rejected) return "打回";

      return store.getStatusValueName;
    },
    shouldShowMarkBoardKeyBoard(): boolean {
      return (
        store.setting.mode === "COMMON" &&
        store.setting.uiSetting["normal.mode"] === "keyboard"
      );
    },
    shouldShowMarkBoardMouse(): boolean {
      return (
        store.setting.mode === "COMMON" &&
        store.setting.uiSetting["normal.mode"] === "mouse"
      );
    },
    isScoreBoardCollapsed(): boolean {
      return store.setting.uiSetting["score.board.collapse"];
    },
    isScoreBoardVisible(): boolean {
      return !store.setting.uiSetting["score.board.collapse"];
    },
  },
  actions: {
    initSetting(adminPageSetting: AdminPageSetting): void {
      Object.assign(this.setting, adminPageSetting, {
        mode: "COMMON" as Setting["mode"],
        uiSetting: {
          "answer.paper.scale": 1,
          "score.board.collapse": false,
          "normal.mode": "keyboard",
          "score.fontSize.scale": 1,
        } as Setting["uiSetting"],
      });
      const fileServer = this.setting.fileServer;
      if (this.setting.subject?.answerUrl) {
        this.setting.subject.answerUrl =
          fileServer + this.setting.subject?.answerUrl;
      }
      if (this.setting.subject?.paperUrl) {
        this.setting.subject.paperUrl =
          fileServer + this.setting.subject?.paperUrl;
      }
    },
    toggleHistory(): void {
      this.historyOpen = !this.historyOpen;
    },
    toggleScoreBoard(): void {
      this.setting.uiSetting["score.board.collapse"] =
        !this.setting.uiSetting["score.board.collapse"];
    },
  },
});

export let store = null as unknown as ReturnType<typeof useMarkStore>;

export const initMarkStore = () => {
  store = useMarkStore();

  watch(
    () => store.currentTask,
    () => {
      // 初始化 task.markResult ，始终保证 task 下有 markResult
      // 1. 评卷时，如果没有 markResult ，则初始化一个 markResult 给它
      // 1. 回评时，先清空它的 markResult ，然后初始化一个 markResult 给它
      if (!store.currentTask) return;

      const task = store.currentTask;
      if (task.previous && task.markResult) {
        task.markResult = undefined;
      }
      if (!task.markResult) {
        // 管理后台可能不设置 questionList, 而且它不用 markResult
        if (!task.questionList) {
          task.questionList = [];
          // return;
        }
        // 初始化 __index
        task.questionList.forEach((q, i, ar) => (ar[i].__index = i));

        task.__markStartTime = Date.now();
        const statusValue = store.setting.statusValue;
        const { libraryId, studentId } = task;
        task.markResult = {
          statusValue: statusValue,
          libraryId: libraryId,
          studentId: studentId,
          spent: 0,

          trackList: task.questionList.map((q) => q.trackList).flat(),
          specialTagList: [...(task.specialTagList ?? [])],
          scoreList: task.questionList.map((q) => q.score),
          markerScore: null, // 后期通过 scoreList 自动更新

          problem: false,
          problemTypeId: 0,
          unselective: false,
        };
        task.markResult.trackList.forEach((t) => {
          if (t.unanswered) {
            t.score = -0;
          }
        });
      }
    }
  );

  // 唯一根据 scoreList 自动更新 markerScore
  watch(
    () => store.currentTask?.markResult.scoreList,
    () => {
      if (!store.currentTask) return;
      const scoreList = store.currentTask.markResult.scoreList.filter(
        (v) => v !== null
      );
      const result =
        scoreList.length === 0
          ? null
          : scoreList.reduce((acc, v) => (acc += Math.round(v * 1000)), 0) /
            1000;
      store.currentTask.markResult.markerScore = result;
    },
    { deep: true }
  );

  // scoreList 被 trackList 和用户手动更新
};
