<template>
  <div class="quiz-container" ref="containerRef">
    <!-- 加载中提示 -->
    <div v-if="isLoading" class="loading">加载中...</div>

    <!-- 当前题目 -->
    <div v-else-if="currentQuestion" class="question-container">
      <h2>题目 {{ questionCount }}</h2>
      <QuestionText :text="currentQuestion.text" :medias="data.medias"/>
      <div class="options">
        <div v-for="(answer, idx) in currentQuestion.answers.slice(1)" :key="idx" class="option">
          <label
              :class="{ 'correct': submitted && idx === correctIndex, 'incorrect': submitted && userAnswer === idx && idx !== correctIndex }">
            <input
                type="radio"
                :value="idx"
                v-model="userAnswer"
                :name="'question'"
                :disabled="submitted"
            />
            <general-renderer :content-input="processMedia(answer, data.medias)"></general-renderer>
          </label>
        </div>
      </div>

      <!-- 提交按钮或下一题按钮 -->
      <button v-if="!submitted" @click="submitAnswer" class="submit-btn">提交答案</button>
      <button v-else @click="nextQuestion" class="next-btn">下一题</button>

      <!-- 答题结果和解析 -->
      <div v-if="submitted" class="result">
        <p v-if="isCorrect" class="correct-text">答对了！</p>
        <p v-else class="incorrect-text">答错了。</p>
        <p>正确答案是：
          <general-renderer :content-input="processMedia(correctAnswerText, data.medias)"></general-renderer>
        </p>
        <div v-if="currentQuestion.explanation" class="explanation">
          <h3>解题思路</h3>
          <general-renderer :content-input="processMedia(currentQuestion.explanation, data.medias)"></general-renderer>
        </div>

        <!-- 类似题目对比 -->
        <div v-if="similarQuestions.length > 0" class="similar-questions">
          <h3>对比其他类似题目</h3>
          <div v-for="(similar, index) in similarQuestions" :key="index" class="similar-question">
            <h4>题目 {{ index + 1 }}</h4>
            <QuestionText :text="similar.text" :medias="data.medias"/>
            <p>正确答案：
              <general-renderer :content-input="processMedia(similar.correctAnswer, data.medias)"></general-renderer>
            </p>
          </div>
        </div>
      </div>
    </div>

    <!-- 进度条 -->
    <div v-if="!isLoading" class="progress-bar">
      <div v-if="progressPercentage"
           class="progress"
           :style="{
          width: `${progressPercentage}%`,
          background: getColor(progressPercentage)
        }"
      >
        {{ progressPercentage.toFixed(1) }}%
      </div>
    </div>
  </div>
</template>

<script setup>
import {reactive, ref, onMounted, computed, onUpdated} from 'vue';
import axios from 'axios';
import QuestionText from './QuestionText.vue';
import GeneralRenderer from "../../../components/GeneralRenderer.vue";
import {useRoute} from 'vue-router'
import swal from "../../../utils/sweetalert.js";
import router from "../../../router/index.js";

const route = useRoute()

// 响应式数据存储 JSON
const data = reactive({
  itemtypes: [],
  texts: [],
  explanations: [],
  gradings: [],
  answerkeys: [],
  answers: [],
  medias: {}
});

// 当前题目、用户答案、状态变量
const containerRef = ref(null);
const currentQuestion = ref(null);
const userAnswer = ref(null);
const submitted = ref(false);
const isCorrect = ref(false);
const correctAnswerText = ref('');
const correctIndex = ref(null);
const isLoading = ref(true);
const questionCount = ref(1); // 当前题目序号
const similarQuestions = ref([]);
const recentResults = ref([]);
const examQuestions = ref([]); // 当前试卷的题目列表
const totalQuestions = ref(0);
// 最近40题的答题记录

// 进度条百分比

const progressPercentage = computed(() => {
  if (recentResults.value.length === 0) return 0;
  const correctCount = recentResults.value.filter(result => result).length;
  return (correctCount / Math.min(recentResults.value.length, totalQuestions.value)) * 100;
});

