<?php
declare(strict_types=1);

/**
 * Shared GES/WAEC-style exam paper renderer.
 *
 * Produces a formal Ghanaian examination paper: school letterhead with crest,
 * paper title block, candidate particulars, "For Examiner's Use Only" grid,
 * boxed instructions to candidates, lettered sections with marks in the right
 * margin, and "Turn over" / page-numbered footers.
 *
 * The two GES templates (standard and compact) are the same document at
 * different metrics — they call this with different $opt values.
 *
 * Output is mPDF-targeted HTML (table-based; no flexbox).
 */

function renderGesExamPaper(array $doc, array $opt): string
{
    $o = $opt + [
        'font'        => '11pt',
        'small'       => '9pt',
        'tiny'        => '8pt',
        'title'       => '13pt',
        'school'      => '17pt',
        'logo'        => 62,
        'pad'         => 6,
        'lineGap'     => 22,   // answer-line height in px
        'examinerBox' => true,
        'accent'      => '#000000',
        'serif'       => "'Times New Roman', Times, serif",
    ];

    $isKey  = !empty($doc['is_key']);
    $school = $doc['school'];
    $e      = static fn($v): string => htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8');

    // ── Page footer: page numbers + "Turn over" ──────────────────────────
    $footerLabel = $isKey ? 'MARKING SCHEME — CONFIDENTIAL' : $e($school['name']);
    $html = '<htmlpagefooter name="ges_ftr">'
          . '<table width="100%" style="border-top:0.6pt solid #444;font-family:' . $o['serif'] . ';font-size:' . $o['tiny'] . ';color:#333;padding-top:2px;"><tr>'
          . '<td width="40%" align="left">' . $footerLabel . '</td>'
          . '<td width="20%" align="center">Page {PAGENO} of {nbpg}</td>'
          . '<td width="40%" align="right"><em>{PAGENO:!=:nbpg:Turn over}</em></td>'
          . '</tr></table></htmlpagefooter>'
          . '<sethtmlpagefooter name="ges_ftr" value="on" />';

    // ── Stylesheet ───────────────────────────────────────────────────────
    $html .= '<style>
      body { font-family: ' . $o['serif'] . '; font-size: ' . $o['font'] . '; line-height: 1.4; color: #000; }
      .lh-name { font-size: ' . $o['school'] . '; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; }
      .lh-sub  { font-size: ' . $o['small'] . '; }
      .rule-thick { border-bottom: 2.2pt solid ' . $o['accent'] . '; margin: 3px 0 1px; }
      .rule-thin  { border-bottom: 0.7pt solid ' . $o['accent'] . '; margin-bottom: 6px; }
      .paper-title { text-align: center; font-size: ' . $o['title'] . '; font-weight: bold; text-transform: uppercase; letter-spacing: 1.5px; margin: 4px 0 2px; }
      .paper-sub { text-align: center; font-size: ' . $o['small'] . '; text-transform: uppercase; letter-spacing: 0.8px; margin-bottom: 6px; }
      .bar { width: 100%; border-top: 1pt solid #000; border-bottom: 1pt solid #000; font-size: ' . $o['small'] . '; text-transform: uppercase; font-weight: bold; }
      .bar td { padding: 3px 5px; }
      .cand { width: 100%; border: 1pt solid #000; font-size: ' . $o['small'] . '; margin-top: 6px; }
      .cand td { padding: ' . $o['pad'] . 'px 6px; }
      .dotted { border-bottom: 0.7pt dotted #333; }
      .exbox { width: 100%; border-collapse: collapse; font-size: ' . $o['tiny'] . '; margin-top: 6px; }
      .exbox th, .exbox td { border: 0.8pt solid #000; padding: 3px 4px; text-align: center; }
      .exbox th { background: #ececec; text-transform: uppercase; font-weight: bold; }
      .instr { border: 1.2pt solid #000; padding: ' . ($o['pad'] + 1) . 'px 8px; margin: 8px 0 10px; font-size: ' . $o['small'] . '; }
      .instr-h { font-weight: bold; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 3px; }
      .sec-h { background: #e8e8e8; border-top: 1.2pt solid #000; border-bottom: 1.2pt solid #000; padding: 4px 6px; margin: 12px 0 3px; font-weight: bold; text-transform: uppercase; font-size: ' . $o['small'] . '; letter-spacing: 0.8px; }
      .sec-i { font-style: italic; font-size: ' . $o['small'] . '; margin: 0 0 7px 2px; }
      .q { margin-bottom: ' . ($o['pad'] + 3) . 'px; }
      .q-txt { font-size: ' . $o['font'] . '; }
      .opts { margin: 3px 0 0 26px; }
      .opt { margin-bottom: 2px; }
      .passage { border: 0.8pt solid #666; background: #f6f6f6; padding: 7px 9px; margin: 5px 0 8px; font-size: ' . $o['small'] . '; }
      .aline { border-bottom: 0.7pt solid #999; height: ' . $o['lineGap'] . 'px; }
      .keybox { border: 0.9pt solid #0a5c0a; background: #f2fbf2; padding: 5px 7px; margin-top: 4px; font-size: ' . $o['small'] . '; }
      .keybox b { color: #0a5c0a; }
      .endmark { text-align: center; font-weight: bold; letter-spacing: 3px; text-transform: uppercase; margin-top: 16px; padding-top: 6px; border-top: 1.2pt solid #000; font-size: ' . $o['small'] . '; }
      .conf { text-align:center; border: 1.5pt solid #a00; color: #a00; font-weight: bold; text-transform: uppercase; letter-spacing: 2px; padding: 5px; margin-top: 6px; font-size: ' . $o['small'] . '; }
      svg { display: block !important; }
      table.mt { width:100%; border-collapse:collapse; margin-top:5px; font-size:' . $o['small'] . '; }
      table.mt td { vertical-align: top; padding-right: 10px; }
    </style>';

    // ── Letterhead ───────────────────────────────────────────────────────
    $html .= '<table width="100%"><tr>';
    if (!empty($school['logo'])) {
        $html .= '<td width="' . ($o['logo'] + 10) . '" style="vertical-align:middle;"><img src="' . $school['logo'] . '" width="' . $o['logo'] . '"></td>';
    }
    $html .= '<td style="text-align:center;vertical-align:middle;">';
    $html .= '<div class="lh-name">' . $e($school['name']) . '</div>';
    if (trim((string) $school['address']) !== '') {
        $html .= '<div class="lh-sub">' . $e($school['address']) . '</div>';
    }
    $contact = array_filter([$school['phone'], $school['email']]);
    if ($contact) {
        $html .= '<div class="lh-sub">' . implode(' &nbsp;|&nbsp; ', array_map($e, $contact)) . '</div>';
    }
    $html .= '</td>';
    if (!empty($school['logo'])) {
        $html .= '<td width="' . ($o['logo'] + 10) . '"></td>'; // balance the crest column
    }
    $html .= '</tr></table>';
    $html .= '<div class="rule-thick"></div><div class="rule-thin"></div>';

    // ── Paper title block ────────────────────────────────────────────────
    $titleLine = trim((string) $doc['title']);
    $html .= '<div class="paper-title">' . $e($titleLine) . ($isKey ? ' &mdash; Marking Scheme' : '') . '</div>';

    $subBits = array_filter([
        trim((string) $doc['term']) !== '' ? $doc['term'] : '',
        trim((string) $doc['academic_year']) !== '' ? $doc['academic_year'] . ' Academic Year' : '',
    ]);
    if ($subBits) {
        $html .= '<div class="paper-sub">' . implode(' &nbsp;&bull;&nbsp; ', array_map($e, $subBits)) . '</div>';
    }

    // Subject / class / duration / marks bar
    $dur = (int) $doc['duration_minutes'];
    $durTxt = $dur > 0 ? ($dur >= 60 ? floor($dur / 60) . 'hr' . ($dur % 60 ? ' ' . ($dur % 60) . 'min' : '') : $dur . ' min') : '—';
    $html .= '<table class="bar"><tr>'
          . '<td width="40%">Subject: ' . $e($doc['subject_name']) . '</td>'
          . '<td width="25%">Class: ' . $e($doc['class_name']) . '</td>'
          . '<td width="20%">Duration: ' . $e($durTxt) . '</td>'
          . '<td width="15%" align="right">Total: ' . (int) $doc['total_marks'] . '</td>'
          . '</tr></table>';

    // ── Candidate particulars / confidential banner ──────────────────────
    if ($isKey) {
        $html .= '<div class="conf">Confidential &mdash; For Examiner / Teacher Use Only</div>';
    } else {
        $html .= '<table class="cand"><tr>'
              . '<td width="58%">Candidate&rsquo;s Name: <span class="dotted">&nbsp;</span></td>'
              . '<td width="42%">Index No.: <span class="dotted">&nbsp;</span></td>'
              . '</tr><tr>'
              . '<td>Class: <span class="dotted">&nbsp;</span></td>'
              . '<td>Date: <span class="dotted">&nbsp;</span></td>'
              . '</tr></table>';

        // For Examiner's Use Only — one column per section plus total
        if ($o['examinerBox'] && !empty($doc['sections'])) {
            $html .= '<table class="exbox"><tr><th colspan="' . (count($doc['sections']) + 2) . '">For Examiner&rsquo;s Use Only</th></tr><tr><th>Section</th>';
            foreach ($doc['sections'] as $s) {
                $html .= '<th>' . $e($s['letter']) . '</th>';
            }
            $html .= '<th>Total</th></tr><tr><td>Marks</td>';
            foreach ($doc['sections'] as $_s) {
                $html .= '<td style="height:20px;">&nbsp;</td>';
            }
            $html .= '<td>&nbsp;</td></tr></table>';
        }
    }

    // ── Instructions to candidates ───────────────────────────────────────
    $instr = trim((string) $doc['instructions']);
    if ($instr !== '') {
        $html .= '<div class="instr"><div class="instr-h">Instructions to Candidates</div>'
               . nl2br($e($instr)) . '</div>';
    }

    // ── Sections ─────────────────────────────────────────────────────────
    foreach ($doc['sections'] as $section) {
        $marks = (int) $section['marks'];
        $html .= '<div class="sec-h">Section ' . $e($section['letter']) . ' &mdash; ' . $e($section['label'])
               . ' <span style="float:right;">[' . $marks . ' mark' . ($marks !== 1 ? 's' : '') . ']</span></div>';
        if (trim((string) $section['instruction']) !== '') {
            $html .= '<div class="sec-i">' . $e($section['instruction']) . '</div>';
        }
        if (trim((string) $section['passage']) !== '') {
            $html .= '<div class="passage"><b>Read the passage below and answer the questions that follow.</b><br><br>' . nl2br($e($section['passage'])) . '</div>';
        }

        foreach ($section['questions'] as $q) {
            $html .= renderGesQuestion($q, $section['type'], $isKey, $o, $e);
        }
    }

    $html .= '<div class="endmark">' . ($isKey ? 'End of Marking Scheme' : 'End of Paper') . '</div>';

    return $html;
}

/**
 * Render one question in GES house style: number, text, marks in the right
 * margin, then type-specific body (options, matching grid, answer lines…),
 * followed by the answer block when rendering a marking scheme.
 */
function renderGesQuestion(array $q, string $sectionType, bool $isKey, array $o, callable $e): string
{
    $marks = (int) $q['marks'];
    $marksTxt = $marks > 0 ? '[' . $marks . ' mark' . ($marks !== 1 ? 's' : '') . ']' : '';

    $html = '<div class="q"><table width="100%"><tr>'
          . '<td width="26" style="vertical-align:top;font-weight:bold;">' . (int) $q['number'] . '.</td>'
          . '<td style="vertical-align:top;" class="q-txt">' . $e($q['text']) . '</td>'
          . '<td width="72" style="vertical-align:top;text-align:right;white-space:nowrap;">' . $marksTxt . '</td>'
          . '</tr></table>';

    if ($q['diagram_html'] !== '') {
        $html .= $q['diagram_html'];
    }

    // Per-question comprehension passage (paper-sourced questions carry it here)
    if (trim((string) ($q['passage'] ?? '')) !== '') {
        $html .= '<div class="passage">' . nl2br($e($q['passage'])) . '</div>';
    }

    switch ($sectionType) {
        case 'mcq':
            if ($q['options']) {
                $html .= '<div class="opts">';
                foreach ($q['options'] as $letter => $text) {
                    $html .= '<div class="opt">' . $e($letter) . '. &nbsp;' . $e($text) . '</div>';
                }
                $html .= '</div>';
            }
            break;

        case 'true_false':
            $html .= '<div class="opts">True &nbsp;/&nbsp; False &nbsp;&nbsp;&nbsp;&nbsp;( ______________ )</div>';
            break;

        case 'matching':
            if (is_array($q['matching'])) {
                $html .= '<table class="mt"><tr><td width="50%"><b>Column A</b>';
                foreach ($q['matching']['left'] as $i => $lt) {
                    $html .= '<div class="opt">' . ($i + 1) . '. ' . $e($lt) . ' &nbsp;( ______ )</div>';
                }
                $html .= '</td><td width="50%"><b>Column B</b>';
                foreach ($q['matching']['right'] as $r) {
                    $html .= '<div class="opt">' . $e($r['letter']) . '. ' . $e($r['text']) . '</div>';
                }
                $html .= '</td></tr></table>';
            }
            break;

        case 'fill_blank':
            if (!$isKey) {
                $html .= '<div class="aline"></div>';
            }
            break;

        case 'comprehension':
            foreach ($q['subs'] as $si => $sq) {
                $sm = (int) $sq['marks'];
                $html .= '<div style="margin:5px 0 2px 20px;">(' . chr(97 + ($si % 26)) . ') ' . $e($sq['text'])
                       . ' <em>[' . $sm . ' mark' . ($sm !== 1 ? 's' : '') . ']</em></div>';
                if (!$isKey) {
                    for ($k = 0, $lines = max(2, $sm * 2); $k < $lines; $k++) {
                        $html .= '<div class="aline"></div>';
                    }
                }
            }
            break;

        case 'theory':
        default:
            if (!$isKey) {
                for ($i = 0, $lines = max(4, $marks * 3); $i < $lines; $i++) {
                    $html .= '<div class="aline"></div>';
                }
            }
            break;
    }

    // ── Marking scheme block ─────────────────────────────────────────────
    if ($isKey) {
        $parts = [];

        if ($sectionType === 'mcq' && $q['correct'] !== '') {
            $letter = strtoupper($q['correct']);
            $text   = $q['options'][$letter] ?? '';
            $parts[] = '<b>Correct option:</b> ' . $e($letter) . ($text !== '' ? '. ' . $e($text) : '');
        }
        if ($sectionType === 'true_false' && $q['correct'] !== '') {
            $parts[] = '<b>Answer:</b> ' . $e($q['correct']);
        }
        if ($sectionType === 'matching' && is_array($q['matching'])) {
            $pairs = [];
            foreach ($q['matching']['answer'] as $num => $letter) {
                $pairs[] = $num . ' &rarr; ' . $e($letter);
            }
            if ($pairs) {
                $parts[] = '<b>Matches:</b> ' . implode(', &nbsp;', $pairs);
            }
        }
        if ($sectionType === 'comprehension' && $q['subs']) {
            $sub = '';
            foreach ($q['subs'] as $si => $sq) {
                if (trim((string) $sq['model_answer']) === '') continue;
                $sub .= '<div>(' . chr(97 + ($si % 26)) . ') ' . $e($sq['model_answer']) . '</div>';
            }
            if ($sub !== '') {
                $parts[] = '<b>Expected answers:</b>' . $sub;
            }
        }
        if (trim((string) $q['model_answer']) !== '' && $sectionType !== 'comprehension') {
            $label = $sectionType === 'mcq' ? 'Explanation' : 'Expected answer';
            $parts[] = '<b>' . $label . ':</b> ' . nl2br($e($q['model_answer']));
        }
        if ($q['marking_guide']) {
            $li = '';
            foreach ($q['marking_guide'] as $point) {
                $li .= '<li>' . $e($point) . '</li>';
            }
            $parts[] = '<b>Marking guide:</b><ul style="margin:2px 0 0 16px;padding:0;">' . $li . '</ul>';
        }

        if ($parts) {
            $html .= '<div class="keybox">' . implode('<div style="height:3px;"></div>', $parts) . '</div>';
        }
    }

    $html .= '</div>';
    return $html;
}
