<template>
  <div ref="reviewMarkPanRef" class="review-mark-pan" :style="areaStyle">
    <div
      class="pan-head"
      v-ele-move-directive.prevent.stop="{
        moveStart: moveAreaStart,
        moveElement: moveArea,
        moveStop: moveAreaStop,
      }"
    ></div>
    <div class="pan-body">
      <p>{{ taskInfo.examNumber }}</p>
      <p>{{ taskInfo.name }}</p>

      <a-button block @click="onMark">正常 (Enter)</a-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, reactive, onMounted, onBeforeMount } from "vue";
import { vEleMoveDirective } from "@/directives/eleMove";
import { local } from "@/utils/tool";

defineOptions({
  name: "ReviewMarkPan",
});

const props = defineProps<{
  taskInfo: { examNumber: string; name: string };
}>();

const emit = defineEmits(["mark"]);

function onMark() {
  emit("mark", true);
}

// move
const areaSize = reactive({
  left: 200,
  top: 300,
});

const areaStyle = computed(() => {
  return { left: `${areaSize.left}px`, top: `${areaSize.top}px` };
});
let areaOriginSize = {
  left: 40,
  top: 0,
};

interface MovePos {
  left: number;
  top: number;
}
interface MarkPanCacheData {
  left: number;
  top: number;
  limitWidth: number;
  limitHeight: number;
}

const reviewMarkPanRef = ref();
let limitWidth = 0;
let limitHeight = 0;
let panWidth = 0;
let panHeight = 0;

function moveAreaStart() {
  areaOriginSize = { ...areaSize };
  updateStaticSize();
}
function moveArea(pos: MovePos) {
  const areaTop = pos.top + areaOriginSize.top;
  areaSize.top = Math.min(areaTop, limitHeight - panHeight);
  areaSize.top = Math.max(0, areaSize.top);
  const areaLeft = pos.left + areaOriginSize.left;
  areaSize.left = Math.min(areaLeft, limitWidth - panWidth);
  areaSize.left = Math.max(0, areaSize.left);
}

function moveAreaStop(pos: MovePos) {
  moveArea(pos);

  local.set("mark-pan", {
    ...areaSize,
    limitHeight,
    limitWidth,
  });
}

function updateStaticSize() {
  const panDom = reviewMarkPanRef.value as HTMLDivElement;
  if (!panDom) return;
  panWidth = panDom.clientWidth;
  panHeight = panDom.clientHeight;
  const parentDom = panDom.parentElement as HTMLDivElement;
  limitWidth = parentDom.clientWidth;
  limitHeight = parentDom.clientHeight;
}

function initAreaSize() {
  const cacheSize: MarkPanCacheData | null = local.get("mark-pan");
  updateStaticSize();

  if (!cacheSize) {
    areaSize.left = (limitWidth - panWidth) / 2;
    areaSize.top = (limitHeight - panHeight) / 2;
    return;
  }

  const rate = limitWidth / cacheSize.limitWidth;
  const areaLeft = (limitWidth * cacheSize.left) / cacheSize.limitWidth;
  areaSize.left = Math.min(areaLeft, limitWidth - panWidth);
  const areaTop = (limitHeight * cacheSize.top) / cacheSize.limitHeight;
  areaSize.top = Math.min(areaTop, limitHeight - panHeight);
}

// 键盘事件
function registKeyEvent() {
  window.addEventListener("resize", initAreaSize);
  document.addEventListener("keydown", keyEventHandle);
}
function removeKeyEvent() {
  window.removeEventListener("resize", initAreaSize);
  document.removeEventListener("keydown", keyEventHandle);
}

function keyEventHandle(e: KeyboardEvent) {
  if (e.code === "Enter") {
    e.preventDefault();
    onMark();
    return;
  }
}

onMounted(() => {
  initAreaSize();

  registKeyEvent();
});

onBeforeMount(() => {
  removeKeyEvent();
});
</script>
