<template>
  <div class="arbitrate">
    <div class="arbitrate-title">
      <a-button class="arbitrate-back" @click="goback">
        <template #icon><SwapLeftOutlined /> </template>后退
      </a-button>
      <div class="arbitrate-stat">
        <p class="color-success">
          <CheckCircleFilled />已处理：{{ progress.finishCount }}
        </p>
        <p class="color-error">
          <CloseCircleFilled />未处理：{{ progress.todoCount }}
        </p>
      </div>
    </div>

    <div class="arbitrate-body">
      <RecognizeImage
        v-if="curArbitrateTaskDetail"
        :img-src="curArbitrateTaskDetail.uri"
      />

      <!-- arbitrate action modal -->
      <div v-if="curArbitrateTaskDetail" class="arbitrate-modal">
        <a-row align="top" :gutter="8" class="m-b-8px">
          <a-col :span="6">
            <div class="modal-box">
              <p class="box-title">客观题</p>
              <p class="box-cont">{{ curTaskDetailName }}</p>
            </div>
          </a-col>
          <a-col :span="12">
            <div class="modal-box modal-origin"></div>
          </a-col>
          <a-col :span="6">
            <div class="modal-box" @click="changePrevTaskDetail">
              <p class="box-title">左键</p>
              <p class="box-cont">上一个</p>
            </div>
          </a-col>
        </a-row>
        <a-row align="top" :gutter="8">
          <a-col :span="3">
            <div class="modal-box">
              <p class="box-title">一评结果</p>
              <p class="box-cont">{{ curArbitrateTaskDetail.result1 }}</p>
            </div>
          </a-col>
          <a-col :span="3">
            <div class="modal-box">
              <p class="box-title">二评结果</p>
              <p class="box-cont">{{ curArbitrateTaskDetail.result2 }}</p>
            </div>
          </a-col>
          <a-col :span="12">
            <div class="modal-box modal-options">
              <a-button
                v-for="option in curArbitrateTaskDetail.options"
                :key="option"
                :type="
                  curArbitrateTaskDetail.value.result.includes(option)
                    ? 'primary'
                    : 'default'
                "
                @click="selectOption(option)"
                >{{ option }}</a-button
              >
            </div>
          </a-col>
          <a-col :span="6">
            <div class="modal-box">
              <p class="box-title">Enter键</p>
              <p class="box-cont">下一个</p>
            </div>
          </a-col>
        </a-row>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  computed,
  ref,
  reactive,
  onMounted,
  onBeforeUnmount,
  nextTick,
} from "vue";
import { useRoute, useRouter } from "vue-router";
import {
  CheckCircleFilled,
  CloseCircleFilled,
  SwapLeftOutlined,
} from "@ant-design/icons-vue";
import { message } from "ant-design-vue";

import RecognizeImage from "./RecognizeImage.vue";

import {
  recognizeArbitrateTask,
  recognizeArbitrateSave,
  recognizeArbitrateProgress,
  recognizeArbitrateHistory,
} from "@/ap/recognizeCheck";
import {
  RecognizeArbitrateItem,
  RecognizeArbitrateTaskDetail,
  RecognizeArbitrateSavePage,
} from "@/ap/types/recognizeCheck";
import { parseRecogData, parseDetailSize } from "@/utils/recog/recog";

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

const router = useRouter();
const route = useRoute();
const groupId = route.params.groupId ? Number(route.params.groupId) : 0;

// 任务进度
const progress = ref({
  finishCount: 0,
  todoCount: 0,
});
async function updateProgress() {
  const res = await recognizeArbitrateProgress(groupId);
  progress.value = res || {};
}

const curArbitrateTaskDetails = ref([] as RecognizeArbitrateTaskDetail[]);
const curArbitrateTaskDetailIndex = ref(0);
const curArbitrateTaskDetail = ref<RecognizeArbitrateTaskDetail | null>(null);

