<template>
  <div class="check-action">
    <a-collapse
      v-model:activeKey="panelKey"
      :bordered="false"
      expandIconPosition="end"
    >
      <a-collapse-panel key="1">
        <template #header><FilterFilled />搜索条件 </template>
        <a-form :label-col="{ style: { width: '76px' } }">
          <a-form-item label="科目">
            <select-course
              v-model:value="searchModel.subjectCode"
              :exam-id="userStore.curExam.id"
              style="width: 150px"
              allow-clear
            ></select-course>
          </a-form-item>
          <a-form-item label="查找条件">
            <a-select
              v-model:value="searchModel.examStatus"
              placeholder="请选择"
              :options="absentCheckOptions"
              allow-clear
            ></a-select>
          </a-form-item>
          <a-form-item label="考号">
            <div class="exam-number">
              <a-textarea
                v-model:value="searchModel.examNumber"
                placeholder="请输入"
                :auto-size="{ minRows: 1, maxRows: 1 }"
              ></a-textarea>
              <div class="number-suffix">{{ examNumberCountCont }}</div>
            </div>
            <a-button
              class="ant-simple m-l-8px"
              type="link"
              @click="onEditExamNumber"
              >查看全部</a-button
            >
          </a-form-item>

          <a-row>
            <a-col :span="15">
              <a-form-item label="姓名">
                <a-input
                  v-model:value="searchModel.name"
                  placeholder="请输入"
                  style="width: 140px"
                ></a-input>
              </a-form-item>
            </a-col>
            <a-col :span="9">
              <a-form-item style="text-align: right">
                <a-button class="m-r-8px" type="primary" @click="onSearch"
                  >查询</a-button
                >
                <a-button @click="onExport">导出</a-button>
              </a-form-item>
            </a-col>
          </a-row>
        </a-form>
      </a-collapse-panel>
      <a-collapse-panel key="2">
        <template #header><PictureFilled />图片类别 </template>

        <a-radio-group v-model:value="imageType" @change="onImageTypeChange">
          <a-radio
            v-for="(item, index) in imageTypeOptions"
            :key="index"
            :value="item.value"
            >{{ item.label }}</a-radio
          >
        </a-radio-group>
      </a-collapse-panel>
      <a-collapse-panel key="3">
        <template #header><IdcardFilled />题卡信息 </template>

        <QuestionPanel
          v-if="dataCheckStore.curStudent && dataCheckStore.curPage"
          v-model:questions="questions"
          :info="questionInfo"
          :simple="isSliceImage"
          @change="onQuestionsChange"
          @exam-status-change="onExamStatusChange"
        />
      </a-collapse-panel>
      <a-collapse-panel key="4">
        <template #header><SettingFilled />缺考数据设置 </template>

        <a-button
          class="m-r-10px"
          type="primary"
          :rotate="90"
          @click="onImport"
        >
          <template #icon><SelectOutlined /></template>导入缺考名单
        </a-button>
        <a-button @click="onReset">
          <template #icon><RedoOutlined :rotate="270" /></template
          >重新生成缺考数据
        </a-button>
      </a-collapse-panel>
    </a-collapse>
  </div>

  <!-- ExportTypeDialog -->
  <ExportTypeDialog ref="exportTypeDialogRef" @confirm="onExportConfirm" />
  <!-- ResetDialog -->
  <ResetDialog ref="resetDialogRef" />
  <!-- ImportTypeDialog -->
  <ImportTypeDialog ref="importTypeDialogRef" />
  <!-- MoreExamNumberDialog -->
  <MoreExamNumberDialog
    ref="moreExamNumberDialogRef"
    :data="searchModel.examNumber"
    @confirm="onExamNumberEdited"
  />
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from "vue";
import {
  FilterFilled,
  PictureFilled,
  IdcardFilled,
  SettingFilled,
  SelectOutlined,
  RedoOutlined,
} from "@ant-design/icons-vue";
import { message } from "ant-design-vue";
import type { DefaultOptionType } from "ant-design-vue/es/vc-select/Select";

import { useUserStore, useDataCheckStore } from "@/store";
import { AbsentCheckListFilter, ImportType } from "@/ap/types/absentCheck";
import { ExamStatus } from "@/ap/types/dataCheck";
import { ReviewExportType } from "@/ap/types/review";

import {
  absentCheckStudentExport,
  absentCheckRoomExport,
  examStatusSave,
} from "@/ap/absentCheck";
import { examNumberFillCount } from "@/ap/base";
import useDictOption from "@/hooks/dictOption";
import useLoading from "@/hooks/useLoading";

import ExportTypeDialog from "../Review/ExportTypeDialog.vue";
import ResetDialog from "./ResetDialog.vue";
import ImportTypeDialog from "./ImportTypeDialog.vue";
import QuestionPanel from "../DataCheck/QuestionPanel.vue";
import MoreExamNumberDialog from "../DataCheck/MoreExamNumberDialog.vue";
import { QuestionInfo } from "../DataCheck/types";
import { getTextAreaRows } from "@/utils";
defineOptions({
  name: "CheckAction",
});

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

const userStore = useUserStore();
const dataCheckStore = useDataCheckStore();

