<template>
  <PageShell>
    <div class="evaluation-view-page" v-loading="loading">
      <div class="left-card">
        <div class="card-title">考生信息</div>
        <div class="info-list">
          <div class="info-item"><span>姓名：</span><span>{{ studentName }}</span></div>
          <div class="info-item"><span>报名岗位：</span><span>{{ positionName }}</span></div>
          <div class="info-item"><span>开始时间：</span><span>{{ startTime || '-' }}</span></div>
          <div class="info-item"><span>结束时间：</span><span>{{ commitTime || '-' }}</span></div>
          <div class="info-item"><span>答题时长：</span><span>{{ ansTime || '-' }}</span></div>
        </div>

        <div class="card-title second">答题信息</div>
        <div class="answer-list">
          <div v-for="ab in scores" :key="ab.abilityName" class="answer-item">
            <span>{{ ab.abilityName }}：{{ ab.score }}/{{ ab.totalScore }}</span>
            <el-tag :type="ab.pass ? 'success' : 'danger'">{{ ab.pass ? '通过' : '未通过' }}</el-tag>
          </div>
          <div v-if="!scores.length" class="answer-item" style="color:#999">暂无答题记录</div>
        </div>

        <div class="card-title second">维度分析</div>
        <div v-if="scores.length >= 3" ref="radarChartRef" class="radar-chart"></div>
        <div v-else class="chart-placeholder">维度数据不足，至少需要3项能力</div>

        <div class="footer-btn">
          <el-button @click="handleBack">返回</el-button>
          <el-button type="primary" :loading="exportLoading" @click="handleExport">导出测评</el-button>
        </div>
      </div>

      <div class="right-card">
        <template v-if="questionList.length > 0">
          <div v-for="(item, index) in questionList" :key="item.id" class="question-block">
            <div class="question-head">
              <span>第{{ index + 1 }}题 <el-tag size="small" type="info">{{ item.typeName }}</el-tag></span>
              <div class="question-result">
                <el-tag :type="item.correct ? 'success' : 'danger'">{{ item.correct ? '正确' : '错误' }}</el-tag>
                <span>得分</span>
                <el-input :model-value="String(item.score)" class="score-input" readonly />
              </div>
            </div>
            <div class="question-title" v-html="item.questionTitle"></div>
            <!-- 选择题：显示选项，标记用户选择和正确答案 -->
            <div v-if="item.options && item.options.length > 0" class="question-options">
              <div v-for="option in item.options" :key="option.label" class="question-option" :class="{ 'is-user-answer': item.answer && item.answer.includes(option.label) }">
                <!-- 单选题 -->
                <el-radio v-if="item.typeName === '单选题'" :model-value="item.answer" :label="option.label" disabled>{{ option.label }}.<span v-html="option.text"></span></el-radio>
                <!-- 多选题 -->
                <el-checkbox v-else :model-value="item.answer ? item.answer.includes(option.label) : false" :label="option.label" disabled>{{ option.label }}.<span v-html="option.text"></span></el-checkbox>
                <el-tag v-if="option.correct" size="small" type="success">正确答案</el-tag>
                <el-tag v-if="item.answer && item.answer.includes(option.label) && !option.correct" size="small" type="danger">考生选择</el-tag>
              </div>
            </div>
            <!-- 问答题：显示考生作答 -->
            <div v-if="item.answer && (!item.options || item.options.length === 0)" class="question-user-answer">
              <span>考生作答：</span><span v-html="item.answer"></span>
            </div>
            <!-- 正确答案（问答题） -->
            <div v-if="item.typeName === '问答题' && item.testAnsRight" class="question-right-answer">
              <span>参考答案：</span><span v-html="item.testAnsRight"></span>
            </div>
            <div v-if="item.analysis" class="question-analysis">
              <div>答案解析：</div>
              <div v-html="item.analysis"></div>
            </div>
          </div>
        </template>
        <el-empty v-else description="暂无答题详情数据" />
      </div>
    </div>
  </PageShell>
