<template>
  <div
    v-if="store.currentTask"
    class="mark-board-track-container tw-flex tw-flex-col"
    :class="[
      {
        hide: store.isScoreBoardCollapsed && !props.modal,
        'mark-board-track-container-in-dialog':
          store.isScoreBoardCollapsed && !props.modal,
        show: !store.isScoreBoardCollapsed,
      },
    ]"
    :style="{
      height: props.modal ? '100%' : 'auto',
    }"
  >
    <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(100% - 56px);
        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
            :id="
              store.isScoreBoardCollapsed
                ? props.modal
                  ? ['bq', question.mainNumber, question.subNumber].join('-')
                  : ''
                : ['bq', question.mainNumber, question.subNumber].join('-')
            "
            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
            :id="
              store.isScoreBoardCollapsed
                ? props.modal
                  ? ['bq', question.mainNumber, question.subNumber].join('-')
                  : ''
                : ['bq', question.mainNumber, question.subNumber].join('-')
            "
            class="question tw-rounded tw-cursor-pointer tw-relative tw-mb-2"
            :class="isCurrentQuestion(question) && 'current-question'"
            tabindex="0"
            outline="0"
            hidefocus="true"
            @click="chooseQuestion(question)"
            @contextmenu="onRightClick($event, index)"
            @blur="rightBlur"
          >
            <div
              v-if="
                activeRightMenuItem?.id ==
                (store.isScoreBoardCollapsed
                  ? props.modal
                    ? ['bq', question.mainNumber, question.subNumber].join('-')
                    : ''
                  : ['bq', question.mainNumber, question.subNumber].join('-'))
              "
              class="tw-fixed right-menu-box"
              :style="tmpStyle"
            >
              <div class="right-menu-item" @click="positioning(question)">
                定位
              </div>
            </div>
            <div
              v-if="!!question.questionName"
              class="tihao"
              @click="positioning(question)"
            >
              {{ question.questionName }}
            </div>
            <div v-else class="tihao" @click="positioning(question)">
              {{ 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.slice(1)"
          :key="i"
          class="single-score tw-cursor-pointer tw-font-bold"
          :class="isCurrentScore(s) && 'current-score'"
          @click="chooseScore(s)"
        >
          {{ s }}
        </div>
        <div
          class="single-score tw-cursor-pointer tw-font-bold"
          :class="Object.is(store.currentScore, 0) && 'current-score'"
          @click="chooseScore(0)"
        >
          0
        </div>
        <div
          class="single-score tw-cursor-pointer tw-font-bold"
          :class="Object.is(store.currentScore, -0) && 'current-score'"
          title="按 # 可以选中"
          @click="chooseScore(-0)"
        >
          空
        </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"
        data-test="clear-score"
        @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, ref, reactive } from "vue";
import { store } from "@/store/store";
import { autoChooseFirstQuestion } from "./use/autoChooseFirstQuestion";
import { dragSplitPane } from "./use/splitPane";
import { addFocusTrack, removeFocusTrack } from "./use/focusTracks";
import EventBus from "@/plugins/eventBus";
import { cloneDeep } from "lodash-es";
const props = defineProps<{ modal?: boolean }>();
const emit = defineEmits(["submit", "allZeroSubmit", "unselectiveSubmit"]);
const { dragSpliter, topPercent } = dragSplitPane();
const activeRightMenuItem = ref<any>(null);
const tmpStyle = reactive<any>({
  left: 0,
  top: 0,
  zIndex: 300,
});
function getParentNode(el: any, c: string): any {
  if (el.className?.includes(c)) {
    return el;
  } else {
    if (el.parentNode) {
      return getParentNode(el.parentNode, c);
    } else {
      return null;
    }
  }
}
const onRightClick = (e: any, index?: any) => {
  e.preventDefault();
  if (
    store.currentTask?.markResult.scoreList[index] ||
    store.currentTask?.markResult.scoreList[index] === 0
  ) {
    tmpStyle.left = e.clientX + "px";
    tmpStyle.top = e.clientY + "px";
    let parentNode = getParentNode(e.target, "question");
    if (parentNode) {
      activeRightMenuItem.value = parentNode;
    }
    console.log("activeRightMenuItem:", activeRightMenuItem.value);
  }
};
const rightBlur = () => {
  activeRightMenuItem.value = null;
  removeFocusTrack();
};
const positioning = (question: Question) => {
  // let list =
  //   store.getMarkStatus === "正评" || store.getMarkStatus === "试评"
  //     ? sliceImagesWithTrackListCopy.value
  //     : undefined;
  // addFocusTrack(undefined, question.mainNumber, question.subNumber, true, list);
  console.log(
    "sliceImagesWithTrackListCopy:",
    sliceImagesWithTrackListCopy.value
  );
  addFocusTrack(
    undefined,
    question.mainNumber,
    question.subNumber,
    true,
    sliceImagesWithTrackListCopy.value || []
  );
  activeRightMenuItem.value = null;
};
watch(topPercent, () => {
  if (topPercent.value < 10) {
    topPercent.value = 10;
  }
  if (topPercent.value > 90) {
    topPercent.value = 90;
  }
});

const { chooseQuestion } = autoChooseFirstQuestion();
let sliceImagesWithTrackListCopy = ref([]);
EventBus.on("draw-change", (list: any) => {
  // if (store.getMarkStatus === "正评" || store.getMarkStatus === "试评") {
  sliceImagesWithTrackListCopy.value = cloneDeep(list);
  // } else {
  // sliceImagesWithTrackListCopy.value = [];
  // }
});

// 切换题目是清空上一题的分数
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 = [];
//   if (question.intervalScore <= 0) {
//     console.warn(`question.intervalScore got: ${question.intervalScore}`);
//   }
//   for (
//     let i = 0;
//     i <= remainScore && question.intervalScore > 0;
//     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;
// });

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

  const remainScore =
    Math.round(question.maxScore * 1000 - (questionScore || 0) * 1000) / 1000;

  const steps = [];
  if (question.intervalScore <= 0) {
    console.warn(`question.intervalScore got: ${question.intervalScore}`);
  }
  for (
    let i = 0;
    i <= remainScore && question.intervalScore > 0;
    i = Math.round(i * 1000 + question.intervalScore * 1000) / 1000
  ) {
    steps.push(i);
  }
  if (
    Math.round(remainScore * 1000) %
      Math.round(question.intervalScore * 1000) !==
    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) {
  if (!store.currentQuestion) return;
  if (" jiklc".includes(event.key)) return;
  if (event.key === "#") {
    keys = [];
    store.currentScore = -0;
    return;
  }

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

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

  // 为了cypress可以加速时间
  if (Date.now() - keyPressTimestamp > 1 * 1000) {
    keys = [];
  }
  keyPressTimestamp = Date.now();
  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);
});