const { optionList: imageTypeOptions } = useDictOption("IMAGE_TYPE");
const panelKey = ref(["1", "2", "3", "4"]);

const absentCheckOptions = ref([] as DefaultOptionType[]);
async function getAbsentCheckOptions() {
  const res = await examNumberFillCount(userStore.curExam.id);
  absentCheckOptions.value = [
    {
      label: "缺考",
      value: "ABSENT",
    },
    {
      label: "正常",
      value: "OK",
    },
    {
      label: "客观题未作答+主观题有作答（待确认）",
      value: "UNCHECK1",
    },
    {
      label: `客观题未作答+主观题未作答+填涂≥${res}+有卷型（待确认）`,
      value: "UNCHECK2",
    },
    {
      label: `交叉对比缺考不一致（待确认）`,
      value: "UNCHECK3",
    },
  ];
}
getAbsentCheckOptions();

// search
const initSearchModel = {
  examId: userStore.curExam.id,
  examNumber: "",
  studentCode: "",
  name: "",
  subjectCode: "",
  examStatus: "",
  status: "SCANNED",
};
const searchModel = reactive<AbsentCheckListFilter>({ ...initSearchModel });
const imageType = ref(dataCheckStore.imageType);

// imageType
const isSliceImage = computed(() => {
  return dataCheckStore.imageType === "SLICE";
});

const examNumberCountCont = computed(() => {
  const examNumbers = (searchModel.examNumber || "")
    .split("\n")
    .filter((item) => item);
  return `${examNumbers.length}/100`;
});

const moreExamNumberDialogRef = ref();
function onEditExamNumber() {
  moreExamNumberDialogRef.value?.open();
}
function onExamNumberEdited(val: string) {
  searchModel.examNumber = val;
}

function onSearch() {
  emit("search", {
    ...searchModel,
    examNumber: (searchModel.examNumber || "")
      .split("\n")
      .filter((item) => item)
      .join(","),
  });
}

function onImageTypeChange() {
  dataCheckStore.setInfo({
    imageType: imageType.value,
  });
}

// question panel
const questionInfo = computed(() => {
  if (!dataCheckStore.curStudent) return {} as QuestionInfo;
  return {
    examNumber: dataCheckStore.curStudent.examNumber,
    name: dataCheckStore.curStudent.name,
    examSite: dataCheckStore.curStudent.examSite,
    seatNumber: dataCheckStore.curStudent.seatNumber,
    paperType: dataCheckStore.curStudent.paperType,
    examStatus: dataCheckStore.curStudent.examStatus as string,
    packageCode: dataCheckStore.curStudent.packageCode as string,
  };
});

const questions = ref([] as string[]);
watch(
  () => dataCheckStore.curPage?.question?.result,
  (val) => {
    if (!val) {
      questions.value = [];
      return;
    }
    questions.value = [...val];
  },
  {
    deep: true,
    immediate: true,
  }
);

async function onQuestionsChange() {
  if (!dataCheckStore.curPage) return;
  dataCheckStore.curPage.question.result = [...questions.value];

  await dataCheckStore
    .updateField({
      field: "QUESTION",
      value: JSON.stringify(dataCheckStore.curPage.question),
    })
    .catch(() => {});
}

async function onExamStatusChange(val: ExamStatus) {
  if (!dataCheckStore.curStudent) return;

  await examStatusSave({ id: dataCheckStore.curStudent.id, examStatus: val });
  dataCheckStore.curStudent.examStatus = val;
}

// 导出
const { loading: downloading, setLoading } = useLoading();
const exportTypeDialogRef = ref();
function onExport() {
  if (downloading.value) return;

  if (!searchModel.subjectCode) {
    message.error("请选择科目");
    return;
  }
  if (!searchModel.examStatus || searchModel.examStatus === "OK") {
    message.error("请选择异常条件");
    return;
  }
  exportTypeDialogRef.value?.open();
}

async function onExportConfirm(type: ReviewExportType) {
  if (downloading.value) return;

  setLoading(true);
  const func =
    type === "STUDENT_CODE" ? absentCheckStudentExport : absentCheckRoomExport;

  const res = await func(searchModel).catch((e: Error) => {
    message.error(e.message || "下载失败，请重新尝试！");
  });
  setLoading(false);

  if (!res) return;
  message.success("导出成功！");
}

// 导入
const importTypeDialogRef = ref();
function onImport() {
  importTypeDialogRef.value?.open();
}

// 重置
const resetDialogRef = ref();
function onReset() {
  resetDialogRef.value?.open();
}

watch(
  () => searchModel.examNumber,
  (val, oldVal) => {
    if (getTextAreaRows(val) > 100) {
      window.$message.error("最多只能输入100行");
      searchModel.examNumber = oldVal;
    }
    if (val.includes(",") || val.includes("，")) {
      let arr = val.split(/[,，]/).filter(Boolean);
      if (arr.length > 100) {
        window.$message.error("输入的考号超过了100个，已自动截取前100条");
        arr = arr.slice(0, 100);
      }
      searchModel.examNumber = arr.join("\n");
    }
  }
);
</script>