const nextArbitrateTaskDetail = computed(() => {
  return curArbitrateTaskDetails.value[curArbitrateTaskDetailIndex.value + 1];
});
// 下一个细分任务是否是另一个任务
const nextDetailIsAnotherTask = computed(() => {
  return !nextArbitrateTaskDetail.value;
});

const curTaskDetailName = computed(() => {
  if (!curArbitrateTaskDetail.value) return "";

  if (curArbitrateTaskDetail.value.type === "question") {
    return `#${curArbitrateTaskDetail.value.index}`;
  }
  return "-";
});

// 获取任务
let curTask: RecognizeArbitrateItem | null = null;
async function getTask() {
  const res = await recognizeArbitrateTask(groupId).catch(() => false);
  curTask = res || null;
  if (!curTask) {
    return;
  }

  curArbitrateTaskDetails.value = parseDetails(curTask);
}

async function initData() {
  await getTask();
  curArbitrateTaskDetailIndex.value = 0;
  setCurTaskDetail();
}

// 解析仲裁任务详情
function parseDetails(
  data: RecognizeArbitrateItem
): RecognizeArbitrateTaskDetail[] {
  const details: RecognizeArbitrateTaskDetail[] = [];
  data.pages.forEach((page) => {
    const recogData = parseRecogData(page.recogData);
    if (!recogData) return;

    // 缺考
    if (page.absent) {
      details.push({
        ...parseDetailSize(recogData.absent.fill_result[0], "absent", 0, []),
        result1: page.absent ? page.absent[0] : "",
        result2: page.absent ? page.absent[1] : "",
        pageIndex: page.index,
        groupId: groupId,
        uri: page.uri,
      });
    }

    // 违纪
    if (page.breach) {
      details.push({
        ...parseDetailSize(recogData.breach.fill_result[0], "breach", 0, []),
        result1: page.breach ? page.breach[0] : "",
        result2: page.breach ? page.breach[1] : "",
        pageIndex: page.index,
        groupId: groupId,
        uri: page.uri,
      });
    }

    // 试卷类型
    if (page.paperType) {
      details.push({
        ...parseDetailSize(
          recogData.paperType.fill_result[0],
          "paperType",
          0,
          []
        ),
        result1: page.paperType ? page.paperType[0] : "",
        result2: page.paperType ? page.paperType[1] : "",
        pageIndex: page.index,
        groupId: groupId,
        uri: page.uri,
      });
    }

    // 试题
    let index = 0;
    recogData.question.forEach((gGroup) => {
      gGroup.fill_result.forEach((qRecog) => {
        qRecog.index = ++index;
        const questionResult = page.question[qRecog.index];
        const arbitrate = questionResult && questionResult.length >= 2;
        if (!arbitrate) return;
        details.push({
          ...parseDetailSize(qRecog, "question", qRecog.index, []),
          result1: questionResult ? questionResult[0] : "",
          result2: questionResult ? questionResult[1] : "",
          pageIndex: page.index,
          groupId: groupId,
          uri: page.uri,
        });
      });
    });
  });

  return details;
}

// 任务执行流程 ----------------- start>
function setCurTaskDetail() {
  curArbitrateTaskDetail.value =
    curArbitrateTaskDetails.value[curArbitrateTaskDetailIndex.value];
}
const detailChanging = ref(false);
async function changeNextTaskDetail() {
  if (detailChanging.value) return;
  detailChanging.value = true;

  if (nextDetailIsAnotherTask.value) {
    await submitCurTask().catch(() => {});
    await getNextTask().catch(() => {});
    await nextTick(() => {
      detailChanging.value = false;
    });
    return;
  }

  curArbitrateTaskDetailIndex.value++;
  setCurTaskDetail();
  setTimeout(() => {
    detailChanging.value = false;
  }, 500);
}

