<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';

// @ts-ignore
import { Page } from '@vben/common-ui';

// @ts-ignore
import { getAnswerResultList, gradeExam } from '#/api/exam/exam/answer';
// @ts-ignore
import { examPaperDetail } from '#/api/exam/exam/exam';
// @ts-ignore
import { getParticipantById } from '#/api/exam/exam/participant';

const route = useRoute();
const examId = Number(route.params.id || 0);
const pid = Number(route.query.pid || 0);

const participantInfo = ref<any>({});

// 考试信息
const examInfo = ref<any>({});
// 答题信息
const answerInfo = ref<any>([]);
// 批改分数存储
const scoreMap = ref<Record<number, number>>({});

// 显示模式状态，true表示只显示填空题和简答题，false表示显示全部
const showOnlySubjective = ref(false);

onMounted(() => {
  getParticipantById(pid).then((res: any) => {
    participantInfo.value = res || {};
  });
});

// 计算用时
const calculateExamTime = () => {
  if (!participantInfo.value.startTime || !participantInfo.value.submitTime) {
    return '-';
  }
  const startTime = new Date(participantInfo.value.startTime).getTime();
  const submitTime = new Date(participantInfo.value.submitTime).getTime();
  const duration = (submitTime - startTime) / 60_000; // 转换为分钟
  return `${duration.toFixed(2)} 分钟`;
};

// 数据处理工具函数
// 解析JSON字符串，处理异常
const parseJson = (str: string) => {
  if (!str) return [];
  try {
    return JSON.parse(str);
  } catch (error) {
    console.error('解析JSON失败:', error);
    return [];
  }
};

// 根据paperQuestionId获取答题信息
const getAnswerByPaperQuestionId = (paperQuestionId: number) => {
  return (
    answerInfo.value.find(
      (item: any) => item.paperQuestionId === paperQuestionId,
    ) || {}
  );
};

// 获取题目类型中文名称
const getQuestionTypeName = (type: string) => {
  const typeMap: any = {
    single_choice: '单选题',
    multiple_choice: '多选题',
    judgment: '判断题',
    fill_blank: '填空题',
    essay: '简答题',
  };
  return typeMap[type] || type;
};

// 按大题索引分组题目
const getQuestionsByBigIndex = () => {
  if (!examInfo.value?.paper?.questions) return [];

  const grouped: any = {};
  examInfo.value.paper.questions.forEach((question: any) => {
    // 根据显示模式筛选题目
    if (
      showOnlySubjective.value && // 只显示填空题和简答题
      question.questionType !== 'fill_blank' &&
      question.questionType !== 'essay'
    ) {
      return;
    }

    if (!grouped[question.bigQuestionIndex]) {
      grouped[question.bigQuestionIndex] = [];
    }
    grouped[question.bigQuestionIndex].push(question);
  });

  // 转换为数组并按索引排序
  return Object.keys(grouped)
    .sort((a, b) => Number(a) - Number(b))
    .map((key) => grouped[key]);
};

// 分数变化处理
const handleScoreChange = (question: any, value: number | string) => {
  const score = Number(value);
  // 验证分数不能超过小题分值
  if (score > question.smallQuestionScore) {
    scoreMap.value[question.id] = question.smallQuestionScore;
    return;
  }
  // 验证分数不能为负数
  if (score < 0) {
    scoreMap.value[question.id] = 0;
    return;
  }
  // 如果输入为空，设置为undefined，方便后续处理
  if (value === '' || value === null || value === undefined) {
    delete scoreMap.value[question.id];
    return;
  }
  scoreMap.value[question.id] = score;
};

// 获取显示的分数
// const getDisplayScore = (question: any) => {
//   // 如果已经批改过，显示批改的分数
//   if (scoreMap.value[question.id] !== undefined) {
//     return scoreMap.value[question.id];
//   }
//   // 否则显示用户原有的分数，如果没有则显示空
//   const answer = getAnswerByPaperQuestionId(question.id);
//   return answer.userScore || '';
// };

// 计算总分
const totalScore = computed(() => {
  let sum = 0;

  // 遍历所有题目
  if (examInfo.value?.paper?.questions) {
    examInfo.value.paper.questions.forEach((question: any) => {
      // 获取题目分数
      let score = 0;

      // 优先使用修改后的分数
      if (scoreMap.value[question.id] === undefined) {
        // 否则使用原有分数
        const answer = getAnswerByPaperQuestionId(question.id);
        score = answer.userScore || 0;
      } else {
        score = scoreMap.value[question.id] || 0;
      }

      sum += score;
    });
  }

  return sum;
});

