<template>
  <div
    v-if="store.currentTask"
    class="mark-board-track-container"
    :class="[store.isScoreBoardCollapsed ? 'hide' : 'show']"
  >
    <div
      class="tw-flex tw-rounded tw-justify-between tw-p-2 tw-pl-5 top-container tw-mb-4"
    >
      <div class="tw-flex tw-flex-col">
        <div class="tw-flex tw-items-center tw-gap-2">
          <img
            src="./images/totalscore.png"
            style="width: 13px; height: 16px"
          />
          总分
        </div>
        <div class="total-score tw-ml-5 tw-font-bold" style="height: 50px">
          <transition-group name="score-number-animation" tag="span">
            <span
              :key="store.currentTask.markResult.markerScore || 0"
              class="tw-inline-block"
              >{{ store.currentTask.markResult.markerScore }}</span
            >
          </transition-group>
        </div>
      </div>

      <div class="tw-flex tw-place-content-center tw-items-center tw-gap-2">
        <div class="tw-flex tw-flex-col tw-gap-1">
          <a-popconfirm
            v-if="store.setting.enableAllZero && !store.setting.forceSpecialTag"
            title="确定给全零分？"
            :overlayStyle="{ width: '200px' }"
            @confirm="$emit('allZeroSubmit')"
          >
            <a-button
              type="primary"
              size="middle"
              class="all-zero-unselective-button"
            >
              <span>全零分</span>
            </a-button>
          </a-popconfirm>
          <a-popconfirm
            v-if="store.setting.selective"
            title="确定是未选做？"
            :overlayStyle="{ width: '200px' }"
            @confirm="$emit('unselectiveSubmit')"
          >
            <a-button
              type="primary"
              size="middle"
              class="all-zero-unselective-button"
            >
              <span>未选做</span>
            </a-button>
          </a-popconfirm>
        </div>

        <qm-button
          type="primary"
          shape="round"
          size="middle"
          style="height: 76px; border-radius: 10px; padding: 12px"
          @click="submit"
        >
          提交
        </qm-button>
      </div>
    </div>

    <div
      style="
        height: calc(100vh - 56px - 210px);
        overflow: hidden;
        user-select: none;
        position: relative;
      "
    >
      <div
        v-if="store.currentTask && store.currentTask.questionList"
        class="tw-flex tw-gap-2 tw-flex-wrap tw-justify-between tw-overflow-auto tw-content-start"
        :style="{ height: `${topPercent}%` }"
      >
        <template
          v-for="(question, index) in store.currentTask.questionList"
          :key="index"
        >
          <div
            class="question tw-rounded tw-cursor-pointer tw-relative tw-mb-2"
            :class="isCurrentQuestion(question) && 'current-question'"
            @click="chooseQuestion(question)"
            @mouseover="
              addFocusTrack(
                undefined,
                question.mainNumber,
                question.subNumber,
                true
              )
            "
            @mouseleave="removeFocusTrack"
          >
            <div>
              {{ question.title }} {{ question.mainNumber }}-{{
                question.subNumber
              }}
            </div>
            <!-- 设置高度 避免动画跳动 -->
            <div style="height: 32px">
              <transition-group name="score-number-animation" tag="span">
                <span
                  :key="store.currentTask?.markResult.scoreList[index] || 0"
                  class="tw-font-medium tw-text-2xl score tw-inline-block"
                >
                  <!-- 特殊的空格符号 -->
                  <!-- eslint-disable-next-line no-irregular-whitespace -->
                  {{ store.currentTask?.markResult.scoreList[index] ?? " " }}
                </span>
              </transition-group>
            </div>
          </div>
        </template>
      </div>

      <div
        ref="dragSpliter"
        style="
          width: 100%;
          height: 4px;
          border: 2px solid grey;
          background-color: grey;
          cursor: row-resize;
        "
        class="split-pane tw-flex tw-justify-evenly"
      >
        <div
          style="
            margin-top: -14px;
            width: 20px;
            height: 16px;
            text-align: center;
            clip-path: polygon(0 100%, 100% 100%, 50% 0);
            background-color: lightskyblue;
            cursor: pointer;
          "
          @click="topPercent = 20"
        ></div>
        <div
          style="
            margin-top: -3px;
            width: 20px;
            height: 16px;
            text-align: center;
            clip-path: polygon(0 0, 100% 0, 50% 100%);
            background-color: lightskyblue;
            cursor: pointer;
          "
          @click="topPercent = 90"
        ></div>
      </div>
      <div
        class="tw-flex tw-flex-wrap tw-mt-5 tw-overflow-auto tw-content-start"
        style="padding-bottom: 40px; gap: 8px"
        :style="{ height: `${100 - topPercent}%` }"
      >
        <div
          v-for="(s, i) in questionScoreSteps"
          :key="i"
          class="single-score tw-cursor-pointer tw-font-bold"
          :class="isCurrentScore(s) && 'current-score'"
          @click="chooseScore(s)"
        >
          {{ s }}
        </div>
      </div>
    </div>
    <div
      class="tw-flex tw-justify-between tw-mt-4"
      style="position: relative; bottom: 0px; right: 0px; width: 230px"
    >
      <qm-button
        type="primary"
        shape="round"
        size="large"
        style="
          background-color: var(--app-undo-button-bg-color);
          border-color: var(--app-undo-button-bg-color);
        "
        :clickTimeout="300"
        @click="clearLatestMarkOfCurrentQuetion"
      >
        回退
      </qm-button>

      <qm-button
        type="primary"
        shape="round"
        size="large"
        :clickTimeout="300"
        @click="clearAllMarksOfCurrentQuetion"
      >
        清除本题
      </qm-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { Question } from "@/types";
