<template>
  <CommonMarkBody
    v-if="store"
    :hasMarkResultToRender="true"
    :makeTrack="makeTrack"
    @error="$emit('error')"
  />
  <div class="cursor">
    <div class="cursor-border">
      <span class="text">{{
        store.currentSpecialTag ||
        (Object.is(store.currentScore, -0) ? "空" : store.currentScore)
      }}</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import CommonMarkBody from "@/features/mark/CommonMarkBody.vue";
import { store } from "@/store/store";
import CustomCursor from "custom-cursor.js";
import { onMounted, onUnmounted, watch } from "vue";
import { SliceImage, SpecialTag, Track } from "@/types";

const makeScoreTrack = (
  event: MouseEvent,
  item: SliceImage,
  maxSliceWidth: number,
  theFinalHeight: number
) => {
  // console.log(item);
  if (!store.currentQuestion || typeof store.currentScore === "undefined")
    return;
  const target = event.target as HTMLImageElement;
  const track: Track = {
    mainNumber: store.currentQuestion?.mainNumber,
    subNumber: store.currentQuestion?.subNumber,
    score: store.currentScore,
    unanswered: Object.is(store.currentScore, -0),
    offsetIndex: item.indexInSliceUrls,
    offsetX: Math.round(
      event.offsetX * (target.naturalWidth / target.width) + item.dx
    ),
    offsetY: Math.round(
      event.offsetY * (target.naturalHeight / target.height) + item.dy
    ),
    positionX: -1,
    positionY: -1,
    number: -1,
  };
  track.positionX = (track.offsetX - item.dx) / maxSliceWidth;
  track.positionY =
    (track.offsetY - item.dy + item.accumTopHeight) / theFinalHeight;

  // const isIllegalRange = (testNum: number, min: number, max: number) => {
  //   return testNum < min || testNum > max;
  // };

  // // 检测有问题，此处没有给原图的宽高，如果有的话，要稍微修改下数据类型
  // // 但其实下面也做了一个基本检测
  // if (
  //   isIllegalRange(track.offsetX, 0, target.naturalWidth) ||
  //   isIllegalRange(track.offsetY, 0, target.naturalHeight) ||
  //   isIllegalRange(track.positionX, 0, 1) ||
  //   isIllegalRange(track.positionY, 0, 1)
  // ) {
  //   console.error(
  //     "错误的track",
  //     track,
  //     target.naturalWidth,
  //     target.naturalHeight
  //   );
  //   void message.error("系统错误，请联系管理员!");
  // }

  if (track.offsetX > item.effectiveWidth + item.dx) {
    console.log("不在有效宽度内，轨迹不生效");
    return;
  }
  if (
    item.trackList.some((t) => {
      return (
        Math.pow(Math.abs(t.offsetX - track.offsetX), 2) +
          Math.pow(Math.abs(t.offsetY - track.offsetY), 2) <
        500
      );
    })
  ) {
    console.log("两个轨迹相距过近");
    return;
  }
  // 是否保留当前的轨迹分
  const questionScore =
    store.currentTask &&
    store.currentQuestion &&
    store.currentTask.markResult.scoreList[store.currentQuestion.__index];
  const ifKeepScore =
    Math.round(
      store.currentQuestion.maxScore * 1000 -
        (questionScore || 0) * 1000 -
        store.currentScore * 2 * 1000
    ) / 1000;
  if (ifKeepScore < 0 && store.currentScore > 0) {
    store.currentScore = undefined;
  }
  const markResult = store.currentTaskEnsured.markResult;
  const maxNumber =
    markResult.trackList.length === 0
      ? 0
      : Math.max(...markResult.trackList.map((t) => t.number));
  track.number = maxNumber + 1;
  // console.log(
  //   maxNumber,
  //   track.number,
  //   markResult.trackList.map((t) => t.number),
  //   Math.max(...markResult.trackList.map((t) => t.number))
  // );
  markResult.trackList = [...markResult.trackList, track];
  const { __index, mainNumber, subNumber } = store.currentQuestion;
  markResult.scoreList[__index] =
    markResult.trackList
      .filter((t) => t.mainNumber === mainNumber && t.subNumber === subNumber)
      .map((t) => t.score)
      .reduce((acc, v) => (acc += Math.round(v * 1000)), 0) / 1000;
  item.trackList.push(track);
};

