<?php
/**
 * Parent Portal — a child's academic progress (charts + subject table).
 *
 * Two hard guards, both server-side and non-negotiable:
 *   1. OWNERSHIP — the child must belong to THIS parent (parent_student_link).
 *      The child id from the request is never trusted on its own.
 *   2. PUBLISHED ONLY — a parent sees a term only after its report is published
 *      (report_details.is_published = 1), matching reports.php. Marks are never
 *      exposed before the school releases them.
 *
 * Gated on hasModule('progress_analytics').
 */
declare(strict_types=1);
session_start();
require_once '../../config.php';
require_once __DIR__ . '/../helpers.php';
require_once dirname(__DIR__, 2) . '/analytics/lib/progress_query.php';

header('Content-Type: application/json; charset=utf-8');

function pp_out(bool $ok, array $extra = [], string $msg = ''): never
{
    echo json_encode(array_merge(['success' => $ok, 'message' => $msg], $extra));
    exit;
}

if (empty($_SESSION['parent_id'])) {
    http_response_code(401);
    pp_out(false, [], 'Please sign in.');
}

$conn = portalGetConnection();
if (!$conn instanceof mysqli) {
    http_response_code(500);
    pp_out(false, [], 'Database unavailable.');
}

if (!hasModule('progress_analytics')) {
    pp_out(true, ['locked' => true], 'Progress Analytics is not enabled.');
}

$parentId  = (int) $_SESSION['parent_id'];
$childId   = (int) ($_GET['child_id'] ?? 0);

// Guard 1 — ownership.
if ($childId <= 0 || !portalParentOwnsStudent($conn, $parentId, $childId)) {
    http_response_code(403);
    pp_out(false, [], 'Not authorised for this student.');
}

// Guard 2 — published periods only.
$published = progressPublishedPeriods($conn, $childId);
if ($published === []) {
    pp_out(true, ['published' => false, 'periods' => []], 'No published reports yet.');
}

// Resolve the requested period, defaulting to the most recent published one.
// Reject anything not in the published set.
$reqTerm = trim((string) ($_GET['term'] ?? ''));
$reqYear = trim((string) ($_GET['academic_year'] ?? ''));
$selected = null;
foreach ($published as $p) {
    if ($reqTerm !== '' && $p['term'] === $reqTerm
        && ($reqYear === '' || $p['academic_year'] === $reqYear)) {
        $selected = $p;
        break;
    }
}
if ($selected === null) {
    $selected = $published[0]; // newest
}

$scope = progressNormalizeScope([
    'level'         => 'student',
    'student_id'    => $childId,
    'academic_year' => $selected['academic_year'],
    'term'          => $selected['term'],
], null);

pp_out(true, [
    'published'      => true,
    'periods'        => $published,
    'selected'       => $selected,
    'student'        => progressStudentHeader($conn, $childId),
    'kpis'           => progressKpis($conn, $scope),
    'attendance_rate'=> progressStudentAttendanceRate($conn, $childId, $selected['academic_year'], $selected['term']),
    'subjects'       => progressSubjectBreakdown($conn, $scope),
    'table'          => progressTableRows($conn, $scope),
    // Trend spans only the child's published terms.
    'trend'          => progressTrend($conn, $scope, $published),
]);
