<template>
  <div
    v-if="markStore.currentTask"
    :key="markStore.currentTask?.secretNumber || 0"
    class="mark-board-track is-key-board"
    :class="[
      markStore.isTrackMode && markStore.isScoreBoardCollapsed
        ? 'hide'
        : 'show',
    ]"
  >
    <div class="board-mode">
      <a-select
        v-model:value="normalMode"
        style="width: 120px"
        @change="normalModeChange"
      >
        <a-select-option value="keyboard">键盘给分</a-select-option>
        <a-select-option value="mouse">鼠标给分</a-select-option>
      </a-select>
    </div>
    <div class="board-header">
      <div class="board-header-left">
        <div class="board-header-info">
          <img src="@/assets/icons/icon-star.svg" />
          <span>总分</span>
        </div>
        <div class="board-header-score">
          <transition-group name="score-number-animation" tag="span">
            <span :key="markStore.currentTask.markResult?.markerScore || 0">{{
              markStore.currentTask.markResult?.markerScore
            }}</span>
          </transition-group>
        </div>
      </div>
      <qm-button
        v-if="props.isCheckAnswer && !hasModifyScore"
        class="board-header-submit"
        size="medium"
        type="primary"
        @click="checkSubmit"
      >
        复核
      </qm-button>
      <qm-button
        v-else
        class="board-header-submit"
        size="medium"
        type="primary"
        @click="submit"
      >
        提交
      </qm-button>
    </div>

    <div
      v-if="markStore.currentTaskEnsured.questionList"
      class="board-questions"
      :style="{
        flexGrow: 2,
      }"
    >
      <template
        v-for="(question, index) in markStore.currentTaskEnsured.questionList"
        :key="index"
      >
        <div class="board-question-full-box">
          <div
            :id="'bq-' + question.mainNumber + '-' + question.subNumber"
            :class="[
              'board-question',
              {
                'is-current': isCurrentQuestion(question),
                'is-disabled': isDisabledQuestion(question),
              },
            ]"
            @click="
              () => {
                chooseQuestion(question);
                scrollToQuestion(question);
              }
            "
          >
            <div class="question-info">
              <div class="question-title" :title="question.title">
                {{ question.title }}
              </div>
              <div class="question-no">
                间隔{{ question.intervalScore }}分，给分区间{{
                  question.minScore
                }}~{{ question.maxScore }}
              </div>
              <div class="question-no">
                {{ question.mainNumber }}-{{ question.subNumber }}
              </div>
            </div>

            <div
              :class="[
                'question-score',
                {
                  'is-problem': question.problem || isArbitrated(question),
                },
              ]"
            >
              <transition-group name="score-number-animation" tag="span">
                <span v-if="question.problem"> 问题卷 </span>
                <span v-else-if="isArbitrated(question)">{{
                  getArbitratedStatusName(question)
                }}</span>
                <span v-else-if="!question.selfMark">已评</span>
                <span
                  v-else
                  :key="`${question.mainNumber}_${question.subNumber}_${index}`"
                >
                  {{
                    isCurrentQuestion(question)
                      ? scoreStr
                      : markStore.currentTask?.markResult?.scoreList[index]
                  }}
                </span>
              </transition-group>
            </div>
          </div>
        </div>
      </template>
    </div>
    <div
      v-if="!isCheckAnswer && markStore.currentQuestion?.selfMark"
      class="board-footer"
    >
      <qm-button
        v-if="markStore.currentQuestion?.problem"
        class="board-clear"
        @click="cancelProblemQuestion"
      >
        取消问题卷
      </qm-button>
      <qm-button v-else class="board-clear" @click="toMarkProblemQuestion">
        标记问题卷
      </qm-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { Question } from "@/types";
import { isNumber } from "lodash-es";
import { ref, onMounted, onUnmounted, watch } from "vue";
import { useMarkStore } from "@/store";
import useAutoChooseFirstQuestion from "../composables/useAutoChooseFirstQuestion";
import useQuestion from "../composables/useQuestion";
import useMakeTrack from "../composables/useMakeTrack";
import { message } from "ant-design-vue";