const makeSpecialTagTrack = (
  event: MouseEvent,
  item: SliceImage,
  maxSliceWidth: number,
  theFinalHeight: number
) => {
  // console.log(item);
  if (!store.currentTask || typeof store.currentSpecialTag === "undefined")
    return;
  const target = event.target as HTMLImageElement;
  const track: SpecialTag = {
    tagName: store.currentSpecialTag,
    offsetIndex: item.indexInSliceUrls,
    offsetX: Math.round(
      event.offsetX * (target.naturalWidth / target.width) + item.dx
    ),
    offsetY: Math.round(
      event.offsetY * (target.naturalHeight / target.height) + item.dy
    ),
    positionX: -1,
    positionY: -1,
  };
  track.positionX = (track.offsetX - item.dx) / maxSliceWidth;
  track.positionY =
    (track.offsetY - item.dy + item.accumTopHeight) / theFinalHeight;

  // const isIllegalRange = (testNum: number, min: number, max: number) => {
  //   return testNum < min || testNum > max;
  // };

  // if (
  //   isIllegalRange(track.offsetX, 0, target.naturalWidth) ||
  //   isIllegalRange(track.offsetY, 0, target.naturalHeight) ||
  //   isIllegalRange(track.positionX, 0, 1) ||
  //   isIllegalRange(track.positionY, 0, 1)
  // ) {
  //   console.error("错误的track", track);
  //   void message.error("系统错误，请联系管理员!");
  // }
  // if (track.offsetX > item.effectiveWidth + item.dx) {
  //   console.log("不在有效宽度内，轨迹不生效");
  //   return;
  // }
  if (
    item.tagList.some((t) => {
      return (
        Math.pow(Math.abs(t.offsetX - track.offsetX), 2) +
          Math.pow(Math.abs(t.offsetY - track.offsetY), 2) <
        500
      );
    })
  ) {
    console.log("两个轨迹相距过近");
    return;
  }
  store.currentTaskEnsured.markResult.specialTagList.push(track);
  item.tagList.push(track);
};

const makeTrack = (
  event: MouseEvent,
  item: SliceImage,
  maxSliceWidth: number,
  theFinalHeight: number
) => {
  if (store.setting.uiSetting["specialTag.modal"] && store.currentSpecialTag) {
    makeSpecialTagTrack(event, item, maxSliceWidth, theFinalHeight);
  } else {
    makeScoreTrack(event, item, maxSliceWidth, theFinalHeight);
  }
};

watch(
  () => store.setting.mode,
  () => {
    const shouldHide = store.setting.mode === "COMMON";
    if (shouldHide) {
      // console.log("hide cursor", theCursor);
      // eslint-disable-next-line @typescript-eslint/no-unsafe-call
      theCursor && theCursor.destroy();
    } else {
      if (document.querySelector(".cursor")) {
        // console.log("show cursor", theCursor);
        // theCursor && theCursor.enable();
        // eslint-disable-next-line @typescript-eslint/no-unsafe-call
        theCursor = new CustomCursor(".cursor", {
          focusElements: [
            {
              selector: ".mark-body-container",
              focusClass: "cursor--focused-view",
            },
          ],
        }).initialize();
      }
    }
  }
);
let theCursor = null as any;
onMounted(() => {
  if (store.isTrackMode) {
    // eslint-disable-next-line @typescript-eslint/no-unsafe-call
    theCursor = new CustomCursor(".cursor", {
      focusElements: [
        {
          selector: ".mark-body-container",
          focusClass: "cursor--focused-view",
        },
      ],
    }).initialize();
  }
});

onUnmounted(() => {
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
  theCursor && theCursor.destroy();
});

defineEmits(["error"]);
</script>
<style scoped>
.cursor {
  color: #ff5050;
  display: none;
  pointer-events: none;
  user-select: none;
  top: 0;
  left: 0;
  position: fixed;
  will-change: transform;
  z-index: 1000;
}

.cursor-border {
  position: absolute;
  box-sizing: border-box;
  align-items: center;
  border: 1px solid #ff5050;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  height: 0px;
  width: 0px;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  transition: all 360ms cubic-bezier(0.23, 1, 0.32, 1);
}

.cursor.cursor--initialized {
  display: block;
}

.cursor .text {
  font-size: 2rem;
  opacity: 0;
  transition: opacity 80ms cubic-bezier(0.23, 1, 0.32, 1);
}

.cursor.cursor--off-screen {
  opacity: 0;
}

.cursor.cursor--focused .cursor-border,
.cursor.cursor--focused-view .cursor-border {
  width: 90px;
  height: 90px;
}

.cursor.cursor--focused-view .text {
  opacity: 1;
  transition: opacity 360ms cubic-bezier(0.23, 1, 0.32, 1);
}
</style>