// 批改完成处理
const handleCorrectComplete = async () => {
  // 这里实现批改完成的逻辑，例如提交分数到后端
  const params: any = [];

  // 遍历所有修改过分数的题目
  for (const [questionId, userScore] of Object.entries(scoreMap.value)) {
    const paperQuestionId = Number(questionId);
    // 获取对应的答题信息
    const answer = getAnswerByPaperQuestionId(paperQuestionId);

    // 只有在 answerInfo 中存在的数据才允许提交
    if (
      answer &&
      answer.id && // 如果分数有变化，才提交
      answer.userScore !== userScore
    ) {
      params.push({
        id: answer.id,
        participantId: answer.participantId,
        examId: answer.examId,
        userScore,
      });
    }
  }

  // 如果有需要提交的数据，调用 API
  if (params.length > 0) {
    await gradeExam(params);
    // 可以添加成功后的处理逻辑，例如提示用户或刷新数据
  }
};

const init = async () => {
  // 并发请求接口获取数据
  const [examInfoRes, participantRes, answerRes] = await Promise.all([
    examPaperDetail(examId),
    getParticipantById(pid),
    getAnswerResultList({
      examId,
      participantId: pid,
    }),
  ]);
  examInfo.value = examInfoRes || {};
  if (examInfo.value?.paper?.bigQuestionNames) {
    examInfo.value.paper.bigQuestionNames = JSON.parse(
      examInfo.value.paper.bigQuestionNames,
    );
  }
  participantInfo.value = participantRes || {};
  answerInfo.value = answerRes.rows || [];

  // 初始化分数映射，将用户原有的分数填充到scoreMap中
  answerInfo.value.forEach((answer: any) => {
    if (answer.userScore !== undefined && answer.userScore !== null) {
      scoreMap.value[answer.paperQuestionId] = answer.userScore;
    }
  });
};