const emit = defineEmits([
  "submit",
  "allZeroSubmit",
  "unselectiveSubmit",
  "checkSubmit",
]);
const props = defineProps<{ isCheckAnswer?: boolean }>();

const {
  isDisabledQuestion,
  isArbitrated,
  getArbitratedStatusName,
  cancelProblemQuestion,
  toMarkProblemQuestion,
} = useQuestion();
const { chooseQuestion } = useAutoChooseFirstQuestion();
const { makeCommonTrack } = useMakeTrack();
const hasModifyScore = ref(false);

const markStore = useMarkStore();

/**
 * 当前题的输入串，初次是markResult.scoreList中score，然后接收输入字符，回车时判断是否合法，合法则赋值给markResult.scoreList
 * 切换到下一题，则重新开始
 *  */
let scoreStr = $ref("");
watch(
  () => [markStore.currentQuestion, markStore.setting.uiSetting["normal.mode"]],
  () => {
    if (markStore.currentQuestion) {
      const { __index } = markStore.currentQuestion;
      const scoreR = markStore.currentTask?.markResult?.scoreList[__index];
      scoreStr =
        scoreR || scoreR === 0 ? scoreR : markStore.currentQuestion.score;
      if (isNumber(scoreStr)) {
        scoreStr = "" + scoreStr;
      } else {
        scoreStr = "";
      }
    } else {
      scoreStr = "";
    }
  },
  { immediate: true }
);
// 切换给分模式
const normalMode = ref(
  markStore.setting.uiSetting["normal.mode"] || "keyboard"
);
function normalModeChange(value: string) {
  markStore.setting.uiSetting["normal.mode"] = value;
}

const questionScoreSteps = $computed(() => {
  const question = markStore.currentQuestion;
  if (!question) return [];

  const remainScore = Math.round(question.maxScore * 100) / 100;
  const steps = [];
  for (
    let i = 0;
    i <= remainScore;
    i = Math.round(i * 100 + question.intervalScore * 100) / 100
  ) {
    steps.push(i);
  }
  if (
    Math.round(remainScore * 100) % Math.round(question.intervalScore * 100) !==
    0
  ) {
    steps.push(remainScore);
  }

  return steps;
});

function isCurrentQuestion(question: Question) {
  return (
    markStore.currentQuestion?.mainNumber === question.mainNumber &&
    markStore.currentQuestion?.subNumber === question.subNumber
  );
}

const questionScore = $computed(
  () =>
    markStore.currentTask &&
    markStore.currentQuestion &&
    markStore.currentTask.markResult.scoreList[
      markStore.currentQuestion.__index
    ]
);