const initial = async () => {
  const file = route.query.id || 'phy250226';
  try {
    const response = await axios.get(`https://mva-cyber.club/data/file/${file}.json`);
    const jsonData = response.data;
    Object.assign(data, jsonData);
    generateNewExam(); // 初始生成一份试卷
  } catch (error) {
    console.error('加载数据失败:', error);
    swal.tip('error', '数据加载失败，请稍后重试。')
    await router.push('/demos/pod');
  } finally {
    isLoading.value = false;
  }
}

// 加载数据
onMounted(initial);

function getColor(progressPercentage) {
  let r, g, b;

  // 0% 到 100% 渐变，从红色到绿色
  r = Math.floor(200 * (1 - progressPercentage / 100));  // 红色逐渐减少
  g = Math.floor(200 * (progressPercentage / 100));      // 绿色逐渐增加
  b = 0;  // 蓝色始终为0

  // 返回rgb颜色格式
  return `rgb(${r}, ${g}, ${b})`;
}

// 随机选择一道题
function selectRandomQuestion() {
  if (data.texts.length <= 1) return;
  const index = Math.floor(Math.random() * (data.texts.length - 1)) + 1;
  currentQuestion.value = {
    text: data.texts[index],
    answers: data.answers[index],
    answerkeys: data.answerkeys[index],
    explanation: data.explanations[index],
    type: data.itemtypes[index] // 保存题目类型用于查找相似题目
  };
  userAnswer.value = null;
  submitted.value = false;
  similarQuestions.value = [];
}

// 处理媒体标签
function processMedia(text, medias) {
  if (!text) return '';
  const mediaRegex = /<media i(\d+)>/g;
  return text.replace(mediaRegex, (match, id) => {
    const mediaKey = `m${id}`;
    if (medias[mediaKey]) {
      const [type, url, width, height] = medias[mediaKey];
      if (type === 'image') {
        return `<img src="${url}" width="100%" height="auto" alt="Question Image" />`;
      }
    }
    return '';
  });
}

function calculateStringSimilarity(str1, str2) {
  // 处理空字符串或非字符串输入
  if (typeof str1 !== 'string' || typeof str2 !== 'string') {
    return 0;
  }

  // 如果两个字符串完全相同，直接返回100%
  if (str1 === str2) {
    return 100;
  }

  // 获取字符串长度
  const len1 = str1.length;
  const len2 = str2.length;

  // 如果任一字符串为空，返回0%
  if (len1 === 0 || len2 === 0) {
    return 0;
  }

  // 创建二维数组
  const matrix = Array(len2 + 1).fill(null).map(() =>
      Array(len1 + 1).fill(null)
  );

  // 初始化第一行和第一列
  for (let i = 0; i <= len1; i++) {
    matrix[0][i] = i;
  }
  for (let j = 0; j <= len2; j++) {
    matrix[j][0] = j;
  }

  // 填充矩阵
  for (let j = 1; j <= len2; j++) {
    for (let i = 1; i <= len1; i++) {
      const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1;
      matrix[j][i] = Math.min(
          matrix[j][i - 1] + 1, // 删除
          matrix[j - 1][i] + 1, // 插入
          matrix[j - 1][i - 1] + indicator // 替换
      );
    }
  }

  // 计算相似度百分比
  const maxLength = Math.max(len1, len2);
  const levenshteinDistance = matrix[len2][len1];
  const similarity = ((maxLength - levenshteinDistance) / maxLength) * 100;

  // 返回保留两位小数的百分比
  return Number(similarity.toFixed(2));
}

// 生成新试卷
function generateNewExam() {
  if (data.texts.length <= 1) return;

  // 创建所有题目的索引数组并打乱顺序
  const indices = Array.from({length: data.texts.length - 1}, (_, i) => i + 1);
  for (let i = indices.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [indices[i], indices[j]] = [indices[j], indices[i]];
  }

  // 生成试卷题目列表
  examQuestions.value = indices.map(index => ({
    text: data.texts[index],
    answers: data.answers[index],
    answerkeys: data.answerkeys[index],
    explanation: data.explanations[index],
    type: data.itemtypes[index]
  }));

  totalQuestions.value = examQuestions.value.length;
  questionCount.value = 1;
  recentResults.value = [];
  selectCurrentQuestion();
}