onMounted(async () => {
  await init();
});
</script>
<template>
  <Page title="待批改">
    <div class="startexamin_box">
      <div class="left">
        <el-button
          style="width: 160px; height: 40px"
          @click="showOnlySubjective = !showOnlySubjective"
        >
          {{
            showOnlySubjective ? '点 击 显 示 全 部' : '点 击 显 示 客 观 题'
          }}
        </el-button>
        <!-- 动态生成大题 -->
        <div
          class="exam_info_left"
          v-for="(bigQuestion, bigIndex) in examInfo?.paper?.bigQuestionNames"
          :key="bigIndex"
        >
          <div class="exam_info_left_title">
            {{ bigQuestion.name }}(本题分值{{ bigQuestion.score }}分)
          </div>
          <!-- 动态生成小题 -->
          <div
            class="exam_info_left_content"
            v-for="(question, questionIndex) in getQuestionsByBigIndex()[
              +bigIndex
            ] || []"
            :key="question.id"
          >
            <div class="exam_info_left_content_title">
              {{ +questionIndex + 1 }}.
              <span v-html="question.info.questionContent"></span>（{{
                getQuestionTypeName(question.questionType)
              }}，{{ question.smallQuestionScore }}分）
            </div>

            <!-- 选项题（单选、多选、判断） -->
            <div
              class="exam_info_left_content_option"
              v-if="
                ['single_choice', 'multiple_choice', 'judgment'].includes(
                  question.questionType,
                )
              "
            >
              <div
                class="exam_info_left_content_option_item"
                v-for="(option, optionIndex) in parseJson(
                  question.info.options,
                )"
                :key="optionIndex"
                :style="{
                  color:
                    getAnswerByPaperQuestionId(question.id).userAnswer &&
                    parseJson(
                      getAnswerByPaperQuestionId(question.id).userAnswer,
                    ).includes(optionIndex)
                      ? getAnswerByPaperQuestionId(question.id).isCorrect === 1
                        ? '#38b865'
                        : '#eb5e12'
                      : '#31373d',
                }"
              >
                <span>
                  {{ String.fromCharCode(65 + +optionIndex) }}.
                  <span v-html="option"></span>
                </span>
                <!-- 显示正确/错误图标 -->
                <el-icon
                  v-if="
                    getAnswerByPaperQuestionId(question.id).userAnswer &&
                    parseJson(
                      getAnswerByPaperQuestionId(question.id).userAnswer,
                    ).includes(optionIndex)
                  "
                >
                  <CircleCheckFilled
                    v-if="
                      getAnswerByPaperQuestionId(question.id).isCorrect === 1
                    "
                  />
                  <CircleCloseFilled v-else />
                </el-icon>
              </div>
            </div>

            <!-- 填空题 -->
            <div
              class="exam_info_left_content_option"
              v-else-if="question.questionType === 'fill_blank'"
            >
              <div class="exam_info_left_content_option_item">
                <span>用户答案：</span>
                <span
                  :style="{
                    color:
                      getAnswerByPaperQuestionId(question.id).isCorrect === 1
                        ? '#38b865'
                        : '#eb5e12',
                    marginLeft: '10px',
                  }"
                >
                  <span
                    v-html="
                      parseJson(
                        getAnswerByPaperQuestionId(question.id).userAnswer ||
                          '[]',
                      ).join('、')
                    "
                  ></span>
                </span>
              </div>
            </div>

            <!-- 简答题 -->
            <div
              class="exam_info_left_content_option"
              v-else-if="question.questionType === 'essay'"
            >
              <div class="exam_info_left_content_option_item">
                <span>用户答案：</span>
              </div>
              <div
                class="exam_info_left_content_option_item"
                :style="{
                  color:
                    getAnswerByPaperQuestionId(question.id).isCorrect === 1
                      ? '#38b865'
                      : '#eb5e12',
                  marginLeft: '20px',
                  marginTop: '10px',
                }"
              >
                <span
                  v-html="
                    getAnswerByPaperQuestionId(question.id).userAnswer ||
                    '未作答'
                  "
                ></span>
              </div>
            </div>

            <!-- 答案解析 -->
            <div class="exam_info_left_content_answer">
              <!-- 正确答案（简答题不显示） -->
              <div
                class="exam_info_left_content_answer_title"
                v-if="question.questionType !== 'essay'"
              >
                正确答案：
                <span
                  v-if="
                    ['single_choice', 'multiple_choice', 'judgment'].includes(
                      question.questionType,
                    )
                  "
                >
                  <span
                    v-html="
                      parseJson(question.info.correctAnswer || '[]')
                        .map((idx: number) => String.fromCharCode(65 + idx))
                        .join(',')
                    "
                  ></span>
                </span>
                <span v-else-if="question.questionType === 'fill_blank'">
                  <span
                    v-html="
                      parseJson(question.info.correctAnswer || '[]').join('、')
                    "
                  ></span>
                </span>
                <span v-else>
                  <span v-html="question.info.correctAnswer || '无'"></span>
                </span>
              </div>
              <div class="exam_info_left_content_answer_desc">
                答案解析：
                <span class="exam_info_left_content_answer_content">
                  <span
                    v-html="question.info.answerAnalysis || '暂无解析'"
                  ></span>
                </span>
              </div>
              <div class="exam_info_left_content_answer">
                <div class="exam_info_left_content_answer_title">
                  本题总分：{{ question.smallQuestionScore }}分
                </div>
                <div class="exam_info_left_content_answer_desc">阅卷得分：</div>
                <div class="exam_info_left_content_answer_content">
                  <el-input
                    placeholder="0"
                    v-model="scoreMap[question.id]"
                    @input="(value) => handleScoreChange(question, value)"
                    type="number"
                    :min="0"
                    :max="question.smallQuestionScore"
                    :disabled="
                      !getAnswerByPaperQuestionId(question.id) ||
                      !getAnswerByPaperQuestionId(question.id).userAnswer ||
                      getAnswerByPaperQuestionId(question.id).userAnswer === ''
                    "
                  />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="rigth">
        <div class="exam_info_right_top">
          <div class="exam_info_right_top_title">{{ examInfo.examName }}</div>
          <div class="exam_info_right_top_content">
            <div>考试姓名：{{ participantInfo.userName || '未知' }}</div>
            <div>试卷总分：{{ examInfo.totalScore }}分</div>
            <div>及格分数：{{ examInfo.passScore }}分</div>
            <div>考生得分：{{ totalScore }}分</div>
            <div>考试用时：{{ calculateExamTime() }}</div>

            <el-button
              style="
                width: 160px;
                height: 40px;
                background-color: #215acd;
                margin: 0 auto;
              "
              type="primary"
              @click="handleCorrectComplete"
            >
              批 改 完 成
            </el-button>
          </div>
        </div>
        <div class="exam_info_right_main">
          <div
            class="rigth_main_content"
            v-for="(bigQuestion, bigIndex) in examInfo?.paper?.bigQuestionNames"
            :key="bigIndex"
          >
            <div class="rigth_main_content_title">
              <text>{{ bigQuestion.name }}</text>
              <text>
                总{{ getQuestionsByBigIndex()[+bigIndex]?.length || 0 }}题/共
                {{ bigQuestion.score }} 分
              </text>
            </div>
            <div class="rigth_main_content_item">
              <div
                v-for="(question, questionIndex) in getQuestionsByBigIndex()[
                  +bigIndex
                ] || []"
                class="rigth_main_content_items"
                :key="question.id"
                :style="{
                  backgroundColor:
                    getAnswerByPaperQuestionId(question.id).isCorrect === 1
                      ? '#38b865'
                      : getAnswerByPaperQuestionId(question.id).isCorrect === 0
                        ? '#eb5e12'
                        : getAnswerByPaperQuestionId(question.id).userAnswer
                          ? '#215acd'
                          : '#d4d6d9',
                }"
              >
                {{ +questionIndex + 1 }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </Page>
</template>
<style lang="scss" scoped>
.startexamin_box {
  width: 100%;
  height: 730px;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  overflow: hidden;
  .left {
    flex: 1;
    // height: 730px;
    // border: 1px solid red;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 12px;
    box-sizing: border-box;
    padding: 24px 24px 0 24px;
    background-color: #fff;
    .exam_info_left {
      display: flex;
      flex-direction: column;
      gap: 12px;
      //       border: 1px solid red;
      .exam_info_left_title {
        width: 100%;
        height: 80px;
        background-color: #f7f9fa;
        font-size: 18px;
        font-weight: 500;
        line-height: 80px;
        box-sizing: border-box;
        padding-left: 24px;
        padding-right: 24px;
        color: #31373d;
      }
      .exam_info_left_content {
        box-sizing: border-box;
        padding: 24px 24px 0 24px;
        background-color: #f7f9fa;
        font-size: 20px;
        font-weight: 400;
        color: #31373d;
        .exam_info_left_content_title {
          margin-bottom: 24px;
          display: flex;
          align-items: center;
          flex-wrap: wrap;
          span {
            display: inline;
            p {
              display: inline;
              margin: 0;
            }
          }
        }
        .exam_info_left_content_option {
          display: flex;
          flex-direction: column;
          gap: 12px;
          .exam_info_left_content_option_item {
            display: flex;
            align-items: flex-start;
            font-size: 18px;
            font-weight: 400;
            color: #31373d;
            width: 100%;
            > span {
              display: flex;
              align-items: flex-start;
              gap: 5px;
              width: 100%;
              &:first-child {
                width: auto;
              }
              p {
                display: inline;
                margin: 0;
                vertical-align: top;
              }
            }
          }
        }
        .exam_info_left_content_answer {
          width: 100%;
          border-top: 1px solid #e6e8eb;
          display: flex;
          flex-direction: column;
          gap: 12px;
          box-sizing: border-box;
          padding-top: 24px;
          padding-bottom: 24px;
          //   margin-top: 24px;
          .exam_info_left_content_answer_title,
          .exam_info_left_content_answer_desc {
            font-size: 18px;
            font-weight: 500;
            color: #31373d;
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            span {
              display: inline;
              p {
                display: inline;
                margin: 0;
              }
            }
            .exam_info_left_content_answer_content {
              margin-left: 8px;
              font-size: 16px;
              font-weight: 400;
              color: #4e5969;
              span {
                display: inline;
                p {
                  display: inline;
                  margin: 0;
                }
              }
            }
          }
        }
      }
    }
  }
  .rigth {
    width: 400px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    // border: 1px solid red;

    .exam_info_right_top {
      background-color: #ffffff;
      width: 100%;
      //       height: 332px;
      padding: 24px;
      box-sizing: border-box;
      .exam_info_right_top_title {
        font-size: 18px;
        font-weight: 500;
        color: #31373d;
        margin-bottom: 28px;
      }
      .exam_info_right_top_content {
        display: flex;
        flex-direction: column;
        gap: 24px;
        font-size: 16px;
        font-weight: 500;
        color: #31373d;
      }
    }
    .exam_info_right_main {
      flex: 1;
      background-color: #ffffff;
      box-sizing: border-box;
      padding: 16px 24px;
      display: flex;
      flex-direction: column;
      gap: 28px;
      //   height: 384px;
      //   border: 1px solid red;
      overflow-y: auto;
      .rigth_main_content {
        display: flex;
        flex-direction: column;
        gap: 12px;
        .rigth_main_content_title {
          //   height: 48px;
          display: flex;
          justify-content: space-between;
          align-items: center;
          font-size: 16px;
          font-weight: 500;
        }
        .rigth_main_content_item {
          display: flex;
          flex-wrap: wrap;
          gap: 12px;
          .rigth_main_content_items {
            width: 40px;
            height: 40px;
            border-radius: 4px;
            background-color: #38b865;
            display: flex;
            justify-content: center;
            align-items: center;
            color: #ffffff;
            font-size: 14px;
            font-weight: 400;
            border: 1px solid #d4d6d9;
          }
          .selectedactive {
            background-color: #e2eaf6;
          }
          .answered {
            background-color: #215acd;
            color: white;
          }
          .selectedactive.answered {
            background-color: #215acd;
            color: white;
          }
        }
      }
    }
  }
}
</style>
