<?php

/**
 * Progress Analytics — printable HTML for PDF export.
 *
 * Dompdf renders HTML/CSS, not <canvas>, so the on-screen Chart.js charts become
 * CSS bar rows here (a coloured div sized by width %). Same figures, same query
 * library — this is a print view of the same data, never a re-computation.
 */

if (!function_exists('getDBConnection')) {
    require_once dirname(__DIR__, 2) . '/config.php';
}
require_once dirname(__DIR__) . '/lib/progress_query.php';

/** HTML-escape shorthand. */
function pe_h($v): string { return htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8'); }

/** Format a numeric value to $dp decimals, or an em dash when null. */
function pe_n($v, int $dp = 1): string
{
    return ($v === null || $v === '') ? '—' : number_format((float) $v, $dp);
}

/** Grade → fill colour (matches the on-screen ordered ramp). */
function pe_grade_color(string $g): string
{
    return [
        'A' => '#0ca30c', 'B' => '#1baf7a', 'C' => '#eda100', 'D' => '#eb6834',
        'E' => '#e34948', 'F' => '#d03b3b', 'W' => '#b23b3b',
    ][$g] ?? '#9aa0a6';
}

/**
 * One CSS bar row: label, a track with a filled portion (value out of 100),
 * and the numeric value. Used for subject and grade breakdowns.
 */
function pe_bar(string $label, ?float $value, string $color, ?float $outOf = 100.0, ?string $valueText = null): string
{
    $pct = ($value === null || !$outOf) ? 0 : max(0, min(100, $value / $outOf * 100));
    $val = $valueText ?? pe_n($value, 1);
    return '<tr>'
        . '<td class="bl">' . pe_h($label) . '</td>'
        . '<td class="bt"><div class="track"><div class="fill" style="width:' . round($pct, 1) . '%;background:' . $color . '"></div></div></td>'
        . '<td class="bv">' . pe_h($val) . '</td>'
        . '</tr>';
}

/**
 * Build the complete printable document for a scope.
 *
 * @param array $opts  ['school'=>string, 'narrative'=>?string, 'generated_by'=>string]
 */
function progressExportHtml(mysqli $conn, array $scope, array $opts = []): string
{
    $school = $opts['school'] ?? 'EduTrack School';
    $genBy  = $opts['generated_by'] ?? '';
    $narrative = $opts['narrative'] ?? null;

    $kpis     = progressKpis($conn, $scope);
    $subjects = progressSubjectBreakdown($conn, $scope);
    $dist     = progressGradeDistribution($conn, $scope);
    $table    = progressTableRows($conn, $scope);

    $scopeLabel = match ($scope['level']) {
        'student' => 'Student',
        'class'   => 'Class: ' . (implode(', ', $scope['classes']) ?: '—'),
        default   => 'Whole school',
    };
    if ($scope['level'] === 'student' && $scope['student_id'] > 0) {
        $sh = progressStudentHeader($conn, $scope['student_id']);
        if ($sh) { $scopeLabel = 'Student: ' . $sh['name'] . ' (' . $sh['class'] . ')'; }
    }
    $period = ($scope['term'] ?: 'All terms') . ($scope['academic_year'] !== '' ? ' · ' . $scope['academic_year'] : '');

    // ── KPI cells ───────────────────────────────────────────────────────────
    $kpiCells = [
        ['Average', pe_n($kpis['avg_score'], 1)],
        ['Pass rate', $kpis['pass_rate'] === null ? '—' : pe_n($kpis['pass_rate'], 1) . '%'],
        [$scope['level'] === 'student' ? 'Best' : 'Top', pe_n($kpis['top_score'], 1)],
        ['Lowest', pe_n($kpis['low_score'], 1)],
        [$scope['level'] === 'student' ? 'Subjects' : 'Students', $scope['level'] === 'student' ? $kpis['results'] : $kpis['students']],
        ['Coverage', $kpis['coverage_pct'] === null ? '—' : pe_n($kpis['coverage_pct'], 0) . '%'],
    ];
    $kpiHtml = '<table class="kpis"><tr>';
    foreach ($kpiCells as $c) {
        $kpiHtml .= '<td><div class="kv">' . pe_h($c[1]) . '</div><div class="kl">' . pe_h($c[0]) . '</div></td>';
    }
    $kpiHtml .= '</tr></table>';

    // ── Subject bars ────────────────────────────────────────────────────────
    $subjHtml = '';
    foreach ($subjects as $s) {
        $subjHtml .= pe_bar($s['subject'], $s['avg_score'], '#2a78d6');
    }
    if ($subjHtml === '') { $subjHtml = '<tr><td colspan="3" class="empty">No subject data.</td></tr>'; }

    // ── Grade distribution bars (share of total) ────────────────────────────
    $gradeHtml = '';
    $gtotal = max(1, (int) $dist['total']);
    foreach ($dist['labels'] as $i => $g) {
        $count = (int) ($dist['counts'][$i] ?? 0);
        $gradeHtml .= pe_bar('Grade ' . $g, (float) $count, pe_grade_color($g), (float) $gtotal, (string) $count);
    }
    if ($gradeHtml === '') { $gradeHtml = '<tr><td colspan="3" class="empty">No grades.</td></tr>'; }

    // ── Breakdown table ─────────────────────────────────────────────────────
    $numKeys = ['avg_score' => 1, 'pass_rate' => 1, 'top_score' => 1, 'total_score' => 1,
                'class_score' => 1, 'exam_score' => 1, 'students' => 0, 'results' => 0,
                'subjects' => 0, 'position' => 0];
    $thead = '';
    foreach ($table['columns'] as $c) {
        $thead .= '<th' . (isset($numKeys[$c['key']]) ? ' class="num"' : '') . '>' . pe_h($c['label']) . '</th>';
    }
    $tbody = '';
    foreach ($table['rows'] as $r) {
        $tbody .= '<tr>';
        foreach ($table['columns'] as $c) {
            $k = $c['key'];
            $v = $r[$k] ?? null;
            if ($k === 'grade' && $v) {
                $tbody .= '<td><span class="gb" style="background:' . pe_grade_color((string) $v) . '">' . pe_h($v) . '</span></td>';
            } elseif (isset($numKeys[$k])) {
                $tbody .= '<td class="num">' . pe_n($v, $numKeys[$k]) . '</td>';
            } else {
                $tbody .= '<td>' . pe_h($v ?? '—') . '</td>';
            }
        }
        $tbody .= '</tr>';
    }
    if ($tbody === '') { $tbody = '<tr><td class="empty" colspan="' . count($table['columns']) . '">No results.</td></tr>'; }

    // ── Cohort movement (school/class only) ─────────────────────────────────
    $moveHtml = '';
    if ($scope['level'] !== 'student') {
        $mv = progressRankMovement($conn, $scope);
        if ($mv['to'] !== null && ($mv['improved'] !== [] || $mv['declined'] !== [])) {
            $row = function (array $list, string $cls) {
                if ($list === []) { return '<div class="mv-empty">None</div>'; }
                $out = '';
                foreach ($list as $d) {
                    $sign = $d['delta'] > 0 ? '+' : '';
                    $out .= '<div class="mv-row"><span>' . pe_h($d['name']) . '</span>'
                          . '<span class="' . $cls . '">' . $sign . pe_n($d['delta'], 1) . '</span></div>';
                }
                return $out;
            };
            $moveHtml = '<div class="section-title">Movement · ' . pe_h($mv['from']['label']) . ' → ' . pe_h($mv['to']['label']) . '</div>'
                . '<table class="mv"><tr>'
                . '<td><div class="mv-h up">Most improved</div>' . $row(array_slice($mv['improved'], 0, 5), 'up') . '</td>'
                . '<td><div class="mv-h down">Most declined</div>' . $row(array_slice($mv['declined'], 0, 5), 'down') . '</td>'
                . '</tr></table>';
        }
    }

    // ── AI narrative (optional) ─────────────────────────────────────────────
    $aiHtml = '';
    if ($narrative !== null && trim($narrative) !== '') {
        $aiHtml = '<div class="ai"><div class="section-title">AI summary</div>'
            . '<div class="ai-body">' . nl2br(pe_h($narrative)) . '</div>'
            . '<div class="ai-note">Generated by AI — verify against the figures above.</div></div>';
    }

    $coverageWarn = '';
    if ($kpis['coverage_pct'] !== null && $kpis['coverage_pct'] < 90) {
        $coverageWarn = '<div class="warn">Only ' . pe_n($kpis['coverage_pct'], 0)
            . '% of students in scope have marks entered — figures may be provisional.</div>';
    }

    $generated = date('j M Y, g:i a');
    $genLine = $genBy !== '' ? ('Generated by ' . pe_h($genBy) . ' · ' . $generated) : $generated;

    // ── Assemble ────────────────────────────────────────────────────────────
    return '<!DOCTYPE html><html><head><meta charset="utf-8"><style>
        * { font-family: "DejaVu Sans", sans-serif; }
        body { color:#1e293b; font-size:11px; margin:0; }
        .head { border-bottom:2px solid #2a78d6; padding-bottom:8px; margin-bottom:12px; }
        .head .sch { font-size:17px; font-weight:bold; color:#0b0b0b; }
        .head .ttl { font-size:12px; color:#2a78d6; font-weight:bold; margin-top:2px; }
        .head .meta { font-size:10px; color:#64748b; margin-top:3px; }
        .warn { background:#fff6e5; border:1px solid #ffe1a8; color:#8a5a00; padding:6px 8px; border-radius:4px; font-size:10px; margin-bottom:10px; }
        .kpis { width:100%; border-collapse:collapse; margin-bottom:14px; }
        .kpis td { border:1px solid #e5e7eb; text-align:center; padding:8px 4px; width:16.6%; }
        .kpis .kv { font-size:15px; font-weight:bold; color:#0b0b0b; }
        .kpis .kl { font-size:8px; text-transform:uppercase; color:#94a3b8; letter-spacing:.03em; margin-top:2px; }
        .section-title { font-size:12px; font-weight:bold; color:#0b0b0b; margin:14px 0 6px; border-bottom:1px solid #e5e7eb; padding-bottom:3px; }
        table.bars { width:100%; border-collapse:collapse; }
        table.bars td { padding:2px 0; vertical-align:middle; }
        td.bl { width:26%; font-size:10px; padding-right:6px; }
        td.bt { width:60%; }
        td.bv { width:14%; text-align:right; font-size:10px; font-weight:bold; padding-left:6px; }
        .track { background:#eef1f5; border-radius:3px; height:12px; width:100%; }
        .fill { height:12px; border-radius:3px; }
        table.data { width:100%; border-collapse:collapse; margin-top:4px; }
        table.data th { background:#f4f6f9; border-bottom:2px solid #e5e7eb; text-align:left; padding:5px 6px; font-size:9px; color:#64748b; text-transform:uppercase; }
        table.data td { border-bottom:1px solid #f1f5f9; padding:5px 6px; font-size:10px; }
        table.data .num, table.data th.num { text-align:right; }
        .gb { color:#fff; font-weight:bold; border-radius:3px; padding:1px 6px; }
        .empty { text-align:center; color:#94a3b8; padding:12px; }
        table.mv { width:100%; border-collapse:collapse; }
        table.mv td { width:50%; vertical-align:top; padding:0 8px; }
        .mv-h { font-size:9px; text-transform:uppercase; font-weight:bold; margin-bottom:4px; }
        .mv-h.up { color:#0a6b0a; } .mv-h.down { color:#a11; }
        .mv-row { border-bottom:1px solid #f1f5f9; padding:3px 0; font-size:10px; }
        .mv-row span:first-child { display:inline-block; width:70%; }
        .mv-row .up { color:#0a6b0a; font-weight:bold; } .mv-row .down { color:#a11; font-weight:bold; }
        .mv-empty { color:#94a3b8; font-size:10px; padding:3px 0; }
        .ai { margin-top:14px; border-left:3px solid #2a78d6; padding-left:10px; }
        .ai-body { font-size:10.5px; line-height:1.5; }
        .ai-note { font-size:8.5px; color:#94a3b8; margin-top:4px; font-style:italic; }
        .foot { margin-top:16px; border-top:1px solid #e5e7eb; padding-top:6px; font-size:8.5px; color:#94a3b8; text-align:center; }
    </style></head><body>'
    . '<div class="head"><div class="sch">' . pe_h($school) . '</div>'
    . '<div class="ttl">Progress Analytics Report</div>'
    . '<div class="meta">' . pe_h($scopeLabel) . ' &nbsp;•&nbsp; ' . pe_h($period) . '</div></div>'
    . $coverageWarn
    . $kpiHtml
    . $aiHtml
    . '<div class="section-title">Subject performance</div><table class="bars">' . $subjHtml . '</table>'
    . '<div class="section-title">Grade distribution</div><table class="bars">' . $gradeHtml . '</table>'
    . $moveHtml
    . '<div class="section-title">Breakdown</div><table class="data"><thead><tr>' . $thead . '</tr></thead><tbody>' . $tbody . '</tbody></table>'
    . '<div class="foot">' . $genLine . ' · EduTrack Progress Analytics</div>'
    . '</body></html>';
}