watch(
  () => store.isScoreBoardCollapsed,
  () => {
    // 此处的逻辑是 MarkBoardTrackDialog 带来的，不然 numberKeyListener 在两个组件中多次触发有问题
    if (store.isScoreBoardCollapsed) {
      document.removeEventListener("keydown", numberKeyListener);
      document.removeEventListener("keydown", submitListener);
    } else {
      // 重复添加相同的function是没问题，不会重复触发
      document.addEventListener("keydown", numberKeyListener);
      document.addEventListener("keydown", submitListener);
    }
  },
  { immediate: true }
);

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 * 1000)), 0) / 1000;
}

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 lang="less" scoped>
.right-menu-box {
  z-index: 10;
  background-color: #fff;
  border-radius: 4px;
  width: 80px;
  padding: 2px 0;
  box-shadow: 0 0 3px #ddd;

  .right-menu-item {
    height: 30px;
    line-height: 30px;
    font-size: 14px;
    padding: 0 10px;
    color: #333;
    &:hover {
      background: var(--app-main-bg-color);
    }
  }
}
.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);
  background-color: var(--app-main-bg-color);
}

.mark-board-track-container-in-dialog {
  max-width: 100%;
  min-width: 100%;
  height: 100%;
}

.mark-board-track-container.show {
  margin-right: 0;
}

.mark-board-track-container.hide {
  margin-right: -100%;
}

.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);
  position: relative;
  .tihao {
    &:hover {
      // font-weight: bold;
    }
  }
}

.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>
