<template>
  <transition-group name="track-score" tag="div">
    <template v-for="track in trackList">
      <div
        v-if="store.shouldShowTrack && (doubleTrack || !track.isByMultMark)"
        :key="`key-${track.mainNumber}-${track.subNumber}-${track.offsetY}-${track.offsetX}`"
        class="score-container no-event"
        :class="[focusedTrack(track) && 'score-animation']"
        :style="computeTopAndLeft(track)"
      >
        <span
          :id="`a-${track.mainNumber}-${track.subNumber}-${track.offsetY}-${track.offsetX}`"
          class="tw-m-auto"
        >
          {{ track.unanswered ? "空" : track.score }}
        </span>
      </div>
    </template>
  </transition-group>
  <template
    v-for="tag in specialTagList"
    :key="`${tag.offsetX}_${tag.offsetY}`"
  >
    <img
      v-if="tag.tagType === 'TEXT'"
      class="special-text"
      :style="computeSpecialTextStyle(tag)"
      :src="getSpecialTextImg(tag)"
    />
    <div
      v-else-if="tag.tagType === 'LINE'"
      class="special-line"
      :style="computeSpecialLineStyle(tag)"
    ></div>
    <div
      v-else-if="tag.tagType === 'CIRCLE'"
      class="special-circle"
      :style="computeSpecialCircleStyle(tag)"
      @click="circleTagClickHandle"
    ></div>
    <div
      v-else-if="tag.tagType === 'RIGHT'"
      :class="['score-container', 'no-event']"
      :style="computeTopAndLeft(tag)"
    >
      <span class="tw-m-auto">
        <CheckOutlined />
      </span>
    </div>
    <div
      v-else
      :class="['score-container', 'no-event']"
      :style="computeTopAndLeft(tag)"
    >
      <span class="tw-m-auto">
        {{ tag.tagName }}
      </span>
    </div>
  </template>
</template>

<script setup lang="ts">
import type { SpecialTag, Track } from "@/types";
import { toRefs, watch, nextTick, computed } from "vue";
import { store } from "@/store/store";
import { message } from "ant-design-vue";
import { CheckOutlined } from "@ant-design/icons-vue";
import { useRoute } from "vue-router";
const route = useRoute();

const doubleTrack = computed(() => {
  return !!store.setting?.doubleTrack;
});
const props = defineProps<{
  trackList: Array<Track>;
  specialTagList: Array<SpecialTag>;
  sliceImageWidth: number;
  sliceImageHeight: number;
  dx: number;
  dy: number;
}>();
const emit = defineEmits(["click-specialtag"]);

const { trackList } = toRefs(props);

const computeSpecialLineStyle = (track: SpecialTag) => {
  // {"tagName":"{\"len\":241.9842519685039}","tagType":"LINE","offsetIndex":2,"offsetX":324.8193228048039,"offsetY":759.8560783391572,"positionX":0.06189180773871382,"positionY":-0.01054037309709878}
  const tagProp = JSON.parse(track.tagName);

  const topInsideSlice = track.offsetY - props.dy;
  const leftInsideSlice = track.offsetX - props.dx;
  const topInsideSliceRatio = topInsideSlice / props.sliceImageHeight;
  const leftInsideSliceRatio = leftInsideSlice / props.sliceImageWidth;
  return {
    top: topInsideSliceRatio * 100 + "%",
    left: leftInsideSliceRatio * 100 + "%",
    width: (100 * tagProp.len) / props.sliceImageWidth + "%",
    position: "absolute",
    borderTop: `1px solid ${track.color || "red"}`,
    zIndex: 9,
  };
};
const computeSpecialCircleStyle = (track: SpecialTag) => {
  // {"tagName":"{\"len\":241.9842519685039}","tagType":"LINE","offsetIndex":2,"offsetX":324.8193228048039,"offsetY":759.8560783391572,"positionX":0.06189180773871382,"positionY":-0.01054037309709878}
  const tagProp = JSON.parse(track.tagName);

  const topInsideSlice = track.offsetY - props.dy;
  const leftInsideSlice = track.offsetX - props.dx;
  const topInsideSliceRatio = topInsideSlice / props.sliceImageHeight;
  const leftInsideSliceRatio = leftInsideSlice / props.sliceImageWidth;
  return {
    top: topInsideSliceRatio * 100 + "%",
    left: leftInsideSliceRatio * 100 + "%",
    width: (100 * tagProp.width) / props.sliceImageWidth + "%",
    height: (100 * tagProp.height) / props.sliceImageHeight + "%",
    position: "absolute",
    border: `1px solid ${track.color || "red"}`,
    borderRadius: "50%",
    zIndex: 9,
  };
};

