<template>
  <a-modal
    v-model:open="visible"
    width="100%"
    :footer="false"
    :closable="false"
    :mask="false"
    :maskClosable="false"
    :keyboard="false"
    wrapClassName="recog-edit-dialog"
    :afterClose="afterClose"
  >
    <div class="recog-edit">
      <div class="recog-row">
        <div class="recog-col is-static is-col1">
          <div class="modal-box">
            <p class="box-title">{{ recogTitle }}</p>
            <p class="box-cont">{{ recogTitleDesc }}</p>
          </div>
        </div>
        <div class="recog-col is-grow">
          <div class="modal-box modal-origin">
            <div class="modal-origin-body" :style="areaImgStyle">
              <img
                v-if="recogData.areaImg"
                ref="areaImgRef"
                :src="recogData.areaImg"
                alt="截图"
                @load="areaImgLoad"
              />
              <div
                v-for="(option, index) in recogData.options.slice(1)"
                :key="option"
                class="select-option"
                :style="getOptionStyle(index)"
                @click="selectOption(option)"
              >
                {{ option }}
              </div>
            </div>
          </div>
        </div>
        <div class="recog-col is-static is-col1">
          <div class="modal-box is-btn" @click="close">
            <p class="box-title">Esc键</p>
            <p class="box-cont">关闭</p>
          </div>
        </div>
      </div>
      <div class="recog-row">
        <div class="recog-col is-static is-col1">
          <div class="modal-box">
            <p class="box-title">识别结果</p>
            <p class="box-cont">{{ recogResult }}</p>
          </div>
        </div>
        <div class="recog-col is-grow">
          <div class="modal-box modal-options">
            <a-button
              v-for="option in recogData.options"
              :key="option"
              :type="selectResult.includes(option) ? 'primary' : 'default'"
              @click="selectOption(option)"
              >{{ recogResultTransform(option) }}</a-button
            >
          </div>
        </div>
        <div class="recog-col is-static is-col1">
          <div class="modal-box is-btn" @click="onConfirm">
            <p class="box-title">Enter键</p>
            <p class="box-cont">保存</p>
          </div>
        </div>
      </div>
    </div>
  </a-modal>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from "vue";
import { message } from "ant-design-vue";
import useModal from "@/hooks/useModal";
import { RecogBlock } from "@/utils/recog/recog";
import { getBoxImageSize, recogResultTransform } from "@/utils/tool";
import { useUserStore, useDataCheckStore } from "@/store";
import { debounce } from "lodash-es";

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

/* modal */
const { visible, open, close } = useModal();
defineExpose({ open, close });

const props = defineProps<{
  recogData: RecogBlock;
}>();

const emit = defineEmits(["confirm", "close"]);
const userStore = useUserStore();
const dataCheckStore = useDataCheckStore();

const selectResult = ref([] as string[]);

const titles = {
  question: "客观题",
  absent: "缺考",
  breach: "违纪",
  paperType: "卷型号",
};
const recogTitle = computed(() => {
  return titles[props.recogData.type];
});

const recogTitleDesc = computed(() => {
  if (props.recogData.type === "question") {
    return `#${props.recogData.index + 25}`;
  }
  return "--";
});

const recogResult = computed(() => {
  if (props.recogData.type === "question") {
    return props.recogData.result.join("");
  }
  return "";
});

function getOptionStyle(index: number): Record<string, any> {
  const optionSize = props.recogData.optionSizes[index];
  const option = props.recogData.options[index + 1];
  const borderColor = selectResult.value.includes(option)
    ? userStore.recogFillSet.fillColor
    : userStore.recogFillSet.unfillColor;
  return {
    width: `${optionSize.w}px`,
    height: `${optionSize.h}px`,
    fontSize: `${optionSize.h * 0.8}px`,
    fontWeight: "bold",
    color: borderColor,
    left: `${optionSize.x}px`,
    top: `${optionSize.y}px`,
    borderColor,
  };
}

const areaImgRef = ref();
const areaImgStyle = ref({});
function areaImgLoad() {
  const areaImgDom = areaImgRef.value as HTMLImageElement;
  const boxDom = areaImgDom.parentNode?.parentNode as HTMLDivElement;
  const recogDpi = dataCheckStore.curPage.recogDpi || 150;
  const scaleRate = (1.5 * 150) / recogDpi;

  const imgSize = getBoxImageSize({
    box: {
      width: boxDom.offsetWidth - 22,
      height: boxDom.offsetHeight - 22,
    },
    img: {
      width: areaImgDom.naturalWidth * scaleRate,
      height: areaImgDom.naturalHeight * scaleRate,
    },
    rotate: 0,
  });
  const rate = imgSize.width / areaImgDom.naturalWidth;
  areaImgStyle.value = {
    width: `${areaImgDom.naturalWidth}px`,
    height: `${areaImgDom.naturalHeight}px`,
    transform: `scale(${rate}) translate(-50%, -50%)`,
  };
}

function selectOption(option: string) {
  if (!props.recogData) return;

  // 单选直接赋值
  if (!props.recogData.multiple) {
    selectResult.value = [option];
    return;
  }

  // 多选情况
  // 空直接赋值，空值与其他互斥
  if (option === "#") {
    selectResult.value = ["#"];
    return;
  }

  let result = selectResult.value.filter((item) => item !== "#");
  if (result.includes(option)) {
    result = result.filter((item) => item !== option);
  } else {
    result.push(option);
  }
  // 保证result的顺序和options的顺序是一致的
  selectResult.value = props.recogData.options.filter((item) =>
    result.includes(item)
  );
}

// save
const onConfirm = debounce(save, 300);
function save() {
  // console.log(`save:${Date.now()}`);

  if (!selectResult.value.length) {
    message.error("请选择答案");
    return;
  }

  emit("confirm", selectResult.value);
  close();
}
// 键盘事件
function registKeyEvent() {
  document.addEventListener("keydown", keyEventHandle);
}
function removeKeyEvent() {
  document.removeEventListener("keydown", keyEventHandle);
}

function keyEventHandle(e: KeyboardEvent) {
  if (e.repeat) return;

  if (e.keyCode == 13) {
    e.preventDefault();
    onConfirm();
    return;
  } else if (e.code === "Escape") {
    e.preventDefault();
    close();
    return;
  }
}

function afterClose() {
  emit("close");
}
// init
watch(
  () => visible.value,
  (val) => {
    if (val) {
      modalOpenHandle();
    } else {
      removeKeyEvent();
    }
  },
  {
    immediate: true,
  }
);

watch(
  () => props.recogData,
  (val) => {
    console.log(`props.recogData:${Date.now()}`, val);

    if (!val) return;
    selectResult.value = [...props.recogData.result];
  }
);

async function modalOpenHandle() {
  selectResult.value = [...props.recogData.result];
  await nextTick();
  registKeyEvent();
}
</script>