</template>

<script setup name="EvaluationView" lang="ts">
import { getCurrentInstance, type ComponentInternalInstance, ref, onMounted, nextTick, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import * as echarts from 'echarts';
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import PageShell from '@/components/PageShell/index.vue';
import { getEvaluation, getExamScoreList, getExamPaperQuestions, getExamAnswerList } from '@/api/main/evaluation/index';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const router = useRouter();
const route = useRoute();

const loading = ref(false);
const evaluationId = route.query.evaluationId as string;
const studentId = route.query.studentId as string;
const studentName = ref((route.query.name as string) || '');
const positionName = ref('');
const startTime = ref('');
const commitTime = ref('');
const ansTime = ref('');

const scores = ref<any[]>([]);
const questionList = ref<any[]>([]);
const radarChartRef = ref<HTMLElement | null>(null);
const exportLoading = ref(false);
let radarChart: echarts.ECharts | null = null;

/** 解析接口返回的 msg 字段（JSON 字符串），提取 bizContent */
const parseBizContent = (res: any) => {
  const msgStr = res?.msg;
  if (typeof msgStr !== 'string') return {};
  try {
    const parsed = JSON.parse(msgStr);
    return parsed?.bizContent || parsed || {};
  } catch (e) {
    return {};
  }
};

/** 从 score-list 的 bizContent.rows 中查找指定学生的最新记录 */
const findStudentInScoreList = (bizContent: any, sid: string) => {
  const rows: any[] = bizContent?.rows || [];
  if (!Array.isArray(rows) || !sid) return null;
  // 同一考生可能有多条记录，取最后一条（最新的）
  let result: any = null;
  for (const item of rows) {
    if (String(item.userId) === String(sid)) {
      result = item;
    }
  }
  return result;
};

/** 将 com_ans 中的 key1~key4 转为 A/B/C/D 标签 */
const convertComAnsToLabel = (comAns: string): string => {
  if (!comAns) return '';
  const keyMap: Record<string, string> = { key1: 'A', key2: 'B', key3: 'C', key4: 'D' };
  // com_ans 格式可能是 "key2," 或 "key1,key3," 等
  const keys = comAns.split(',').map((k: string) => k.trim()).filter(Boolean);
  return keys.map((k: string) => keyMap[k] || k).join('');
};

const TYPE_NAME_MAP: Record<number, string> = {
  1: '单选题',
  2: '多选题',
  3: '判断题',
  5: '问答题'
};

/** 从 paper-questions 的 bizContent.rows 中提取题目列表
 *  注意：paper-questions 的 testId 是 "--"，真实的 test_id 在 answer-list 中
 *  所以这里需要用 answer-list 中的信息来确定题目 ID
 */
const extractQuestions = (bizContent: any, ansMap: Map<string, any>) => {
  const rows: any[] = bizContent?.rows || [];
  if (!Array.isArray(rows)) return [];

  // 建立 question 文本 -> answer-map 中 test_id 的映射
  const questionToTestId = new Map<string, string>();
  ansMap.forEach((detail: any, testId: string) => {
    const q = detail.question || '';
    if (q) {
      questionToTestId.set(q, testId);
    }
  });

  const questions: any[] = [];
  let seq = 0;
  rows.forEach((row: any) => {
    const tc = row.testContent || {};
    const qType = Number(tc.type);
    const questionTitle = tc.question || '';
    const analysis = tc.analysis || '';

    // 优先用 answer-list 中的 test_id 匹配
    let questionId = questionToTestId.get(questionTitle);
    if (!questionId) {
      questionId = tc.test_id || row.testId || `q_${seq}`;
    }

    // 构建选项：问答题无选项，单选/多选题从 answer1~answer4 + key1~key4 构建
    const options: { label: string; text: string; correct: boolean }[] = [];
    if (qType === 1 || qType === 2) {
      const answerFields = ['answer1', 'answer2', 'answer3', 'answer4'];
      const keyFields = ['key1', 'key2', 'key3', 'key4'];
      const labels = ['A', 'B', 'C', 'D'];
      for (let i = 0; i < 4; i++) {
        const text = tc[answerFields[i]];
        if (text) {
          options.push({
            label: labels[i],
            text,
            correct: tc[keyFields[i]] === '1'
          });
        }
      }
    }

    questions.push({
      id: questionId,
      questionTitle,
      analysis,
      options,
      type: qType,
      typeName: TYPE_NAME_MAP[qType] || '其他',
      testName: row.testName || ''
    });
    seq++;
  });
  return questions;
};

/** 从 answer-list 的 bizContent.rows 中查找指定学生，并提取其作答信息 */
const extractAnswers = (bizContent: any, sid: string) => {
  const rows: any[] = bizContent?.rows || [];
  if (!Array.isArray(rows) || !sid) return new Map<string, any>();
  const studentRow = rows.find((item: any) => String(item.userId) === String(sid));
  if (!studentRow?.ansAndScore) return new Map<string, any>();

  const ansMap = new Map<string, any>();
  const ansAndScore: any[] = studentRow.ansAndScore;

  for (const group of ansAndScore) {
    if (!Array.isArray(group)) continue;
    for (let i = 1; i < group.length; i++) {
      const entry = group[i];
      if (Array.isArray(entry) && entry.length >= 2) {
        const testId = String(entry[0]);
        const detail = entry[1] || {};
        ansMap.set(testId, detail);
      }
    }
  }
  return ansMap;
};

/** 将题目和作答合并为展示数据 */
const combineQA = (questions: any[], ansMap: Map<string, any>) => {
  return questions.map((q, index) => {
    const ans = ansMap.get(String(q.id));

    let correct = false;
    if (ans) {
      if (ans.is_ok === 'right') correct = true;
    }

    // 用户答案
    let answer = '';
    if (ans) {
      const comAns = ans.com_ans || '';
      if (comAns && (q.type === 1 || q.type === 2)) {
        // 选择题：将 key1~key4 转为 A~D
        answer = convertComAnsToLabel(comAns);
      } else if (comAns) {
        // 问答题：直接使用 HTML 内容
        answer = comAns;
      }
    }

    // 正确答案文本（问答题用）
    const testAnsRight = ans?.test_ans_right || '';

    const options = q.options.map((o: any) => ({ ...o }));

    return {
      id: q.id || `q_${index}`,
      questionTitle: q.questionTitle || '未命名题目',
      correct,
      score: ans?.score ?? 0,
      answer,
      options: options.length > 0 ? options : q.type === 5 ? [] : [{ label: 'A', text: '选项A' }, { label: 'B', text: '选项B' }],
      analysis: q.analysis || '',
      typeName: q.typeName,
      testName: q.testName,
      testAnsRight
    };
  });
};

/** 渲染雷达图 */
const renderRadarChart = () => {
  if (!radarChartRef.value || scores.value.length < 3) return;

  if (!radarChart) {
    radarChart = echarts.init(radarChartRef.value);
  }

  const indicator = scores.value.map((s: any) => ({
    name: s.abilityName,
    max: Number(s.totalScore) || 100
  }));

  const dataValues = scores.value.map((s: any) => Number(s.score) || 0);

  radarChart.setOption({
    tooltip: {
      trigger: 'item'
    },
    radar: {
      indicator,
      radius: '65%',
      name: {
        textStyle: {
          fontSize: 11
        }
      },
      splitArea: {
        areaStyle: {
          color: ['rgba(64,158,255,0.05)', 'rgba(64,158,255,0.1)', 'rgba(64,158,255,0.15)', 'rgba(64,158,255,0.2)']
        }
      }
    },
    series: [{
      type: 'radar',
      data: [{
        value: dataValues,
        name: '得分',
        areaStyle: {
          color: 'rgba(64,158,255,0.2)'
        },
        lineStyle: {
          color: '#409EFF'
        },
        itemStyle: {
          color: '#409EFF'
        }
      }]
    }]
  });
};

const loadData = async () => {
  if (!evaluationId) return;
  loading.value = true;
  try {
    const res = await getEvaluation(evaluationId);
    const evalData = res.data;
    positionName.value = evalData.positionName || evalData.position || '未知岗位';

    const abilityConfigs = evalData.abilityConfigs || [];
    let allQuestions: any[] = [];
    let scoreItems: any[] = [];

    for (const ability of abilityConfigs) {
      const examId = ability.thirdExamInfoId;
      if (!examId) continue;

      // 获取成绩列表
      const scoreRes = await getExamScoreList({ examInfoId: examId, page: 1 }).catch(() => ({ msg: '{}' }));
      const scoreBiz = parseBizContent(scoreRes);
      const myScoreObj = findStudentInScoreList(scoreBiz, studentId);

      const score = myScoreObj?.score || 0;
      const passMark = ability.thirdExamPassMark || ability.passingScore || 0;
      const pass = myScoreObj ? String(myScoreObj.isPass) === '1' : Number(score) >= Number(passMark);

      // 取考生时间信息（只需取第一次有数据的记录）
      if (myScoreObj && !startTime.value) {
        startTime.value = myScoreObj.startTime || '';
        commitTime.value = myScoreObj.commitTime || '';
        ansTime.value = myScoreObj.ansTime || '';
      }

      scoreItems.push({
        abilityName: ability.abilityName || ability.thirdExamName || '考核',
        score: score,
        totalScore: ability.thirdExamTotalScore || ability.score || 100,
        pass
      });

      // 获取答题详情（先获取，因为需要用 test_id 来匹配 paper-questions）
      const answerRes = await getExamAnswerList({ examInfoId: examId }).catch(() => ({ msg: '{}' }));
      const answerBiz = parseBizContent(answerRes);
      const ansMap = extractAnswers(answerBiz, studentId);

      // 获取试卷题目
      const paperRes = await getExamPaperQuestions({ examInfoId: examId }).catch(() => ({ msg: '{}' }));
      const paperBiz = parseBizContent(paperRes);
      const questions = extractQuestions(paperBiz, ansMap);

      allQuestions.push(...combineQA(questions, ansMap));
    }

    scores.value = scoreItems;
    questionList.value = allQuestions;

    // 渲染雷达图
    await nextTick();
    renderRadarChart();

  } catch (e) {
    console.error(e);
    proxy?.$modal?.msgError('获取测评数据失败');
  } finally {
    loading.value = false;
  }
};

const handleExport = async () => {
  if (exportLoading.value) return;
  exportLoading.value = true;
  try {
    const container = document.createElement('div');
    container.style.cssText = 'position:fixed;left:-9999px;top:0;width:794px;background:#fff;padding:40px;font-family:"Microsoft YaHei",sans-serif;font-size:14px;color:#333;line-height:1.6;';

    const title = document.createElement('h2');
    title.style.cssText = 'text-align:center;margin-bottom:24px;font-size:20px;';
    title.textContent = `测评报告 - ${positionName.value || '未知岗位'}`;
    container.appendChild(title);

    const infoSection = document.createElement('div');
    infoSection.style.cssText = 'margin-bottom:20px;padding:16px;border:1px solid #e4e7ed;border-radius:6px;';
    infoSection.innerHTML = `
      <div style="font-size:16px;font-weight:600;margin-bottom:10px;">考生信息</div>
      <div style="display:grid;grid-template-columns:1fr 1fr;gap:6px;font-size:13px;">
        <div><strong>姓名：</strong>${studentName.value || '-'}</div>
        <div><strong>报名岗位：</strong>${positionName.value || '未知岗位'}</div>
        <div><strong>开始时间：</strong>${startTime.value || '-'}</div>
        <div><strong>结束时间：</strong>${commitTime.value || '-'}</div>
        <div><strong>答题时长：</strong>${ansTime.value || '-'}</div>
      </div>
    `;
    container.appendChild(infoSection);

    if (scores.value.length > 0) {
      const scoreSection = document.createElement('div');
      scoreSection.style.cssText = 'margin-bottom:20px;padding:16px;border:1px solid #e4e7ed;border-radius:6px;';
      let scoreHtml = '<div style="font-size:16px;font-weight:600;margin-bottom:10px;">答题信息</div>';
      scoreHtml += '<table style="width:100%;border-collapse:collapse;font-size:13px;">';
      scoreHtml += '<tr style="background:#f5f7fa;"><th style="border:1px solid #e4e7ed;padding:8px;text-align:left;">能力项</th><th style="border:1px solid #e4e7ed;padding:8px;text-align:center;">得分</th><th style="border:1px solid #e4e7ed;padding:8px;text-align:center;">满分</th><th style="border:1px solid #e4e7ed;padding:8px;text-align:center;">结果</th></tr>';
      scores.value.forEach((s: any) => {
        const passColor = s.pass ? '#67c23a' : '#f56c6c';
        const passText = s.pass ? '通过' : '未通过';
        scoreHtml += `<tr><td style="border:1px solid #e4e7ed;padding:8px;">${s.abilityName}</td><td style="border:1px solid #e4e7ed;padding:8px;text-align:center;">${s.score}</td><td style="border:1px solid #e4e7ed;padding:8px;text-align:center;">${s.totalScore}</td><td style="border:1px solid #e4e7ed;padding:8px;text-align:center;color:${passColor};font-weight:600;">${passText}</td></tr>`;
      });
      scoreHtml += '</table>';
      scoreSection.innerHTML = scoreHtml;
      container.appendChild(scoreSection);
    }

    if (questionList.value.length > 0) {
      const qSection = document.createElement('div');
      qSection.style.cssText = 'padding:16px;border:1px solid #e4e7ed;border-radius:6px;';
      let qHtml = '<div style="font-size:16px;font-weight:600;margin-bottom:10px;">答题详情</div>';
      questionList.value.forEach((item: any, index: number) => {
        const resultColor = item.correct ? '#67c23a' : '#f56c6c';
        const resultText = item.correct ? '正确' : '错误';
        qHtml += `<div style="margin-bottom:16px;padding-bottom:12px;border-bottom:1px dashed #ebeef5;">`;
        qHtml += `<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">`;
        qHtml += `<span>第${index + 1}题 <span style="background:#f0f2f5;color:#909399;padding:2px 6px;border-radius:3px;font-size:12px;">${item.typeName}</span></span>`;
        qHtml += `<span><span style="color:${resultColor};font-weight:600;">${resultText}</span> | 得分：${item.score}</span>`;
        qHtml += `</div>`;
        const plainTitle = item.questionTitle?.replace(/<[^>]*>/g, '') || '未命名题目';
        qHtml += `<div style="margin-bottom:8px;">${plainTitle}</div>`;
        if (item.options && item.options.length > 0) {
          item.options.forEach((opt: any) => {
            const isCorrect = opt.correct;
            const isUserAnswer = item.answer && item.answer.includes(opt.label);
            let optStyle = 'padding:2px 0;';
            if (isCorrect) optStyle += 'color:#67c23a;font-weight:600;';
            if (isUserAnswer && !isCorrect) optStyle += 'color:#f56c6c;';
            const tags = [];
            if (isCorrect) tags.push('【正确答案】');
            if (isUserAnswer && !isCorrect) tags.push('【考生选择】');
            const plainText = opt.text?.replace(/<[^>]*>/g, '') || '';
            qHtml += `<div style="${optStyle}">${opt.label}. ${plainText} ${tags.join('')}</div>`;
          });
        }
        if (item.answer && (!item.options || item.options.length === 0)) {
          const plainAnswer = item.answer?.replace(/<[^>]*>/g, '') || '';
          qHtml += `<div style="margin-top:6px;padding:6px 10px;background:#f5f7fa;border-radius:4px;font-size:13px;">考生作答：${plainAnswer}</div>`;
        }
        if (item.testAnsRight) {
          const plainRight = item.testAnsRight?.replace(/<[^>]*>/g, '') || '';
          qHtml += `<div style="margin-top:6px;padding:6px 10px;background:#f0f9eb;border-radius:4px;font-size:13px;color:#67c23a;">参考答案：${plainRight}</div>`;
        }
        if (item.analysis) {
          const plainAnalysis = item.analysis?.replace(/<[^>]*>/g, '') || '';
          qHtml += `<div style="margin-top:6px;font-size:13px;color:#606266;">答案解析：${plainAnalysis}</div>`;
        }
        qHtml += `</div>`;
      });
      qSection.innerHTML = qHtml;
      container.appendChild(qSection);
    }

    document.body.appendChild(container);
    await nextTick();
    await new Promise(resolve => setTimeout(resolve, 300));

    const canvas = await html2canvas(container, { scale: 2, useCORS: true, backgroundColor: '#ffffff' });
    document.body.removeChild(container);

    const imgData = canvas.toDataURL('image/jpeg', 0.95);
    const imgWidth = 210;
    const pageHeight = 297;
    const imgHeight = (canvas.height * imgWidth) / canvas.width;
    const pdf = new jsPDF('p', 'mm', 'a4');
    let heightLeft = imgHeight;
    let position = 0;

    pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
    heightLeft -= pageHeight;

    while (heightLeft > 0) {
      position = heightLeft - imgHeight;
      pdf.addPage();
      pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
      heightLeft -= pageHeight;
    }

    const fileName = `测评报告_${studentName.value || '考生'}_${positionName.value || '未知岗位'}.pdf`;
    pdf.save(fileName);
  } catch (e) {
    console.error('导出测评失败:', e);
    proxy?.$modal?.msgError('导出测评失败');
  } finally {
    exportLoading.value = false;
  }
};

const handleBack = () => {
  proxy?.$tab.closePage();
  router.back();
};

onMounted(() => {
  loadData();
});
</script>

<style scoped>
.evaluation-view-page {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 16px;
}

.left-card {
  background: #fff;
  border-radius: 6px;
  padding: 16px;
  height: calc(100vh - 180px);
  overflow-y: auto;
}

.right-card {
  background: #fff;
  border-radius: 6px;
  padding: 16px;
  height: calc(100vh - 180px);
  overflow-y: auto;
}

.card-title {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 12px;
}

.card-title.second {
  margin-top: 20px;
}

.info-list,
.answer-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12px;
  color: #606266;
}

.info-item,
.answer-item {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}

.chart-placeholder {
  height: 180px;
  border: 1px dashed #dcdfe6;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #909399;
  font-size: 12px;
}

.radar-chart {
  height: 220px;
  margin-top: 8px;
}

.footer-btn {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.question-block {
  padding-bottom: 18px;
  margin-bottom: 18px;
  border-bottom: 1px dashed #ebeef5;
}

.question-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.question-result {
  display: flex;
  align-items: center;
  gap: 8px;
}

.score-input {
  width: 56px;
}

.question-title {
  margin-bottom: 12px;
}

.question-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.question-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  border-radius: 4px;
}

.question-option.is-user-answer {
  background: #ecf5ff;
}

.correct-text {
  color: #67c23a;
  font-size: 12px;
}

.question-analysis {
  margin-top: 16px;
  color: #606266;
  font-size: 13px;
}

.question-user-answer {
  margin-top: 8px;
  padding: 8px 12px;
  background: #f5f7fa;
  border-radius: 4px;
  color: #606266;
  font-size: 13px;
}

.question-right-answer {
  margin-top: 8px;
  padding: 8px 12px;
  background: #f0f9eb;
  border-radius: 4px;
  color: #67c23a;
  font-size: 13px;
}
</style>
