@php
    // 提取15位paper_id数字部分作为学案编号
    $rawPaperId = $paper['id'] ?? $paper['paper_id'] ?? 'unknown';
    preg_match('/paper_(\d{15})/', $rawPaperId, $matches);
    $reportCode = $matches[1] ?? '';
    if ($reportCode === '') {
        $digits = preg_replace('/[^0-9]/', '', $rawPaperId);
        $reportCode = substr(str_pad($digits, 15, '0', STR_PAD_LEFT), -15);
    }
    $averageMastery = isset($mastery['average']) ? number_format($mastery['average'] * 100, 1) . '%' : '无数据';

    // 【修复】从insights中获取AI分析结果（而不是从analysis_data）
    $questionAnalysis = $insights ?? [];
    // 生成时间（格式：2026年01月30日 15:04:05）
    $generateDateTime = now()->format('Y年m月d日 H:i:s');
@endphp
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>学情报告 - {{ $paper['name'] ?? '试卷' }}</title>
    <link rel="stylesheet" href="/css/katex/katex.min.css">
    <style>
        @page {
            size: A4;
            margin: 2.2cm 2cm 2.3cm 2cm;
            @top-left {
                content: "知了数学·{{ $generateDateTime }}";
                font-size: 13px;
                color: #666;
            }
            @top-center {
                content: "{{ $student['name'] ?? '-' }}";
                font-size: 13px;
                color: #666;
            }
            @top-right {
                content: "{{ $reportCode }}";
                font-size: 19px;
                font-weight: 600;
                font-family: "Noto Sans", "Liberation Sans", "Nimbus Sans", sans-serif;
                letter-spacing: 0;
                padding-right: 3mm;
                padding-top: 1.8mm;
                color: #222;
            }
            @bottom-left {
                content: "{{ $reportCode }}";
                font-size: 11px;
                color: #666;
            }
            @bottom-right {
                content: counter(page) "/" counter(pages);
                font-size: 13px;
                color: #666;
            }
        }
        * { box-sizing: border-box; }
        body {
            font-family: "SimSun", "Songti SC", serif;
            margin: 0;
            padding: 0;
            color: #000;
            background: #fff;
            font-size: 12px;
            line-height: 1.6;
        }
        h1, h2, h3 { margin: 0; color: #000; }
        .card { background: #fff; border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px 16px; margin-bottom: 12px; box-shadow: 0 2px 8px rgba(15, 23, 42, 0.04); break-inside: auto; page-break-inside: auto; }
        .header { text-align: center; margin-bottom: 1.5rem; border-bottom: 2px solid #000; padding-bottom: 1rem; }
        .paper-title { font-size: 22px; font-weight: bold; margin-bottom: 14px; }
        .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
        .tag { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; color: #374151; background: #e5e7eb; }
        .section-title { font-size: 16px; margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
        .pill { padding: 4px 10px; border-radius: 999px; font-size: 12px; }
        .pill.green { background: #ecfdf3; color: #15803d; }
        .pill.amber { background: #fef3c7; color: #b45309; }
        .pill.red { background: #fef2f2; color: #b91c1c; }
        table { width: 100%; border-collapse: collapse; font-size: 13px; }
        th, td { padding: 8px 10px; border-bottom: 1px solid #e5e7eb; text-align: left; vertical-align: top; }
        th { background: #f3f4f6; color: #111827; }
        .muted { color: #6b7280; font-size: 12px; }
        .progress-wrap { background: #f3f4f6; border-radius: 999px; overflow: hidden; height: 10px; }
        .progress-bar { height: 100%; background: linear-gradient(90deg, #4f46e5, #10b981); }
        .recommend-card { border: 1px dashed #cbd5e1; border-radius: 10px; padding: 10px 12px; margin-bottom: 8px; background: #f8fafc; }
        .relation-board { margin: 6px 0 10px; break-inside: auto; page-break-inside: auto; }
        .relation-block { margin-bottom: 10px; padding: 8px; border: 1px solid #dbeafe; border-radius: 8px; background: #fff; break-inside: auto; page-break-inside: auto; }
        .relation-row { display: flex; align-items: flex-start; gap: 10px; }
        .tree-cards { width: 100%; border-collapse: collapse; table-layout: fixed; }
        .tree-cards td { border: none; padding: 0; vertical-align: top; }
        .tree-left { width: 45%; flex: 0 0 45%; padding-right: 10px; }
        .tree-right { width: 55%; flex: 1; padding-left: 10px; }
        .tree-parent {
            display: inline-block;
            margin-bottom: 6px;
            padding: 4px 8px;
            border-radius: 999px;
            border: 1px solid #93c5fd;
            background: #dbeafe;
            color: #1e3a8a;
            font-weight: 700;
            font-size: 12px;
        }
        .tree-lines { margin: 0; padding-left: 14px; border-left: 2px solid #cbd5e1; }
        .tree-line {
            font-size: 11px;
            color: #334155;
            margin-bottom: 3px;
            white-space: normal;
            overflow: visible;
            text-overflow: clip;
            word-break: break-all;
            line-height: 1.45;
        }
        .tree-line.hit { font-weight: 600; color: #1e40af; }
        .tree-line-badge { display: inline-block; margin-left: 6px; padding: 1px 5px; border-radius: 999px; font-size: 10px; border: 1px solid transparent; }
        .tree-line-badge.high,
        .tree-line-badge.mid,
        .tree-line-badge.low,
        .tree-line-badge.miss { background: #f8fafc; color: #64748b; border-color: #cbd5e1; }
        .detail-card {
            border: 1px solid #e2e8f0;
            border-radius: 6px;
            background: #f8fafc;
            padding: 6px 8px;
            margin-bottom: 5px;
            break-inside: auto;
            page-break-inside: auto;
        }
        .detail-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
        .detail-title { font-size: 11px; color: #0f172a; font-weight: 700; margin-bottom: 2px; }
        .detail-meta { font-size: 11px; color: #475569; margin-top: 3px; }
        .detail-mastery { font-size: 38px; color: #0f172a; font-weight: 700; line-height: 1; margin: 0; }
        .detail-mastery.high { color: #16a34a; }
        .detail-mastery.mid { color: #d97706; }
        .detail-mastery.low { color: #dc2626; }
        .node-tags { margin-top: 2px; }
        .node-tag {
            display: inline-block;
            margin: 0 6px 6px 0;
            padding: 1px 7px;
            border-radius: 999px;
            font-size: 10px;
            line-height: 1.4;
            color: #475569;
            background: #f1f5f9;
            border: 1px solid #cbd5e1;
        }
        .suggest-tags { display: inline; }
        .suggest-tag {
            display: inline-block;
            margin: 0 6px 6px 0;
            padding: 1px 7px;
            border-radius: 999px;
            font-size: 10px;
            line-height: 1.4;
            color: #334155;
            background: #f8fafc;
            border: 1px solid #d1d5db;
        }
        .weak-kp-tags { margin-top: 6px; }
        .weak-kp-tag {
            display: inline-block;
            margin: 0 6px 6px 0;
            padding: 1px 7px;
            border-radius: 999px;
            font-size: 10px;
            line-height: 1.45;
            color: #854d0e;
            background: #fef3c7;
            border: 1px solid #fcd34d;
        }
        .error-kp-tag {
            display: inline-block;
            margin: 0 6px 6px 0;
            padding: 1px 7px;
            border-radius: 999px;
            font-size: 10px;
            line-height: 1.45;
            color: #334155;
            background: #f8fafc;
            border: 1px solid #d1d5db;
        }
        .error-kp-tag.high-risk {
            color: #b91c1c;
            border-color: #fca5a5;
            background: #fff;
            font-weight: 600;
        }
        .detail-change-up { color: #16a34a; font-weight: 700; }
        .detail-change-down { color: #dc2626; font-weight: 700; }
        .aggregate-tip { font-size: 11px; color: #475569; margin-top: 6px; }
        .question-card { border:1px solid #e5e7eb; border-radius:8px; padding:6px 9px; margin-bottom:5px; background:#fff; page-break-inside: auto; break-inside: auto; }
        .question-block { margin-bottom: 5px; padding: 5px; border-radius: 4px; page-break-inside: auto; break-inside: auto; }
        .question-card,
        .question-card .math-content,
        .question-card .solution-content {
            font-size: 12px;
            line-height: 1.7;
        }
        /* 题干区：与判卷 PDF（exam-grading）一致 — <img>、内嵌 SVG、公式 */
        .question-card .question-stem svg,
        .question-card .math-content svg {
            max-width: 100%;
            height: auto;
            display: block;
            shape-rendering: geometricPrecision;
            text-rendering: geometricPrecision;
        }
        .question-card .question-stem svg text {
            font-family: "Noto Serif", "Noto Serif CJK SC", "Noto Sans CJK SC", "Noto Sans", "STSongti-SC", "PingFang SC", "Songti SC", serif !important;
            font-size: 13px !important;
            font-weight: bold;
            dominant-baseline: middle;
            text-anchor: middle;
        }
        .question-card .question-stem svg circle,
        .question-card .question-stem svg line,
        .question-card .question-stem svg polygon,
        .question-card .question-stem svg polyline {
            shape-rendering: geometricPrecision;
        }
        .question-card .question-stem img,
        .question-card .question-main img {
            display: block;
            max-width: 220px;
            max-height: 60mm;
            width: auto;
            height: auto;
            margin: 6px auto;
            box-sizing: border-box;
            object-fit: contain;
            -webkit-print-color-adjust: exact;
            print-color-adjust: exact;
            image-rendering: -webkit-optimize-contrast;
        }
        .question-card .question-stem .katex {
            font-size: 1em !important;
            vertical-align: 0;
        }
        .question-card .question-stem .katex-display {
            margin: 0.35em 0 !important;
        }
        .question-card .solution-content img,
        .question-card .report-answer-meta img {
            display: block;
            max-width: 220px;
            max-height: 60mm;
            width: auto;
            height: auto;
            margin: 6px auto;
            object-fit: contain;
            -webkit-print-color-adjust: exact;
            print-color-adjust: exact;
        }
        .solution-content {
            display: block;
            line-height: 1.75;
            white-space: normal;
            word-break: break-word;
            overflow-wrap: anywhere;
            page-break-inside: auto;
            break-inside: auto;
        }
        /* 与判卷 PDF（exam-grading / paper-body）一致的选项网格 */
        .report-options {
            margin-top: 6px;
            page-break-inside: avoid;
            break-inside: avoid;
        }
        .report-options.options-grid-4 {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 8px 12px;
        }
        .report-options.options-grid-2 {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 8px 20px;
        }
        .report-options.options-grid-1 {
            display: grid;
            grid-template-columns: 1fr;
            gap: 8px;
        }
        .report-options .option {
            display: flex;
            align-items: baseline;
            font-size: 12px;
            line-height: 1.6;
            page-break-inside: avoid;
            break-inside: avoid;
        }
        .report-options .option strong { margin-right: 4px; flex: 0 0 auto; }
        .report-options .option-value.option-short { white-space: nowrap; }
        .report-options .option-value.option-long { white-space: normal; word-break: break-word; }
        .report-options .option p, .report-options .option div { margin: 0; display: inline; }
        .report-options .option img {
            max-width: 100%;
            height: auto;
            vertical-align: middle;
        }
        /* 判卷风格：解题思路（与 answer-meta 一致） */
        .report-answer-meta {
            font-size: 12px;
            color: #2f2f2f;
            line-height: 1.75;
            margin-top: 6px;
            page-break-inside: avoid;
            break-inside: avoid;
        }
        .report-answer-meta .answer-line + .answer-line { margin-top: 4px; }
        .report-answer-meta .solution-content {
            display: inline;
            line-height: 1.75;
        }
    </style>
</head>
<body>
    <div class="page">
        <div class="header">
            <h1 class="paper-title">学情分析报告</h1>
            @php
                $teacherName = trim((string) ($teacher['name'] ?? ''));
                $showTeacher = $teacherName !== '' && $teacherName !== '________' && $teacherName !== '未知老师';
            @endphp
            <div style="display:flex;justify-content:space-between;font-size:14px;margin-top:8px;">
                @if($showTeacher)
                    <span>老师：{{ $teacherName }}</span>
                @endif
                <span>年级：@formatGrade($student['grade'] ?? '________')</span>
                @if(!empty($paper['assemble_type_label']) && $paper['assemble_type_label'] !== '未知类型')
                    <span>类型：{{ $paper['assemble_type_label'] }}</span>
                @endif
                <span>姓名：{{ $student['name'] ?? '________' }}</span>
                <span>题目数：{{ $paper['total_questions'] ?? (is_array($questions ?? null) ? count($questions) : '-') }}</span>
            </div>
        </div>

    <div class="card">
        <div class="section-title">本次命中子知识点掌握度</div>
        @php
            // 严格口径：顶部列表来自“本卷题目关联知识点”
            $hitCodes = array_values(array_unique(array_filter($exam_hit_kp_codes ?? [])));
            $masteryByCode = [];
            $hitMasteryFromParents = [];
            $questionKpNameMap = [];
            foreach (($questions ?? []) as $q) {
                $code = trim((string) ($q['knowledge_point'] ?? ''));
                $name = trim((string) ($q['knowledge_point_name'] ?? ''));
                if ($code !== '' && $name !== '') {
                    $questionKpNameMap[$code] = $name;
                }
            }
            // 优先使用父节点树里的命中子节点掌握度（与左侧树口径一致）
            foreach (($parent_mastery_levels ?? []) as $parent) {
                $childrenAll = $parent['children_all'] ?? [];
                if (!is_array($childrenAll)) {
                    continue;
                }
                foreach ($childrenAll as $child) {
                    $cCode = trim((string) ($child['kp_code'] ?? ''));
                    if ($cCode === '' || empty($child['is_hit'])) {
                        continue;
                    }
                    $hitMasteryFromParents[$cCode] = floatval($child['mastery_level'] ?? 0);
                }
            }
            foreach (($mastery['items'] ?? []) as $item) {
                $code = (string) ($item['kp_code'] ?? '');
                if ($code !== '') {
                    $masteryByCode[$code] = $item;
                }
            }

            $filteredMasteryItems = [];
            foreach ($hitCodes as $kpCode) {
                if (in_array($kpCode, ['K-GENERAL', 'GENERAL', 'DEFAULT'])) {
                    continue;
                }
                $base = $masteryByCode[$kpCode] ?? null;
                $levelFromParentTree = $hitMasteryFromParents[$kpCode] ?? null;
                $resolvedLevel = $levelFromParentTree !== null
                    ? floatval($levelFromParentTree)
                    : floatval($base['mastery_level'] ?? 0);
                $resolvedChange = $base['mastery_change'] ?? null;
                // 当顶部使用了父节点树中的实时值且与旧值不一致时，避免显示旧变化值误导
                if ($levelFromParentTree !== null && $base !== null) {
                    $oldLevel = floatval($base['mastery_level'] ?? 0);
                    if (abs($resolvedLevel - $oldLevel) > 0.0001) {
                        $resolvedChange = null;
                    }
                }
                $filteredMasteryItems[] = [
                    'kp_code' => $kpCode,
                    'kp_name' => $questionKpNameMap[$kpCode] ?? ($base['kp_name'] ?? $kpCode),
                    'mastery_level' => $resolvedLevel,
                    'mastery_change' => $resolvedChange,
                    'is_hit' => true,
                ];
            }
        @endphp

        @if(!empty($filteredMasteryItems))
            @foreach($filteredMasteryItems as $item)
                @php
                    $pct = min(100, max(0, ($item['mastery_level'] ?? 0) * 100));
                    $barColor = $pct >= 80 ? '#10b981' : ($pct >= 60 ? '#f59e0b' : '#ef4444');
                    $delta = $item['mastery_change'] ?? null;
                    $isHitItem = !empty($item['is_hit']);
                    // 只有当有变化值时才显示变化信息
                    $changeText = '';
                    if ($delta !== null && $delta !== '' && abs($delta) > 0.001) {
                        $changeText = ($delta > 0 ? '↑ ' : '↓ ') . number_format(abs($delta) * 100, 1) . '%';
                    }
                @endphp
                <div style="margin-bottom:12px; padding: 8px; border: 1px solid #e5e7eb; border-radius: 6px;">
                    <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom: 6px;">
                        <div style="font-weight: 600; font-size: 13px;">{{ $item['kp_name'] ?? $item['kp_code'] ?? '未知知识点' }}</div>
                        <div style="font-weight: 600; color: {{ $barColor }}; font-size: 13px;">
                            {{ number_format($pct, 1) }}%
                            <span style="margin-left: 8px; color: #666; font-size: 11px;">{{ $changeText ? '子节点变化 ' . $changeText : '' }}</span>
                        </div>
                    </div>
                    <div class="progress-wrap" style="height: 12px;">
                        <div class="progress-bar" style="width: {{ $pct }}%; background: {{ $barColor }};"></div>
                    </div>
                </div>
            @endforeach
        @else
            <div class="muted">暂无有效掌握度数据（已过滤通用知识点）</div>
        @endif
    </div>

    <div class="card">
        <div class="section-title">📊 知识点层级掌握度分析</div>
        @php
            $parentMasteryLevels = $parent_mastery_levels ?? [];
            $hasParentMastery = !empty($parentMasteryLevels);
            $childMasteryMap = [];
            foreach (($filteredMasteryItems ?? []) as $it) {
                $childMasteryMap[$it['kp_code']] = [
                    'level' => floatval($it['mastery_level'] ?? 0),
                    'delta' => isset($it['mastery_change']) ? floatval($it['mastery_change']) : null,
                ];
            }
        @endphp

        @if($hasParentMastery)
            <div class="relation-board">
                <div style="font-size:12px; color:#334155; margin-bottom:6px; font-weight:600;">父子知识点关系</div>
                @foreach($parentMasteryLevels as $parentData)
                    @php
                        $childrenAll = $parentData['children_all'] ?? [];
                        $children = $parentData['children'] ?? []; // 命中子节点
                        $childCount = count($childrenAll);
                        $hitCount = count($children);
                        $hitAvg = $parentData['children_hit_avg_mastery'] ?? null;
                        $parentPct = number_format(floatval($parentData['mastery_percentage'] ?? 0), 1);
                        $parentLevel = floatval($parentData['mastery_level'] ?? 0);
                        $parentClass = $parentLevel >= 0.8 ? 'high' : ($parentLevel >= 0.6 ? 'mid' : 'low');
                        $delta = $parentData['mastery_change'] ?? null;
                        $hitNames = array_values(array_map(fn($c) => $c['kp_name'] ?? ($c['kp_code'] ?? ''), $children));
                        $allChildrenPerfect = !empty($childrenAll) && count(array_filter($childrenAll, function ($c) {
                            return floatval($c['mastery_level'] ?? 0) >= 0.999;
                        })) === count($childrenAll);
                    @endphp
                    <div class="relation-block">
                        <div class="relation-row">
                                <div class="tree-left">
                                    <div class="tree-parent">{{ $parentData['kp_name'] ?? $parentData['kp_code'] }}</div>
                                    @if(!empty($childrenAll))
                                        <div class="tree-lines">
                                            @foreach($childrenAll as $child)
                                                @php
                                                    $isHit = !empty($child['is_hit']);
                                                    $m = floatval($child['mastery_level'] ?? 0);
                                                    $badgeClass = $m >= 0.8 ? 'high' : ($m >= 0.6 ? 'mid' : ($m > 0 ? 'low' : 'miss'));
                                                    $badgeText = number_format($m * 100, 1) . '%';
                                                @endphp
                                                <div class="tree-line {{ $isHit ? 'hit' : '' }}">
                                                    └─ {{ $child['kp_name'] }}
                                                    <span class="tree-line-badge {{ $badgeClass }}">{{ $badgeText }}</span>
                                                </div>
                                            @endforeach
                                        </div>
                                    @else
                                        <div class="muted">无命中子知识点</div>
                                    @endif
                                </div>
                                <div class="tree-right">
                                    <div class="detail-card">
                                        <div class="detail-head">
                                            <div class="detail-title">{{ $parentData['kp_name'] ?? $parentData['kp_code'] }}</div>
                                            <div class="detail-mastery {{ $parentClass }}">{{ $parentPct }}%</div>
                                        </div>
                                        <div class="detail-meta">
                                            父节点变化：
                                            @if($delta !== null)
                                                <span class="{{ $delta >= 0 ? 'detail-change-up' : 'detail-change-down' }}">
                                                    {{ $delta >= 0 ? '↑ ' : '↓ ' }}{{ number_format(abs($delta) * 100, 1) }}%
                                                </span>
                                            @else
                                                -
                                            @endif
                                        </div>
                                        <div class="detail-meta" style="margin-top: 3px;">
                                            本次重点子节点：
                                            @if($hitCount > 0)
                                                <span class="node-tags">
                                                    @foreach($hitNames as $hitName)
                                                        @if(!empty(trim($hitName)))
                                                            <span class="node-tag">{{ $hitName }}</span>
                                                        @endif
                                                    @endforeach
                                                </span>
                                            @else
                                                无
                                            @endif
                                        </div>
                                        <div class="detail-meta">
                                            子节点总数 {{ $childCount }} 个，本次命中 {{ $hitCount }} 个，命中均值 {{ $hitAvg !== null ? number_format(floatval($hitAvg) * 100, 1) . '%' : '-' }}（命中表示本次覆盖，不等于已掌握）
                                        </div>
                                    </div>
                                </div>
                        </div>
                    </div>
                @endforeach
            </div>
            @php
                $allParentPerfect = !empty($parentMasteryLevels) && count(array_filter($parentMasteryLevels, function ($p) {
                    return floatval($p['mastery_level'] ?? 0) >= 0.999;
                })) === count($parentMasteryLevels);
                $allHitChildrenPerfect = !empty($filteredMasteryItems) && count(array_filter($filteredMasteryItems, function ($it) {
                    return floatval($it['mastery_level'] ?? 0) >= 0.999;
                })) === count($filteredMasteryItems);
                $isAllPerfect = $allParentPerfect && $allHitChildrenPerfect;
                // 1) 优先：本次命中子知识点中的低掌握度（<60%）
                $hitWeakChildren = [];
                $hitWeakKeys = [];
                foreach (($filteredMasteryItems ?? []) as $hitItem) {
                    $level = floatval($hitItem['mastery_level'] ?? 0);
                    $name = trim((string) ($hitItem['kp_name'] ?? $hitItem['kp_code'] ?? ''));
                    if ($name === '' || $level >= 0.6) {
                        continue;
                    }
                    $key = (string) ($hitItem['kp_code'] ?? $name);
                    $hitWeakChildren[$key] = [
                        'name' => $name,
                        'level' => $level,
                    ];
                    $hitWeakKeys[$key] = true;
                }
                $hitWeakChildren = array_values($hitWeakChildren);
                usort($hitWeakChildren, function ($a, $b) {
                    return $a['level'] <=> $b['level'];
                });

                // 2) 兜底：若命中子知识点都 >=60%，再从其他低掌握度子知识点补
                $otherWeakChildren = [];
                foreach (($parentMasteryLevels ?? []) as $pData) {
                    foreach (($pData['children_all'] ?? []) as $child) {
                        $level = floatval($child['mastery_level'] ?? 0);
                        $name = trim((string) ($child['kp_name'] ?? $child['kp_code'] ?? ''));
                        if ($name === '' || $level >= 0.6) {
                            continue;
                        }
                        $key = ($child['kp_code'] ?? $name);
                        if (isset($hitWeakKeys[$key])) {
                            continue;
                        }
                        $otherWeakChildren[$key] = [
                            'name' => $name,
                            'level' => $level,
                        ];
                    }
                }
                $otherWeakChildren = array_values($otherWeakChildren);
                usort($otherWeakChildren, function ($a, $b) {
                    return $a['level'] <=> $b['level'];
                });

                // 3) 最终展示：总数不超过5
                $globalWeakChildren = [];
                if (!empty($hitWeakChildren)) {
                    $globalWeakChildren = array_slice($hitWeakChildren, 0, 5);
                } else {
                    $globalWeakChildren = array_slice($otherWeakChildren, 0, 5);
                }
            @endphp
            <div style="margin-top: 12px; padding: 8px; background: #fefce8; border-left: 4px solid #eab308; border-radius: 4px;">
                <div style="font-size: 12px; color: #854d0e; line-height: 1.6;">
                    <strong>学习建议：</strong>
                    @if($isAllPerfect)
                        本次学案表现非常出色，相关知识点掌握稳定且完整。建议继续进入新的知识点专题学习，优先选择同层级未覆盖内容或更高难度综合题，保持进阶节奏。
                    @else
                        建议重点关注掌握度较低的知识点，通过专项练习提升整体学习水平。优先练习掌握度低于60%的知识点。
                    @endif
                    @if(!empty($globalWeakChildren))
                        <div class="weak-kp-tags">
                            @foreach($globalWeakChildren as $weakChild)
                                <span class="weak-kp-tag">{{ $weakChild['name'] }}（{{ number_format($weakChild['level'] * 100, 1) }}%）</span>
                            @endforeach
                        </div>
                    @endif
                </div>
            </div>
        @else
            <div class="muted">暂无父节点掌握度数据</div>
            <div style="margin-top: 8px; font-size: 12px; color: #64748b;">
                当前分析主要基于具体知识点掌握度。完整的层级掌握度分析需要在系统中建立完整的知识点层级关系。
            </div>
        @endif
    </div>

    @php
        $insightMap = [];
        foreach (($question_insights ?? []) as $insight) {
            $no = $insight['question_number'] ?? $insight['question_id'] ?? null;
            if ($no !== null) {
                $insightMap[$no] = $insight;
            }
        }

        $analysisWrongMap = [];
        foreach (($analysis_data['question_analysis'] ?? []) as $qa) {
            $qid = $qa['question_bank_id'] ?? $qa['question_id'] ?? null;
            if ($qid === null || $qid === '') {
                continue;
            }
            $rawCorrect = $qa['is_correct'] ?? null;
            $isWrongFromAnalysis = false;
            if (is_array($rawCorrect)) {
                $isWrongFromAnalysis = in_array(0, $rawCorrect, true);
            } elseif ($rawCorrect !== null) {
                $isWrongFromAnalysis = !boolval($rawCorrect);
            }
            if ($isWrongFromAnalysis) {
                $analysisWrongMap[(string)$qid] = true;
            }
        }

        $wrongQuestions = [];
        foreach (($questions ?? []) as $qItem) {
            $studentAnswerProbe = $qItem['student_answer'] ?? null;
            $correctAnswerProbe = $qItem['answer'] ?? ($qItem['correct_answer'] ?? null);
            $isCorrectProbe = $qItem['is_correct'] ?? null;
            if ($isCorrectProbe === null && !empty($studentAnswerProbe) && !empty($correctAnswerProbe)) {
                $isCorrectProbe = (trim((string)$studentAnswerProbe) === trim((string)$correctAnswerProbe)) ? 1 : 0;
            }
            $normalizedCorrect = $isCorrectProbe;
            if ($isCorrectProbe !== null) {
                $normalizedCorrect = is_bool($isCorrectProbe) ? ($isCorrectProbe ? 1 : 0) : intval($isCorrectProbe);
            }
            $qidProbe = (string)($qItem['question_bank_id'] ?? $qItem['question_id'] ?? '');
            $isWrongByAnalysis = ($qidProbe !== '' && isset($analysisWrongMap[$qidProbe]));
            if ($normalizedCorrect === 0 || $isWrongByAnalysis) {
                $wrongQuestions[] = $qItem;
            }
        }

        // 错题知识点聚合统计（同知识点错几题/共几题）
        $kpStats = [];
        foreach (($questions ?? []) as $qItem) {
            $kpName = trim((string)($qItem['knowledge_point_name'] ?? $qItem['knowledge_point'] ?? '未标注知识点'));
            if ($kpName === '') {
                $kpName = '未标注知识点';
            }
            if (!isset($kpStats[$kpName])) {
                $kpStats[$kpName] = ['total' => 0, 'wrong' => 0];
            }
            $kpStats[$kpName]['total']++;
        }
        foreach ($wrongQuestions as $qItem) {
            $kpName = trim((string)($qItem['knowledge_point_name'] ?? $qItem['knowledge_point'] ?? '未标注知识点'));
            if ($kpName === '') {
                $kpName = '未标注知识点';
            }
            if (!isset($kpStats[$kpName])) {
                $kpStats[$kpName] = ['total' => 0, 'wrong' => 0];
            }
            $kpStats[$kpName]['wrong']++;
        }

        $kpWrongStats = [];
        foreach ($kpStats as $kpName => $stat) {
            if (($stat['wrong'] ?? 0) <= 0) {
                continue;
            }
            $total = max(1, intval($stat['total'] ?? 0));
            $wrong = intval($stat['wrong'] ?? 0);
            $kpWrongStats[] = [
                'kp_name' => $kpName,
                'wrong' => $wrong,
                'total' => $total,
                'rate' => $wrong / $total,
            ];
        }
        usort($kpWrongStats, function ($a, $b) {
            if ($a['rate'] === $b['rate']) {
                return $b['wrong'] <=> $a['wrong'];
            }
            return $b['rate'] <=> $a['rate'];
        });
    @endphp

    @if(!empty($wrongQuestions))
    <div class="card">
        <div class="section-title">错题列表</div>
        @if(!empty($kpWrongStats))
            <div style="margin-bottom:8px; padding:8px; border:1px solid #e5e7eb; border-radius:6px; background:#f8fafc;">
                <div style="font-size:12px; font-weight:600; color:#111827; margin-bottom:6px;">知识点错误率</div>
                <div style="font-size:12px; color:#475569; line-height:1.7;">
                    @foreach($kpWrongStats as $item)
                        <span class="error-kp-tag {{ $item['rate'] > 0.5 ? 'high-risk' : '' }}">{{ $item['kp_name'] }}：{{ $item['wrong'] }}/{{ $item['total'] }}（{{ number_format($item['rate'] * 100, 1) }}%）</span>
                    @endforeach
                </div>
            </div>
        @endif
        @foreach($wrongQuestions as $q)
            @php
                // 【修复】从题目数据中获取学生答案、正确答案和判分结果
                $studentAnswer = $q['student_answer'] ?? $q['student_answer'] ?? null;
                $correctAnswer = $q['answer'] ?? $q['correct_answer'] ?? null;
                $isCorrect = $q['is_correct'] ?? null;  // 1=正确，0=错误，null=未判

                // 如果未判分但有学生答案和正确答案，自动比较判断
                if ($isCorrect === null && !empty($studentAnswer) && !empty($correctAnswer)) {
                    $isCorrect = (trim($studentAnswer) === trim($correctAnswer)) ? 1 : 0;
                }

                // 判分状态显示逻辑
                $statusText = '';
                $statusColor = '';
                if ($isCorrect === 1) {
                    $statusText = '正确';
                    $statusColor = '#10b981';
                } elseif ($isCorrect === 0) {
                    $statusText = '错误';
                    $statusColor = '#ef4444';
                }
                $showStatus = $statusText !== '';

                $insight = $insightMap[$q['question_number']] ?? ($insightMap[$q['display_number'] ?? null] ?? []);
                // 【修复】得分显示：答错显示实际得分，答对显示满分
                $fullScore = $insight['full_score'] ?? ($q['score'] ?? null);
                if ($isCorrect === 1) {
                    // 答对了，显示满分
                    $score = $fullScore;
                } elseif ($isCorrect === 0) {
                    // 答错了，显示实际得分（可能为0分或其他分数）
                    $score = $q['score_obtained'] ?? 0;
                } else {
                    // 未判分或未答题，不显示得分
                    $score = null;
                }
                $analysisRaw = $insight['analysis']
                    ?? $insight['thinking_process']
                    ?? $insight['feedback']
                    ?? $insight['suggestions']
                    ?? $insight['reason']
                    ?? ($insight['correct_solution'] ?? null);
                // 若有下一步建议，追加
                if (empty($analysisRaw) && !empty($insight['next_steps'])) {
                    $analysisRaw = '后续建议：' . (is_array($insight['next_steps']) ? implode('；', $insight['next_steps']) : $insight['next_steps']);
                }
                $analysis = is_array($analysisRaw) ? json_encode($analysisRaw, JSON_UNESCAPED_UNICODE) : $analysisRaw;
                if ($analysis === null || $analysis === '') {
                    $analysis = '暂无解题思路，待补充';
                }
                if (is_string($analysis)) {
                    $analysis = preg_replace('/^【?\s*解题思路\s*】?\s*[:：]?\s*/u', '', $analysis);
                }
                $formatSolutionLikeGrading = function ($text) {
                    if (!is_string($text) || trim($text) === '') {
                        return $text;
                    }
                    $normalized = preg_replace('/\s*；\s*步骤\s*(\d+)/u', "；\n步骤$1", $text);
                    $normalized = preg_replace('/\s*。\s*步骤\s*(\d+)/u', "。\n步骤$1", $normalized);
                    $normalized = preg_replace('/(?<!^)(步骤\s*\d+\s*[:：])/u', "\n$1", $normalized);
                    $normalized = preg_replace('/(?<!^)(第\s*\d+\s*步\s*[:：]?)/u', "\n$1", $normalized);
                    $normalized = preg_replace('/\n{3,}/u', "\n\n", $normalized);
                    // 去掉每行左侧缩进空白，避免出现“左边空好几个字符”
                    $normalized = preg_replace('/^[\h\x{3000}]+/mu', '', $normalized);
                    return trim($normalized);
                };
                $stepsRaw = $insight['steps'] ?? $insight['solution_steps'] ?? $insight['analysis_steps'] ?? null;
                $steps = [];
                if (is_array($stepsRaw)) {
                    $steps = $stepsRaw;
                } elseif (is_string($stepsRaw) && trim($stepsRaw) !== '') {
                    $steps = preg_split('/[\r\n]+/', trim($stepsRaw));
                }
                $typeMap = ['choice' => '选择题', 'fill' => '填空题', 'answer' => '解答题'];
                $typeLabel = $typeMap[$q['question_type'] ?? ''] ?? ($q['question_type'] ?? '题型未标注');
                $questionText = is_string($q['question_text']) ? $q['question_text'] : json_encode($q['question_text'], JSON_UNESCAPED_UNICODE);
                $solution = $q['solution'] ?? null;
                if (is_string($solution)) {
                    $solution = preg_replace('/^【?\s*解题思路\s*】?\s*[:：]?\s*/u', '', $solution);
                }
                $solution = $formatSolutionLikeGrading($solution);
                $analysis = $formatSolutionLikeGrading($analysis);
                // 对齐判卷渲染口径：直接走 MathFormulaProcessor，保留图片与公式标签
                $renderLikeGrading = function ($text) {
                    if (is_array($text)) {
                        $text = json_encode($text, JSON_UNESCAPED_UNICODE);
                    }
                    $text = is_string($text) ? trim($text) : '';
                    if ($text === '') {
                        return '';
                    }
                    return \App\Services\MathFormulaProcessor::processFormulas($text);
                };
                // 选择题：选项来自服务端 questions.options / 题干解析；正确答案字母用于打 ✅
                $displayCorrectAnswer = is_array($correctAnswer)
                    ? json_encode($correctAnswer, JSON_UNESCAPED_UNICODE)
                    : (string) $correctAnswer;
                $questionTypeRaw = strtolower(trim((string) ($q['question_type'] ?? '')));
                $isChoiceQuestion = in_array($questionTypeRaw, ['choice', 'multiple_choice', 'single_choice', '选择题', 'select'], true);
                $normalizedOptions = [];
                $correctAnswerLetters = [];
                if ($isChoiceQuestion) {
                    $rawOptions = $q['options'] ?? [];
                    if (is_string($rawOptions)) {
                        $decodedOptions = json_decode($rawOptions, true);
                        $rawOptions = is_array($decodedOptions) ? $decodedOptions : [];
                    }
                    if (is_array($rawOptions)) {
                        foreach ($rawOptions as $optKey => $optValue) {
                            $letter = null;
                            if (is_string($optKey) && preg_match('/([A-H])/i', $optKey, $m)) {
                                $letter = strtoupper($m[1]);
                            } elseif (is_array($optValue)) {
                                $candidate = $optValue['label'] ?? $optValue['key'] ?? $optValue['option'] ?? null;
                                if (is_string($candidate) && preg_match('/([A-H])/i', $candidate, $m)) {
                                    $letter = strtoupper($m[1]);
                                }
                            }
                            if ($letter === null) {
                                continue;
                            }
                            $content = is_array($optValue)
                                ? ($optValue['content'] ?? $optValue['text'] ?? $optValue['value'] ?? '')
                                : $optValue;
                            if (!is_string($content)) {
                                $content = json_encode($content, JSON_UNESCAPED_UNICODE);
                            }
                            $content = trim((string) $content);
                            if ($content !== '') {
                                $normalizedOptions[$letter] = $content;
                            }
                        }
                    }
                    if (trim((string) $correctAnswer) !== '') {
                        preg_match_all('/[A-H]/i', strtoupper((string) $correctAnswer), $answerMatches);
                        $correctAnswerLetters = array_values(array_unique($answerMatches[0] ?? []));
                    }
                    if (!empty($normalizedOptions) && !empty($correctAnswerLetters)) {
                        $mappedAnswers = [];
                        foreach ($correctAnswerLetters as $letter) {
                            if (isset($normalizedOptions[$letter])) {
                                $mappedAnswers[] = $letter . '. ' . $normalizedOptions[$letter];
                            }
                        }
                        if (!empty($mappedAnswers)) {
                            $displayCorrectAnswer = implode('；', $mappedAnswers);
                        }
                    }
                }
                $choiceOptionLetters = !empty($normalizedOptions) ? array_keys($normalizedOptions) : [];
                sort($choiceOptionLetters);
                $choiceLayoutClass = 'options-grid-1';
                $layoutDecider = app(\App\Support\OptionLayoutDecider::class);
                if (! empty($normalizedOptions) && ! empty($choiceOptionLetters)) {
                    $optValuesForLayout = [];
                    foreach ($choiceOptionLetters as $L) {
                        $optValuesForLayout[] = $normalizedOptions[$L];
                    }
                    $layoutMeta = $layoutDecider->decide($optValuesForLayout, 'grading');
                    $choiceLayoutClass = $layoutMeta['class'] ?? 'options-grid-1';
                }
            @endphp
            <div class="question-card">
                <div style="display:flex; justify-content:space-between; align-items:center; gap:8px; margin-bottom:4px;">
                    <div style="display:flex; align-items:center; gap:8px; font-weight:600;">
                        <span class="tag">题号 {{ $q['display_number'] ?? $q['question_number'] }} · {{ $typeLabel }}</span>
                        @php
                            $kpName = $q['knowledge_point_name'] ?? $q['knowledge_point'] ?? null;
                            if (!empty($kpName) && $kpName !== '-' && $kpName !== '未标注') {
                                echo '<span class="tag" style="background: #eef2ff; color:#4338ca;">' . e($kpName) . '</span>';
                            }
                        @endphp
                        @if($showStatus)
                            <span class="tag" style="background: {{ $statusColor }}; color:#fff;">{{ $statusText }}</span>
                        @endif
                    </div>
                    @if($score !== null && $fullScore !== null)
                        <div class="muted">得分 {{ $score }} / {{ $fullScore }}</div>
                    @endif
                </div>

                {{-- 题干：数据已在 ExamPdfExportService 中经 processQuestionData（含 <image>→<img>、公式）；样式对齐判卷 question-stem --}}
                <div class="question-stem math-content" style="margin-bottom:6px;">{!! $questionText !!}</div>

                {{-- 选择题：与判卷页相同网格布局（OptionLayoutDecider），正确项旁 ✅ --}}
                @if(!empty($isChoiceQuestion) && !empty($normalizedOptions))
                    <div class="report-options {{ $choiceLayoutClass }}">
                        @foreach($choiceOptionLetters as $optLetter)
                            @php
                                $isCorrectOpt = in_array($optLetter, $correctAnswerLetters ?? [], true);
                                $rawOpt = (string) ($normalizedOptions[$optLetter] ?? '');
                                $normalizedOpt = str_replace('\\dfrac', '\\frac', $rawOpt);
                                $normalizedOpt = str_replace('\\displaystyle', '', $normalizedOpt);
                                $normalizedOpt = $layoutDecider->normalizeCompactMathForDisplay($normalizedOpt);
                                $rawOptPlain = html_entity_decode(strip_tags($rawOpt), ENT_QUOTES | ENT_HTML5, 'UTF-8');
                                $rawOptPlain = preg_replace('/\s+/u', '', $rawOptPlain ?? '');
                                $isShortOption = mb_strlen((string) $rawOptPlain, 'UTF-8') <= 8;
                                $valClass = $isShortOption ? 'option-short' : 'option-long';
                                $renderedOpt = $renderLikeGrading($normalizedOpt);
                            @endphp
                            <div class="option option-compact">
                                <strong>{{ $optLetter }}.</strong>
                                <span class="option-value {{ $valClass }}">{!! $renderedOpt !!}</span>
                                @if($isCorrectOpt)
                                    <span style="margin-left:4px; font-size:13px; color:#15803d; font-weight:700;">✅</span>
                                @endif
                            </div>
                        @endforeach
                    </div>
                @endif

                {{-- 非选择题，或选择题未能得到选项列表时：显示「正确答案」文字框 --}}
                @if(!empty($correctAnswer) && (!$isChoiceQuestion || empty($normalizedOptions)))
                    <div class="question-block" style="background:#f0fdf4; border-left:3px solid #10b981;">
                        <div style="font-weight:600; font-size:12px; color:#111827; margin-bottom:3px;">正确答案</div>
                        <div class="math-content" style="line-height:1.7; color:#374151;">
                            {!! $renderLikeGrading($displayCorrectAnswer) !!}
                        </div>
                    </div>
                @endif

                {{-- 解题思路：判卷页 answer-meta 口径（单行标题+正文，避免大块色条占行） --}}
                @if(!empty($solution))
                    <div class="report-answer-meta">
                        <div class="answer-line">
                            <strong>解题思路：</strong>
                            <span class="solution-content">{!! $renderLikeGrading($solution) !!}</span>
                        </div>
                    </div>
                @elseif(!empty($analysis) && $analysis !== '暂无解题思路记录')
                    <div class="report-answer-meta">
                        <div class="answer-line">
                            <strong>解题思路：</strong>
                            <span class="solution-content">{!! $renderLikeGrading($analysis) !!}</span>
                        </div>
                    </div>
                @endif

                {{-- 解题步骤（如果有） --}}
                @if(!empty($steps))
                    <div style="margin-top:6px; font-size:12px;">
                        <div style="font-weight:600; margin-bottom:3px;">解题步骤</div>
                        <ol style="margin:0; padding-left:18px;">
                            @foreach($steps as $s)
                                <li style="margin-bottom:2px;">{!! nl2br(e(is_array($s) ? json_encode($s, JSON_UNESCAPED_UNICODE) : $s)) !!}</li>
                            @endforeach
                        </ol>
                    </div>
                @endif
            </div>
        @endforeach
    </div>
    @endif
    </div> {{-- 闭合page div --}}

    <script src="/js/katex.min.js"></script>
    <script src="/js/auto-render.min.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            try {
                renderMathInElement(document.body, {
                    delimiters: [
                        {left: "$$", right: "$$", display: true},
                        {left: "$", right: "$", display: false},
                        {left: "\\(", right: "\\)", display: false},
                        {left: "\\[", right: "\\]", display: true}
                    ],
                    throwOnError: false,
                    strict: false,
                    trust: true
                });
            } catch (e) {}
        });
    </script>
</body>
</html>