import { isNumber } from "lodash-es";
import { onMounted, onUnmounted, watch } from "vue";
import { store } from "@/store/store";
import { autoChooseFirstQuestion } from "./use/autoChooseFirstQuestion";
import { dragSplitPane } from "./use/splitPane";
import { addFocusTrack, removeFocusTrack } from "./use/focusTracks";

const emit = defineEmits(["submit", "allZeroSubmit", "unselectiveSubmit"]);
const { dragSpliter, topPercent } = dragSplitPane();

watch(topPercent, () => {
  if (topPercent.value <= 10) {
    topPercent.value = 10;
  }
  if (topPercent.value >= 90) {
    topPercent.value = 90;
  }
});

const { chooseQuestion } = autoChooseFirstQuestion();

// 切换题目是清空上一题的分数
watch(
  () => store.currentQuestion,
  () => (store.currentScore = undefined)
);

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

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

  const remainScore =
    Math.round(question.maxScore * 100 - (questionScore || 0) * 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 (
    store.currentQuestion?.mainNumber === question.mainNumber &&
    store.currentQuestion?.subNumber === question.subNumber
  );
}

function isCurrentScore(score: number) {
  return store.currentScore === score;
}
function chooseScore(score: number) {
  if (store.currentScore === score) {
    store.currentScore = undefined;
  } else {
    store.currentScore = score;
    store.currentSpecialTag = undefined;
  }
}

let keyPressTimestamp = 0;
let keys: string[] = [];
function numberKeyListener(event: KeyboardEvent) {
  // console.log(event);
  if (!store.currentQuestion) return;
  if (" jiklc".includes(event.key)) return;

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

  // tab 循环答题列表
  if (event.key === "Tab") {
    const idx = indexOfCurrentQuestion() as number;
    if (idx >= 0 && store.currentTask) {
      const len = store.currentTask.questionList.length;
      chooseQuestion(store.currentTask.questionList[(idx + 1) % len]);
      event.preventDefault();
    }
    return;
  }

  if (event.timeStamp - keyPressTimestamp > 1 * 1000) {
    keys = [];
  }
  keyPressTimestamp = event.timeStamp;
  keys.push(event.key);
  if (isNaN(parseFloat(keys.join("")))) {
    keys = [];
  }
  if (event.key === "Escape") {
    keys = [];
    store.currentScore = undefined;
    store.currentSpecialTag = undefined;
    return;
  }
  const score = parseFloat(keys.join(""));
  if (isNumber(score) && questionScoreSteps.includes(score)) {
    chooseScore(score);
  }
}

function submitListener(e: KeyboardEvent) {
  // if (import.meta.env.DEV && e.ctrlKey && e.key === "Enter") {
  if (e.ctrlKey && e.key === "Enter") {
    submit();
  }
}
onMounted(() => {
  document.addEventListener("keydown", numberKeyListener);
  document.addEventListener("keydown", submitListener);
});
onUnmounted(() => {
  document.removeEventListener("keydown", numberKeyListener);
  document.removeEventListener("keydown", submitListener);
});

function clearLatestMarkOfCurrentQuetion() {
  if (!store.currentTask?.markResult || !store.currentQuestion) return;

  const { __index, mainNumber, subNumber } = store.currentQuestion;
  const markResult = store.currentTask.markResult;
  const ts = markResult.trackList.filter(
    (q) => q.mainNumber === mainNumber && q.subNumber === subNumber
  );
  if (ts.length === 0) {
    return;
  }
  const lastMark = ts.splice(-1)[0];
  store.removeScoreTracks = [lastMark];
  markResult.trackList = markResult.trackList.filter((t) => t !== lastMark);

  markResult.scoreList[__index] =
    ts.length === 0
      ? null
      : ts
          .map((t) => t.score)
          .reduce((acc, v) => (acc += Math.round(v * 100)), 0) / 100;
}

function clearAllMarksOfCurrentQuetion() {
  if (!store.currentTask?.markResult || !store.currentQuestion) return;

  const markResult = store.currentTask.markResult;
  store.removeScoreTracks = markResult.trackList.filter(
    (q) =>
      q.mainNumber === store.currentQuestion?.mainNumber &&
      q.subNumber === store.currentQuestion?.subNumber
  );
  markResult.trackList = markResult.trackList.filter(
    (q) => !store.removeScoreTracks.includes(q)
  );
  const { __index } = store.currentQuestion;
  markResult.scoreList[__index] = null;
}

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

const buttonHeightForSelective = $computed(() =>
  store.setting.selective &&
  store.setting.enableAllZero &&
  !store.setting.forceSpecialTag
    ? "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: 110px;
  max-width: 110px;
  min-height: 72px;
  padding: 10px;
  background-color: var(--app-container-bg-color);
}
.current-question {
  color: white;
  background-color: var(--app-score-color);
}
.single-score {
  position: relative;
  width: 32px;
  height: 32px;
  font-size: var(--app-secondary-font-size);
  display: grid;
  place-content: center;
  background-color: var(--app-container-bg-color);

  border-radius: 30px;
}
.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>