// 查找类似题目
function findSimilarQuestions() {
  const currentText = currentQuestion.value.text;
  const similar = [];
  for (let i = 1; i < data.itemtypes.length; i++) {
    if (
        calculateStringSimilarity(data.texts[i], currentText) > 50 && // 相似度
        data.texts[i] !== currentQuestion.value.text// 不是当前题目
        // similar.length < 2 // 最多选 2 道
    ) {
      const correctIdx = data.answerkeys[i].findIndex((key, idx) => idx > 0 && key === 1) - 1;
      similar.push({
        text: data.texts[i],
        correctAnswer: data.answers[i][correctIdx + 1]
      });
    }
  }
  similarQuestions.value = similar;
}

function selectCurrentQuestion() {
  if (questionCount.value <= totalQuestions.value) {
    currentQuestion.value = examQuestions.value[questionCount.value - 1];
    userAnswer.value = null;
    submitted.value = false;
    similarQuestions.value = [];
  }
}

// 提交答案
function submitAnswer() {
  if (userAnswer.value === null) {
    swal.tip('info', '必须选一个')
    return;
  }
  correctIndex.value = currentQuestion.value.answerkeys.findIndex((key, idx) => idx > 0 && key === 1) - 1;
  isCorrect.value = userAnswer.value === correctIndex.value;
  containerRef.value.style.border = `
    ${isCorrect.value ? '#00c800' : '#c80000'} solid 5px`;
  setTimeout(() => {
    containerRef.value.style.border = 'rgba(126, 126, 126, 0) solid 5px';
  }, 1000)
  correctAnswerText.value = currentQuestion.value.answers[correctIndex.value + 1];
  submitted.value = true;

  // 更新最近40题记录
  recentResults.value.push(isCorrect.value);
  if (recentResults.value.length > 40) {
    recentResults.value.shift();
  }

  // 查找类似题目
  findSimilarQuestions();
}

// 下一题
function nextQuestion() {
  if (questionCount.value < totalQuestions.value) {
    questionCount.value++;
    selectCurrentQuestion();
  } else {
    swal.tip('success', '所有题目已完成！将生成新试卷。')
    generateNewExam(); // 完成当前试卷后生成新试卷
  }
}
</script>

<style scoped>
.quiz-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  width: calc(100% - 49px);
  //max-width: 800px;
  margin: auto;
  height: calc(100vh - 109px);
  overflow-y: auto;
  padding: 20px;
  font-family: Arial, sans-serif;
}

.loading {
  text-align: center;
  font-size: 18px;
  color: #666;
}

.question-container {
  margin-bottom: 20px;
  max-width: 800px;
}

.progress-bar {
  width: calc(100% - 100px);
  height: 20px;
  background-color: rgba(126, 126, 126, 0.23);
  margin-top: 20px;
  border-radius: 10px;
  overflow: hidden;
  position: fixed;
  bottom: 20px;
}

.progress {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: bold;
  transition: width 0.5s ease;
}

.options {
  margin-top: 20px;
}

.option {
  margin: 10px 0;

}

.option label {
  display: flex;
  flex-direction: row;
  align-items: center;
  cursor: pointer;
  padding: 10px 0;
}

.option input {
  margin-right: 10px;
}

.option label.correct {
  color: green;
  font-weight: bold;
}

.option label.incorrect {
  color: red;
}

.submit-btn,
.next-btn {
  margin-top: 20px;
  padding: 10px 20px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

.submit-btn:hover,
.next-btn:hover {
  background-color: #0056b3;
}

.result {
  margin-top: 20px;
  padding: 15px;
  border-top: 1px solid #ddd;
}

.correct-text {
  color: green;
  margin: 10px 0;
}

.incorrect-text {
  color: red;
  margin: 10px 0;
}

.explanation {
  margin-top: 20px;
}

.explanation h3 {
  margin-bottom: 10px;
}

.similar-questions {
  margin-top: 20px;
  padding: 15px;
  border-top: 1px dashed #ddd;
}

.similar-question {
  margin-bottom: 15px;
}

.similar-question h4 {
  margin-bottom: 10px;
}
</style>