<?php

declare(strict_types=1);

require_once __DIR__ . '/../../library/auth.php';
require_once __DIR__ . '/../helpers/result-helper.php';

allow_roles(['admin', 'teacher']);

requirePostRequest();
verifyCsrfToken();

$school_id = (int) $_SESSION['school_id'];
$session_id = (int) ($_SESSION['session_id'] ?? 0);
$user_id = (int) ($_SESSION['user_id'] ?? 0);

/*
|--------------------------------------------------------------------------
| VALIDATE INPUT PLUGINS
|--------------------------------------------------------------------------
*/
$student_session_id = validateId($_POST['student_session_id'] ?? 0);
$student_id = validateId($_POST['student_id'] ?? 0);
$exam_type_id = validateId($_POST['exam_type_id'] ?? 0);
$class_id = validateId($_POST['class_id'] ?? 0);

$subject_ids = $_POST['subject_id'] ?? [];
$marks_obtained = $_POST['marks_obtained'] ?? [];
$total_marks = $_POST['total_marks'] ?? [];
$schedule_ids = $_POST['schedule_id'] ?? [];
$attendance_status = $_POST['attendance_status'] ?? [];
$remarks = $_POST['remarks'] ?? [];

if (
    $student_session_id <= 0 ||
    $student_id <= 0 ||
    $exam_type_id <= 0 ||
    $class_id <= 0 ||
    $session_id <= 0 ||
    empty($subject_ids)
) {
    jsonResponse(false, 'Invalid request payload metadata context!');
}

/*
|--------------------------------------------------------------------------
| VERIFY STUDENT ACADEMIC SESSION INTEGRITY
|--------------------------------------------------------------------------
*/
$studentStmt = $pdo->prepare("
    SELECT id 
    FROM student_sessions
    WHERE school_id = ?
    AND session_id = ?
    AND class_id = ?
    AND student_id = ?
    AND id = ?
    LIMIT 1
");

$studentStmt->execute([
    $school_id,
    $session_id,
    $class_id,
    $student_id,
    $student_session_id
]);

if (!$studentStmt->fetch()) {
    jsonResponse(false, 'Verification failed: Student session mismatched!');
}

try {
    /*
    |--------------------------------------------------------------------------
    | BEGIN SQL TRANSACTION
    |--------------------------------------------------------------------------
    */
    $pdo->beginTransaction();

    /*
    |--------------------------------------------------------------------------
    | PREPARE SAVE / UPSERT EXAM MARKS STATEMENT
    |--------------------------------------------------------------------------
    */
    $saveStmt = $pdo->prepare("
        INSERT INTO exam_marks (
            school_id,
            session_id,
            exam_type_id,
            class_id,
            schedule_id,
            student_id,
            subject_id,
            marks_obtained,
            total_marks,
            attendance_status,
            remarks
        ) VALUES (
            ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
        )
        ON DUPLICATE KEY UPDATE
            marks_obtained = VALUES(marks_obtained),
            total_marks = VALUES(total_marks),
            attendance_status = VALUES(attendance_status),
            remarks = VALUES(remarks),
            updated_at = CURRENT_TIMESTAMP
    ");

    /*
    |--------------------------------------------------------------------------
    | ITERATE SUBJECT MARKS DISPATCH PIPELINE
    |--------------------------------------------------------------------------
    */
    foreach ($subject_ids as $sub_id) {
        $subject_id = validateId($sub_id);
        if ($subject_id <= 0) {
            continue;
        }

        // Extract and balance values inside mapped keys safely
        $rawObtained = $marks_obtained[$subject_id] ?? 0;
        $rawMaxMarks = $total_marks[$subject_id] ?? 0;

        // Secure fallback checking for empty string values
        $obtained = ($rawObtained === '') ? 0.0 : (float) $rawObtained;
        $maxMarks = ($rawMaxMarks === '') ? 0.0 : (float) $rawMaxMarks;

        $schedule_id = validateId($schedule_ids[$subject_id] ?? 0);
        $attendance = trim((string)($attendance_status[$subject_id] ?? 'Present'));
        $remark = trim((string)($remarks[$subject_id] ?? ''));

        // Enforce strong strict standard constraints on attendance values
        if (!in_array($attendance, ['Present', 'Absent'], true)) {
            $attendance = 'Present';
        }

        // Auto-override marks reset payload if user flagged as Absent
        if ($attendance === 'Absent') {
            $obtained = 0.0;
        }

        // Validate range bounds integrity
        if ($obtained < 0.0 || $obtained > $maxMarks) {
            throw new Exception("Invalid marks entered for subject ID: {$subject_id}. Marks cannot exceed maximum threshold limit.");
        }

        /*
        |--------------------------------------------------------------------------
        | VERIFY EXAM SCHEDULE RELATIONAL KEY
        |--------------------------------------------------------------------------
        */
        $scheduleStmt = $pdo->prepare("
            SELECT id 
            FROM exam_schedule
            WHERE school_id = ?
            AND session_id = ?
            AND exam_type_id = ?
            AND class_id = ?
            AND subject_id = ?
            AND id = ?
            LIMIT 1
        ");

        $scheduleStmt->execute([
            $school_id,
            $session_id,
            $exam_type_id,
            $class_id,
            $subject_id,
            $schedule_id
        ]);

        if (!$scheduleStmt->fetch()) {
            throw new Exception("Security Alert: Course mapping mismatch or invalid schedule identity detected!");
        }

        /*
        |--------------------------------------------------------------------------
        | EXECUTE RECORD INGESTION
        |--------------------------------------------------------------------------
        */
        $saveStmt->execute([
            $school_id,
            $session_id,
            $exam_type_id,
            $class_id,
            $schedule_id,
            $student_id,
            $subject_id,
            $obtained,
            $maxMarks,
            $attendance,
            $remark
        ]);
    }

    /*
    |--------------------------------------------------------------------------
    | WRITE LOG AUDIT DEPLOYMENT
    |--------------------------------------------------------------------------
    */
    $auditStmt = $pdo->prepare("
        INSERT INTO audit_logs (
            school_id,
            user_id,
            module,
            action,
            record_id,
            message,
            ip_address,
            user_agent
        ) VALUES (
            ?, ?, ?, ?, ?, ?, ?, ?
        )
    ");

    $auditStmt->execute([
        $school_id,
        $user_id,
        'Exams',
        'Save Marks',
        $student_id,
        "Student marks saved/updated across active subject sets safely.",
        $_SERVER['REMOTE_ADDR'] ?? '',
        $_SERVER['HTTP_USER_AGENT'] ?? ''
    ]);

    /*
    |--------------------------------------------------------------------------
    | COMMIT TRANSACTION CONTEXT SAFELY
    |--------------------------------------------------------------------------
    */
    $pdo->commit();

    jsonResponse(true, 'Marks saved successfully!');

} catch (Throwable $e) {
    /*
    |--------------------------------------------------------------------------
    | ROLLBACK ACTIVE SEGMENTS ON FAILURE
    |--------------------------------------------------------------------------
    */
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    jsonResponse(false, $e->getMessage());
}