function numberKeyListener(event: KeyboardEvent) {
  if (
    isDisabledQuestion(markStore.currentQuestion) ||
    markStore.currentQuestion?.problem
  )
    return;
  // 只要修改了分值，就当做已修改
  hasModifyScore.value = true;

  // console.log(event);
  // if (event.target.tagName !== "BODY") return;
  if (!markStore.currentQuestion || !markStore.currentTask) return;
  if (markStore.globalMask) return;

  function indexOfCurrentQuestion() {
    return markStore.currentTaskEnsured.questionList.findIndex(
      (q) =>
        q.mainNumber === markStore.currentQuestion?.mainNumber &&
        q.subNumber === markStore.currentQuestion.subNumber
    );
  }

  // 处理Enter跳下一题或submit
  if (event.key === "Enter") {
    const allScoreMarked = markStore.currentTask.markResult.scoreList.every(
      (s) => isNumber(s)
    );
    // 如果所有题已赋分，并且当前题赋分和输入串和当前题分数一致，则可以在任意题提交
    if (allScoreMarked && scoreStr === "" + questionScore) {
      submit();
      return;
    }

    if (scoreStr.length === 0) {
      void message.error({ content: "请输入分数", duration: 5 });
      console.log("请输入分数");
      return;
    }

    // 0 分
    // 整数分 (开始不为0)
    // 小数分 (开始和结束不为0，结束必须为1-9
    if (
      !(
        scoreStr === "0" ||
        /^0\.[1-9]\d*$/.test(scoreStr) ||
        /^[1-9]\d*$/.test(scoreStr) ||
        /^[1-9]\d*\.\d*[1-9]$/.test(scoreStr)
      )
    ) {
      void message.error({ content: "分数格式不正确", duration: 5 });
      console.log("分数格式不正确");
      return;
    }
    const score = parseFloat(scoreStr);
    // console.log(score);
    if (!isNumber(score)) {
      void message.error({ content: "非数字输入", duration: 5 });
      console.log("非数字输入");
      return;
    }
    if (!questionScoreSteps.includes(score)) {
      void message.error({ content: "输入的分数不在有效间隔内", duration: 5 });
      return;
    }
    makeCommonTrack(markStore.currentQuestion, score);

    // 跳到下一题
    const idx = indexOfCurrentQuestion();
    if (idx + 1 < markStore.currentTask.questionList.length) {
      chooseQuestion(markStore.currentTask.questionList[idx + 1]);
    }
    return;
  }
  if (event.key === "ArrowUp") {
    const idx = indexOfCurrentQuestion();
    if (idx > 0) {
      chooseQuestion(markStore.currentTask.questionList[idx - 1]);
    }
    event.preventDefault();
    return;
  }
  if (event.key === "ArrowDown") {
    const idx = indexOfCurrentQuestion();
    if (idx < markStore.currentTask.questionList.length - 1) {
      chooseQuestion(markStore.currentTask.questionList[idx + 1]);
    }
    event.preventDefault();
    return;
  }
  // 处理回退删除分数
  if (event.key === "Backspace") {
    if (scoreStr.length > 0) {
      scoreStr = scoreStr.slice(0, -1);
    } else {
      return;
    }
  }
  if (event.key === "Escape") {
    scoreStr = "";
  }

  // 此时不再接受任何非数字键
  if (".0123456789".includes(event.key)) {
    scoreStr += event.key;
  }
}
onMounted(() => {
  document.addEventListener("keydown", numberKeyListener);
});
onUnmounted(() => {
  document.removeEventListener("keydown", numberKeyListener);
});

// const scrollToQuestion = (question: Question) => {
//   const node = document.querySelector(
//     `#q-${question.mainNumber}-${question.subNumber}`
//   );
//   node && node.scrollIntoView({ behavior: "smooth" });
// };

// watch(
//   () => markStore.currentQuestion,
//   () => {
//     markStore.currentQuestion && scrollToQuestion(markStore.currentQuestion);
//   }
// );

function submit() {
  emit("submit");
}

function checkSubmit() {
  emit("checkSubmit");
}

const buttonHeightForSelective = $computed(() =>
  markStore.setting.selective && markStore.setting.enableAllZero
    ? "36px"
    : "76px"
);
</script>

<style scoped>
.mark-board-track-container {
  max-width: 290px;
  min-width: 290px;
  padding: 20px;
  max-height: calc(100vh - 56px - 0px);
  overflow: auto;
  z-index: 1001;
  transition: margin-right 0.5s;
  color: var(--app-small-header-text-color);
}
.mark-board-track-container.show {
  margin-right: 0;
}
.mark-board-track-container.hide {
  margin-right: -290px;
}

.top-container {
  background-color: var(--app-container-bg-color);
}
.total-score {
  color: var(--app-main-text-color);
  font-size: 32px;
}
.question {
  min-width: 80px;
  padding: 10px;
  background-color: var(--app-container-bg-color);
}
.current-question {
  color: white;
  background-color: var(--app-score-color);
}

.current-score {
  background-color: var(--app-score-color);
  color: white;
}
.all-zero-unselective-button {
  height: v-bind(buttonHeightForSelective);
  border-radius: 10px;
  padding: 7px;
  background-color: #4db9ff;
  border: none;
}
</style>