const computeSpecialTextStyle = (track: SpecialTag) => {
  // {"tagName":"{\"len\":241.9842519685039}","tagType":"LINE","offsetIndex":2,"offsetX":324.8193228048039,"offsetY":759.8560783391572,"positionX":0.06189180773871382,"positionY":-0.01054037309709878}
  const tagProp = JSON.parse(track.tagName);

  const topInsideSlice = track.offsetY - props.dy;
  const leftInsideSlice = track.offsetX - props.dx;
  const topInsideSliceRatio = topInsideSlice / props.sliceImageHeight;
  const leftInsideSliceRatio = leftInsideSlice / props.sliceImageWidth;

  return {
    top: topInsideSliceRatio * 100 + "%",
    left: leftInsideSliceRatio * 100 + "%",
    width: (100 * tagProp.width) / props.sliceImageWidth + "%",
    height: (100 * tagProp.height) / props.sliceImageHeight + "%",
    position: "absolute",
    marginTop: "-10px",
    zIndex: 9,
  };
};
const getSpecialTextImg = (track: SpecialTag) => {
  const tagProp = JSON.parse(track.tagName);
  const canvas = document.createElement("canvas");
  canvas.width = tagProp.width * 2;
  canvas.height = tagProp.height * 2;
  const ctx = canvas.getContext("2d");

  ctx.fillStyle = track.color || "#ff0000";
  ctx.font = "normal 40px 黑体";

  const contents = tagProp.content.split("\n");
  const lineHeight = 48;
  let y = 42;
  const x = 0;

  // 每次回车换行时会多一个换行符，需要剔除
  let conts = [];
  let lastContIsEmpty = false;
  contents.forEach((cont) => {
    if (cont.trim()) {
      conts.push(cont);
      lastContIsEmpty = false;
    } else {
      if (lastContIsEmpty) return;
      conts.push(cont);
      lastContIsEmpty = true;
    }
  });

  conts.forEach((cont, index) => {
    if (!cont) {
      y += lineHeight;
      return;
    }
    let arrText = cont.split("");
    let line = "";
    for (let n = 0; n < arrText.length; n++) {
      let textLine = line + arrText[n];
      const metrics = ctx.measureText(textLine);
      if (metrics.width > canvas.width && n > 0) {
        ctx.fillText(line, x, y);
        line = arrText[n];
        y += lineHeight;
      } else {
        line = textLine;
      }
    }
    ctx.fillText(line, x, y);
    y += lineHeight;
  });

  return canvas.toDataURL();
};

const computeTopAndLeft = (track: Track | SpecialTag) => {
  const topInsideSlice = track.offsetY - props.dy;
  const leftInsideSlice = track.offsetX - props.dx;
  const topInsideSliceRatio = topInsideSlice / props.sliceImageHeight;
  const leftInsideSliceRatio = leftInsideSlice / props.sliceImageWidth;
  if (
    topInsideSliceRatio < 0 ||
    topInsideSliceRatio > 1 ||
    leftInsideSliceRatio < 0 ||
    leftInsideSliceRatio > 1
  ) {
    /** 解决message提示死循环的问题 */
    void nextTick(() => {
      void message.error("轨迹坐标有误，可能是图片被修改过，请联系管理员！");
    });
  }

  return {
    color: route.path === "/arbitrate" ? "green" : track.color || "red",
    top: topInsideSliceRatio * 100 + "%",
    left: leftInsideSliceRatio * 100 + "%",
    "font-size":
      (store.setting.uiSetting["score.fontSize.scale"] || 1) *
        store.setting.uiSetting["answer.paper.scale"] *
        2.2 +
      "em",
  };
};
const hasMember = (track: any) => {
  return (
    // (store.getMarkStatus === "正评" || store.getMarkStatus === "试评") &&
    store.focusTracks.find((item: any) => {
      return (
        item.mainNumber == track.mainNumber && item.subNumber == track.subNumber
      );
    })
  );
};
const focusedTrack = (track: Track) => {
  return store.focusTracks.includes(track) || hasMember(track);
};
const circleTagClickHandle = (event: MouseEvent) => {
  emit("click-specialtag", event);
};

watch(
  () => store.focusTracks,
  () => {
    if (store.focusTracks.length === 0) return;
    const minImageIndex = Math.min(
      ...store.focusTracks.map((t) => t.offsetIndex)
    );
    const minImageOffsetY = Math.min(
      ...store.focusTracks
        .filter((t) => t.offsetIndex === minImageIndex)
        .map((t) => t.offsetY)
    );
    const topTrack = store.focusTracks.find(
      (t) => t.offsetIndex === minImageIndex && t.offsetY === minImageOffsetY
    );
    if (topTrack) {
      let allHeaderTracks = store.currentTask.questionList
        .map((item: any) => item.headerTrack || [])
        .flat();
      console.log("allHeaderTracks", allHeaderTracks);
      let find = allHeaderTracks.find(
        (item: any) =>
          item.mainNumber == topTrack.mainNumber &&
          item.subNumber == topTrack.subNumber
      );
      document
        .getElementById(
          `a-${topTrack.mainNumber}-${topTrack.subNumber}-${
            find?.offsetY || topTrack.offsetY
          }-${find?.offsetX || topTrack.offsetX}`
        )
        ?.scrollIntoView({ behavior: "smooth" });
    }
  },
  {
    deep: true,
  }
);
</script>

<style scoped>
.score-container {
  position: absolute;
  z-index: 9;
  display: flex;
  align-items: center;
  justify-content: center;
  place-content: center;
  /* color: red; */

  /* to center score */
  width: 200px;
  height: 200px;
  margin-top: -100px;
  margin-left: -100px;
}
.score-container.special-container {
  width: auto;
  height: auto;
  margin-top: 0;
  margin-left: 0;
  max-width: 200px;
  max-height: 200px;
  transform: translate(-50%, -50%);
}
.score-container.no-event {
  /* to click through div */
  pointer-events: none;
}
.score-animation {
  animation: 0.5s ease-in-out 0s infinite alternate change_size;
}

@keyframes change_size {
  from {
    transform: scale(1, 1);
  }
  to {
    transform: scale(2, 2);
  }
}
.track-score-enter-active {
  transition: opacity 0.3s ease;
}
.track-score-leave-active {
  transition: opacity 0.6s ease;
}

.track-score-enter-from,
.track-score-leave-to {
  opacity: 0;
}
</style>