async function changePrevTaskDetail() {
  if (detailChanging.value) return;

  if (curArbitrateTaskDetailIndex.value === 0) {
    detailChanging.value = true;
    await getPrevTask().catch(() => {});
    await nextTick(() => {
      detailChanging.value = false;
    });
    return;
  }

  detailChanging.value = true;
  curArbitrateTaskDetailIndex.value--;
  setCurTaskDetail();
  setTimeout(() => {
    detailChanging.value = false;
  }, 500);
}

async function getPrevTask() {
  let result = true;
  const res = await recognizeArbitrateHistory({
    groupId,
    id: curTask?.id,
  }).catch(() => {
    result = false;
  });

  if (!result) {
    message.error("获取上一个任务失败！");
    return;
  }

  if (!res) {
    message.error("没有上一个任务了！");
    return;
  }

  curTask = res;
  curArbitrateTaskDetails.value = parseDetails(curTask);
  curArbitrateTaskDetailIndex.value = curArbitrateTaskDetails.value.length - 1;
  setCurTaskDetail();
}

async function getNextTask() {
  let result = true;
  const res = await recognizeArbitrateHistory({
    groupId,
    id: curTask?.id,
    next: true,
  }).catch(() => {
    result = false;
  });

  if (!result) {
    message.error("获取下一个任务失败！");
    return;
  }

  if (!res) {
    message.error("没有下一个任务了！");
    return;
  }

  curTask = res;
  curArbitrateTaskDetails.value = parseDetails(curTask);

  curArbitrateTaskDetailIndex.value = 0;
  setCurTaskDetail();
}

function selectOption(option: string) {
  if (!curArbitrateTaskDetail.value) return;

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

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

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

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

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

// 保存任务详情信息
async function onConfirm() {
  if (!curArbitrateTaskDetail.value?.result.length) {
    message.error("请完成仲裁结果！");
    return;
  }

  await changeNextTaskDetail();
}

// 提交当前任务仲裁数据
function getTaskTypeResult(
  type: "absent" | "breach" | "paperType",
  pageIndex: number
) {
  const taskDetail = curArbitrateTaskDetails.value.find(
    (item) => item.pageIndex === pageIndex && item.type === type
  );

  const result = taskDetail ? taskDetail.result.join() : null;

  if (type === "paperType") return result;

  return result ? result === "true" : null;
}

async function submitCurTask() {
  if (!curTask) return;
  const curArbitrateTaskDetailQuestionResults: Record<string, string> = {};
  curArbitrateTaskDetails.value.forEach((item) => {
    if (item.type !== "question") return;

    const k = `${item.pageIndex}-${item.index}`;
    curArbitrateTaskDetailQuestionResults[k] = item.result.join("");
  });

  const pages = curTask.pages.map((page) => {
    const absentResult = getTaskTypeResult(
      "absent",
      page.index
    ) as RecognizeArbitrateSavePage["absent"];
    const breachResult = getTaskTypeResult(
      "breach",
      page.index
    ) as RecognizeArbitrateSavePage["breach"];

    const paperTypeResult = getTaskTypeResult(
      "paperType",
      page.index
    ) as RecognizeArbitrateSavePage["paperType"];

    const questionResult: Record<number, string> = {};
    curTaskDetails.value.forEach((item) => {
      if (item.type !== "question") return;

      const k = `${item.pageIndex}-${item.index}`;
      const result = item.arbitrate
        ? curArbitrateTaskDetailQuestionResults[k]
        : item.result.join("");
      questionResult[item.index] = result;
    });

    const npage: RecognizeArbitrateSavePage = {
      index: page.index,
      absent: absentResult,
      breach: breachResult,
      paperType: paperTypeResult,
      question: questionResult,
      selective: null,
    };
    return npage;
  });

  await recognizeArbitrateSave({ id: curTask.id, pages }).catch(() => false);
}

// 任务执行流程 ----------------- end>

// 返回
function goback() {
  router.back();
}

onMounted(() => {
  initData();
  registKeyEvent();
});

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