<?php
declare(strict_types=1);

/*
|--------------------------------------------------------------------------
| SMI Core Periods
| Premium Mobile Student Exam Center
|--------------------------------------------------------------------------
| File: public_html/student-gateway/student/exams.php
|--------------------------------------------------------------------------
| PART 1 / 5
|--------------------------------------------------------------------------
*/

require_once __DIR__ . '/../includes/config.php';
require_once __DIR__ . '/../includes/db.php';
require_once __DIR__ . '/../includes/functions.php';
require_once __DIR__ . '/../includes/student-auth.php';

if (file_exists(__DIR__ . '/../includes/student-course-context.php')) {
    require_once __DIR__ . '/../includes/student-course-context.php';
}

date_default_timezone_set('Asia/Riyadh');

$pdo = db();

if (function_exists('requireStudent')) {
    requireStudent();
} elseif (function_exists('requireStudentLogin')) {
    requireStudentLogin();
}

/*
|--------------------------------------------------------------------------
| Safe Helpers
|--------------------------------------------------------------------------
*/

if (!function_exists('e')) {
    function e($value): string
    {
        return htmlspecialchars((string)($value ?? ''), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    }
}

if (!function_exists('safeOne')) {
    function safeOne(PDO $pdo, string $sql, array $params = []): ?array
    {
        try {
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            return $row ?: null;
        } catch (Throwable $e) {
            return null;
        }
    }
}

if (!function_exists('safeAll')) {
    function safeAll(PDO $pdo, string $sql, array $params = []): array
    {
        try {
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
        } catch (Throwable $e) {
            return [];
        }
    }
}

if (!function_exists('safeCount')) {
    function safeCount(PDO $pdo, string $sql, array $params = []): int
    {
        try {
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            return (int)$stmt->fetchColumn();
        } catch (Throwable $e) {
            return 0;
        }
    }
}

if (!function_exists('tableExists')) {
    function tableExists(PDO $pdo, string $table): bool
    {
        try {
            $stmt = $pdo->prepare("
                SELECT COUNT(*)
                FROM information_schema.TABLES
                WHERE TABLE_SCHEMA = DATABASE()
                  AND TABLE_NAME = ?
            ");
            $stmt->execute([$table]);
            return (int)$stmt->fetchColumn() > 0;
        } catch (Throwable $e) {
            return false;
        }
    }
}

if (!function_exists('columnExists')) {
    function columnExists(PDO $pdo, string $table, string $column): bool
    {
        try {
            $stmt = $pdo->prepare("
                SELECT COUNT(*)
                FROM information_schema.COLUMNS
                WHERE TABLE_SCHEMA = DATABASE()
                  AND TABLE_NAME = ?
                  AND COLUMN_NAME = ?
            ");
            $stmt->execute([$table, $column]);
            return (int)$stmt->fetchColumn() > 0;
        } catch (Throwable $e) {
            return false;
        }
    }
}

if (!function_exists('redirectToUrl')) {
    function redirectToUrl(string $url): void
    {
        header('Location: ' . $url);
        exit;
    }
}

if (!function_exists('mysqlDateTimeToTimestamp')) {
    function mysqlDateTimeToTimestamp($value): ?int
    {
        if (empty($value) || $value === '0000-00-00 00:00:00') {
            return null;
        }

        $timestamp = strtotime((string)$value);
        return $timestamp ?: null;
    }
}

if (!function_exists('formatExamDateTime')) {
    function formatExamDateTime($value): string
    {
        $timestamp = mysqlDateTimeToTimestamp($value);
        return $timestamp ? date('M d, Y · h:i A', $timestamp) : 'Open schedule';
    }
}

if (!function_exists('formatMinutes')) {
    function formatMinutes($value): string
    {
        return max(1, (int)$value) . ' min';
    }
}

if (!function_exists('pickValue')) {
    function pickValue(array $row, array $keys, string $default = ''): string
    {
        foreach ($keys as $key) {
            if (isset($row[$key]) && trim((string)$row[$key]) !== '') {
                return (string)$row[$key];
            }
        }
        return $default;
    }
}

if (!function_exists('resolveAssetUrl')) {
    function resolveAssetUrl(string $url): string
    {
        $url = trim($url);

        if ($url === '') return '';
        if (preg_match('/^https?:\/\//i', $url)) return $url;
        if (str_starts_with($url, '/')) return $url;

        return '../' . ltrim($url, '/');
    }
}

/*
|--------------------------------------------------------------------------
| Student
|--------------------------------------------------------------------------
*/

$studentId = 0;

if (!empty($_SESSION['student_id'])) {
    $studentId = (int)$_SESSION['student_id'];
} elseif (!empty($_SESSION['student']['id'])) {
    $studentId = (int)$_SESSION['student']['id'];
} elseif (function_exists('currentStudent')) {
    $currentStudent = currentStudent($pdo);
    $studentId = (int)($currentStudent['id'] ?? 0);
}

if ($studentId <= 0) {
    die('Student session was not found. Please login again.');
}

$student = safeOne($pdo, "SELECT * FROM students WHERE id = ? LIMIT 1", [$studentId]);

if (!$student) {
    die('Student account was not found.');
}

$studentName = (string)($student['full_name'] ?? 'Student');
$studentCode = (string)($student['student_code'] ?? '');

/*
|--------------------------------------------------------------------------
| Language
|--------------------------------------------------------------------------
*/

$lang = (string)($_GET['lang'] ?? $_SESSION['student_lang'] ?? 'en');

if (!in_array($lang, ['en', 'ar'], true)) {
    $lang = 'en';
}

$_SESSION['student_lang'] = $lang;

$dir = $lang === 'ar' ? 'rtl' : 'ltr';

$TEXT = [
    'en' => [
        'title' => 'Exam Center',
        'subtitle' => 'Smart, secure, and focused assessment area.',
        'course_dashboard' => 'Course Dashboard',
        'available_exams' => 'Available Exams',
        'start_exam' => 'Start Exam',
        'resume_exam' => 'Resume',
        'view_result' => 'Result',
        'completed' => 'Completed',
        'open' => 'Open',
        'closed' => 'Closed',
        'waiting' => 'Waiting',
        'duration' => 'Duration',
        'questions' => 'Questions',
        'attempts' => 'Attempts',
        'exam_code' => 'Exam Code',
        'enter_code' => 'Enter exam code',
        'before_start' => 'Before you start',
        'rule_1' => 'Stay inside the exam screen until submission.',
        'rule_2' => 'Your answers are saved automatically while you type.',
        'rule_3' => 'Submit before the timer ends.',
        'question' => 'Question',
        'submit_exam' => 'Submit Exam',
        'time_left' => 'Time Left',
        'answered' => 'Answered',
        'autosaved' => 'Autosaved',
        'no_exams' => 'No exams are available for this course right now.',
        'no_questions' => 'No questions were found for this exam.',
        'submit_warning' => 'Submit your exam? You cannot edit your answers after submission.',
        'score' => 'Score',
        'status' => 'Status',
        'attempt' => 'Attempt',
        'mark_review' => 'Review',
        'navigator' => 'Navigator',
    ],
    'ar' => [
        'title' => 'مركز الاختبارات',
        'subtitle' => 'منطقة اختبارات ذكية وآمنة ومريحة للتركيز.',
        'course_dashboard' => 'لوحة الدورة',
        'available_exams' => 'الاختبارات المتاحة',
        'start_exam' => 'بدء الاختبار',
        'resume_exam' => 'متابعة',
        'view_result' => 'النتيجة',
        'completed' => 'مكتمل',
        'open' => 'مفتوح',
        'closed' => 'مغلق',
        'waiting' => 'بانتظار الوقت',
        'duration' => 'المدة',
        'questions' => 'الأسئلة',
        'attempts' => 'المحاولات',
        'exam_code' => 'كود الاختبار',
        'enter_code' => 'أدخل كود الاختبار',
        'before_start' => 'قبل البدء',
        'rule_1' => 'ابق داخل شاشة الاختبار حتى التسليم.',
        'rule_2' => 'يتم حفظ إجاباتك تلقائيًا أثناء الكتابة.',
        'rule_3' => 'سلّم الاختبار قبل انتهاء المؤقت.',
        'question' => 'السؤال',
        'submit_exam' => 'تسليم الاختبار',
        'time_left' => 'الوقت المتبقي',
        'answered' => 'تمت الإجابة',
        'autosaved' => 'تم الحفظ',
        'no_exams' => 'لا توجد اختبارات متاحة لهذه الدورة حاليًا.',
        'no_questions' => 'لا توجد أسئلة لهذا الاختبار.',
        'submit_warning' => 'هل تريد تسليم الاختبار؟ لا يمكنك تعديل الإجابات بعد التسليم.',
        'score' => 'الدرجة',
        'status' => 'الحالة',
        'attempt' => 'المحاولة',
        'mark_review' => 'مراجعة',
        'navigator' => 'التنقل',
    ],
];

function trText(string $key): string
{
    global $TEXT, $lang;
    return (string)($TEXT[$lang][$key] ?? $TEXT['en'][$key] ?? $key);
}

/*
|--------------------------------------------------------------------------
| Labels
|--------------------------------------------------------------------------
*/

if (!function_exists('examTypeLabel')) {
    function examTypeLabel(string $type): string
    {
        return match ($type) {
            'midterm' => 'Midterm',
            'final' => 'Final',
            'quiz' => 'Quiz',
            'practice' => 'Practice',
            'placement' => 'Placement',
            'reading' => 'Reading',
            'listening' => 'Listening',
            'speaking' => 'Speaking',
            'writing' => 'Writing',
            'story' => 'Story',
            'sra' => 'SRA',
            default => ucfirst(str_replace('_', ' ', $type)),
        };
    }
}

if (!function_exists('questionTypeLabel')) {
    function questionTypeLabel(string $type): string
    {
        return match ($type) {
            'multiple_choice' => 'Multiple Choice',
            'true_false' => 'True / False',
            'fill_blank' => 'Fill Blank',
            'short_answer' => 'Short Answer',
            'essay' => 'Essay',
            'reading' => 'Reading',
            'listening' => 'Listening',
            default => ucfirst(str_replace('_', ' ', $type)),
        };
    }
}

if (!function_exists('examIcon')) {
    function examIcon(string $type): string
    {
        return match ($type) {
            'reading', 'story', 'sra' => '📖',
            'listening' => '🎧',
            'speaking' => '🎙️',
            'writing', 'essay' => '✍️',
            'quiz', 'practice' => '⚡',
            'final' => '🏆',
            'midterm' => '📝',
            'placement' => '🎯',
            default => '🧠',
        };
    }
}

/*
|--------------------------------------------------------------------------
| CSRF
|--------------------------------------------------------------------------
*/

if (empty($_SESSION['student_exam_csrf'])) {
    $_SESSION['student_exam_csrf'] = bin2hex(random_bytes(32));
}

$csrfToken = (string)$_SESSION['student_exam_csrf'];

function verifyStudentExamCsrf(): void
{
    $token = (string)($_POST['csrf_token'] ?? '');

    if (
        empty($_SESSION['student_exam_csrf']) ||
        !hash_equals((string)$_SESSION['student_exam_csrf'], $token)
    ) {
        throw new Exception('Security token expired. Please refresh the page.');
    }
}

/*
|--------------------------------------------------------------------------
| Course Context
|--------------------------------------------------------------------------
*/

$courseId = (int)($_GET['course_id'] ?? $_POST['course_id'] ?? $_SESSION['selected_core_course_id'] ?? 0);

if ($courseId <= 0 && function_exists('getSelectedStudentCourseId')) {
    $courseId = (int)getSelectedStudentCourseId($pdo, $studentId);
}

if ($courseId <= 0) {
    $firstCourse = safeOne(
        $pdo,
        "
        SELECT c.*
        FROM core_course_students cs
        INNER JOIN core_courses c ON c.id = cs.course_id
        WHERE cs.student_id = ?
          AND cs.status IN ('active','approved','enrolled')
        ORDER BY cs.id DESC
        LIMIT 1
        ",
        [$studentId]
    );

    if ($firstCourse) {
        $courseId = (int)$firstCourse['id'];
    }
}

if ($courseId <= 0) {
    redirectToUrl('courses.php');
}

$isEnrolled = safeCount(
    $pdo,
    "
    SELECT COUNT(*)
    FROM core_course_students
    WHERE student_id = ?
      AND course_id = ?
      AND status IN ('active','approved','enrolled')
    ",
    [$studentId, $courseId]
) > 0;

if (!$isEnrolled) {
    redirectToUrl('courses.php');
}

$_SESSION['selected_core_course_id'] = $courseId;

$course = safeOne($pdo, "SELECT * FROM core_courses WHERE id = ? LIMIT 1", [$courseId]);

$courseTitle = (string)($course['title'] ?? 'Core Course');
$courseCode = (string)($course['course_code'] ?? '');

/*
|--------------------------------------------------------------------------
| Required Tables
|--------------------------------------------------------------------------
*/

$requiredTables = [
    'core_exams',
    'core_exam_questions',
    'core_exam_options',
    'core_exam_attempts',
    'core_exam_answers'
];

foreach ($requiredTables as $table) {
    if (!tableExists($pdo, $table)) {
        die('Missing required table: ' . e($table));
    }
}

/*
|--------------------------------------------------------------------------
| Page State
|--------------------------------------------------------------------------
*/

$view = (string)($_GET['view'] ?? 'list');
$allowedViews = ['list', 'lobby', 'take', 'result'];

if (!in_array($view, $allowedViews, true)) {
    $view = 'list';
}

$examId = (int)($_GET['exam_id'] ?? $_POST['exam_id'] ?? 0);
$attemptId = (int)($_GET['attempt_id'] ?? $_POST['attempt_id'] ?? 0);

$errorMessage = '';
$successMessage = '';



/*
|--------------------------------------------------------------------------
| Exam Open Logic
|--------------------------------------------------------------------------
*/

if (!function_exists('isExamOpenForStudent')) {
    function isExamOpenForStudent(array $exam): array
    {
        $now = time();

        $startAt = mysqlDateTimeToTimestamp($exam['start_at'] ?? null);
        $endAt   = mysqlDateTimeToTimestamp($exam['end_at'] ?? null);

        if ($startAt !== null && $now < $startAt) {
            return [
                'open' => false,
                'reason' => 'not_started',
                'message' => 'This exam will open at ' . date('Y-m-d h:i A', $startAt),
            ];
        }

        if ($endAt !== null && $now > $endAt) {
            return [
                'open' => false,
                'reason' => 'closed',
                'message' => 'This exam is closed.',
            ];
        }

        return [
            'open' => true,
            'reason' => 'open',
            'message' => 'Exam is open.',
        ];
    }
}

if (!function_exists('examStatusClass')) {
    function examStatusClass(array $exam): string
    {
        $check = isExamOpenForStudent($exam);

        if ($check['open']) {
            return 'is-open';
        }

        if ($check['reason'] === 'not_started') {
            return 'is-waiting';
        }

        return 'is-closed';
    }
}

if (!function_exists('examStatusLabel')) {
    function examStatusLabel(array $exam): string
    {
        $check = isExamOpenForStudent($exam);

        if ($check['open']) {
            return trText('open');
        }

        if ($check['reason'] === 'not_started') {
            return trText('waiting');
        }

        return trText('closed');
    }
}

/*
|--------------------------------------------------------------------------
| Exam Fetching
|--------------------------------------------------------------------------
*/

if (!function_exists('getStudentExam')) {
    function getStudentExam(PDO $pdo, int $examId, int $courseId): ?array
    {
        if ($examId <= 0 || $courseId <= 0) {
            return null;
        }

        return safeOne(
            $pdo,
            "
            SELECT
                e.*,
                c.title AS course_title,
                c.course_code
            FROM core_exams e
            INNER JOIN core_courses c ON c.id = e.course_id
            WHERE e.id = ?
              AND e.course_id = ?
              AND e.status = 'published'
            LIMIT 1
            ",
            [$examId, $courseId]
        );
    }
}

/*
|--------------------------------------------------------------------------
| Attempts Helpers
|--------------------------------------------------------------------------
*/

if (!function_exists('logExamActivity')) {
    function logExamActivity(
        PDO $pdo,
        int $examId,
        ?int $attemptId,
        int $studentId,
        string $eventType,
        string $eventDetail = ''
    ): void {
        if (!tableExists($pdo, 'core_exam_activity_logs')) {
            return;
        }

        try {
            $stmt = $pdo->prepare("
                INSERT INTO core_exam_activity_logs (
                    exam_id,
                    attempt_id,
                    student_id,
                    event_type,
                    event_detail,
                    ip_address,
                    user_agent,
                    created_at
                ) VALUES (
                    ?, ?, ?, ?, ?, ?, ?, NOW()
                )
            ");

            $stmt->execute([
                $examId,
                $attemptId,
                $studentId,
                $eventType,
                $eventDetail,
                $_SERVER['REMOTE_ADDR'] ?? '',
                $_SERVER['HTTP_USER_AGENT'] ?? ''
            ]);
        } catch (Throwable $e) {
            return;
        }
    }
}

if (!function_exists('getAttemptCount')) {
    function getAttemptCount(PDO $pdo, int $examId, int $studentId): int
    {
        return safeCount(
            $pdo,
            "
            SELECT COUNT(*)
            FROM core_exam_attempts
            WHERE exam_id = ?
              AND student_id = ?
              AND status <> 'cancelled'
            ",
            [$examId, $studentId]
        );
    }
}

if (!function_exists('getActiveAttempt')) {
    function getActiveAttempt(PDO $pdo, int $examId, int $studentId): ?array
    {
        return safeOne(
            $pdo,
            "
            SELECT *
            FROM core_exam_attempts
            WHERE exam_id = ?
              AND student_id = ?
              AND status = 'in_progress'
            ORDER BY id DESC
            LIMIT 1
            ",
            [$examId, $studentId]
        );
    }
}

if (!function_exists('getLatestAttempt')) {
    function getLatestAttempt(PDO $pdo, int $examId, int $studentId): ?array
    {
        return safeOne(
            $pdo,
            "
            SELECT *
            FROM core_exam_attempts
            WHERE exam_id = ?
              AND student_id = ?
              AND status <> 'cancelled'
            ORDER BY id DESC
            LIMIT 1
            ",
            [$examId, $studentId]
        );
    }
}

if (!function_exists('expireAttemptIfNeeded')) {
    function expireAttemptIfNeeded(PDO $pdo, array $attempt): array
    {
        if (!$attempt) {
            return [];
        }

        if ((string)($attempt['status'] ?? '') !== 'in_progress') {
            return $attempt;
        }

        $expiresAt = mysqlDateTimeToTimestamp($attempt['expires_at'] ?? null);

        if ($expiresAt !== null && time() > $expiresAt) {
            $updates = [
                "status = 'expired'",
                "updated_at = NOW()"
            ];

            $sql = "
                UPDATE core_exam_attempts
                SET " . implode(', ', $updates) . "
                WHERE id = ?
            ";

            $pdo->prepare($sql)->execute([(int)$attempt['id']]);

            $attempt['status'] = 'expired';
        }

        return $attempt;
    }
}

if (!function_exists('createStudentAttempt')) {
    function createStudentAttempt(PDO $pdo, array $exam, int $studentId, string $examCodeUsed = ''): array
    {
        $examId = (int)$exam['id'];
        $courseId = (int)$exam['course_id'];
        $durationMinutes = max(1, (int)($exam['duration_minutes'] ?? 60));
        $attemptNumber = getAttemptCount($pdo, $examId, $studentId) + 1;
        $expiresAt = date('Y-m-d H:i:s', strtotime('+' . $durationMinutes . ' minutes'));

        $columns = [
            'exam_id',
            'course_id',
            'student_id',
            'attempt_number',
            'started_at',
            'expires_at',
            'status',
            'total_score',
            'percentage',
            'result_status',
            'created_at',
            'updated_at'
        ];

        $placeholders = [
            '?',
            '?',
            '?',
            '?',
            'NOW()',
            '?',
            "'in_progress'",
            '0',
            '0',
            "'pending'",
            'NOW()',
            'NOW()'
        ];

        $values = [
            $examId,
            $courseId,
            $studentId,
            $attemptNumber,
            $expiresAt
        ];

        if (columnExists($pdo, 'core_exam_attempts', 'exam_code_used')) {
            $columns[] = 'exam_code_used';
            $placeholders[] = '?';
            $values[] = $examCodeUsed;
        }

        if (columnExists($pdo, 'core_exam_attempts', 'auto_graded_score')) {
            $columns[] = 'auto_graded_score';
            $placeholders[] = '0';
        }

        if (columnExists($pdo, 'core_exam_attempts', 'manual_graded_score')) {
            $columns[] = 'manual_graded_score';
            $placeholders[] = '0';
        }

        if (columnExists($pdo, 'core_exam_attempts', 'suspicious_events_count')) {
            $columns[] = 'suspicious_events_count';
            $placeholders[] = '0';
        }

        $sql = "
            INSERT INTO core_exam_attempts (
                " . implode(', ', $columns) . "
            ) VALUES (
                " . implode(', ', $placeholders) . "
            )
        ";

        $stmt = $pdo->prepare($sql);
        $stmt->execute($values);

        $attemptId = (int)$pdo->lastInsertId();

        logExamActivity(
            $pdo,
            $examId,
            $attemptId,
            $studentId,
            'attempt_started',
            'Student started exam.'
        );

        return safeOne(
            $pdo,
            "SELECT * FROM core_exam_attempts WHERE id = ? LIMIT 1",
            [$attemptId]
        ) ?: [];
    }
}

/*
|--------------------------------------------------------------------------
| Question Helpers
|--------------------------------------------------------------------------
*/

if (!function_exists('getQuestionPassage')) {
    function getQuestionPassage(array $question): string
    {
        return pickValue($question, [
            'reading_passage',
            'passage_text',
            'question_passage',
            'content_text'
        ]);
    }
}

if (!function_exists('getQuestionAudio')) {
    function getQuestionAudio(array $question): string
    {
        return pickValue($question, [
            'audio_url',
            'listening_audio',
            'media_url',
            'attachment_url'
        ]);
    }
}

if (!function_exists('getQuestionImage')) {
    function getQuestionImage(array $question): string
    {
        return pickValue($question, [
            'image_url',
            'question_image',
            'media_image'
        ]);
    }
}

if (!function_exists('loadQuestionOptions')) {
    function loadQuestionOptions(PDO $pdo, int $questionId): array
    {
        return safeAll(
            $pdo,
            "
            SELECT
                id,
                option_text,
                is_correct,
                sort_order
            FROM core_exam_options
            WHERE question_id = ?
            ORDER BY sort_order ASC, id ASC
            ",
            [$questionId]
        );
    }
}

if (!function_exists('normalizeAnswerText')) {
    function normalizeAnswerText(string $value): string
    {
        $value = trim(mb_strtolower($value, 'UTF-8'));
        return preg_replace('/\s+/u', ' ', $value) ?? $value;
    }
}

if (!function_exists('loadExamQuestions')) {
    function loadExamQuestions(PDO $pdo, array $exam): array
    {
        $orderSql = (int)($exam['shuffle_questions'] ?? 0) === 1
            ? "ORDER BY RAND()"
            : "ORDER BY sort_order ASC, id ASC";

        $questions = safeAll(
            $pdo,
            "
            SELECT *
            FROM core_exam_questions
            WHERE exam_id = ?
            $orderSql
            ",
            [(int)$exam['id']]
        );

        foreach ($questions as &$question) {
            $questionId = (int)$question['id'];
            $type = (string)($question['question_type'] ?? '');

            $question['options'] = loadQuestionOptions($pdo, $questionId);

            if ($type === 'true_false' && empty($question['options'])) {
                $correct = normalizeAnswerText((string)($question['correct_answer'] ?? ''));

                $question['options'] = [
                    [
                        'id' => 'TF_TRUE_' . $questionId,
                        'option_text' => 'True',
                        'is_correct' => $correct === 'true' ? 1 : 0
                    ],
                    [
                        'id' => 'TF_FALSE_' . $questionId,
                        'option_text' => 'False',
                        'is_correct' => $correct === 'false' ? 1 : 0
                    ]
                ];
            }
        }

        unset($question);

        return $questions;
    }
}

/*
|--------------------------------------------------------------------------
| Grade Answers
|--------------------------------------------------------------------------
*/

if (!function_exists('gradeStudentAnswer')) {
    function gradeStudentAnswer(PDO $pdo, array $question, $rawAnswer): array
    {
        $questionId = (int)$question['id'];
        $type = (string)($question['question_type'] ?? '');
        $marks = (float)($question['marks'] ?? 0);
        $correctAnswer = (string)($question['correct_answer'] ?? '');

        $answerText = '';
        $selectedOptionId = null;
        $score = 0.00;
        $isCorrect = null;

        $optionBasedTypes = [
            'multiple_choice',
            'true_false',
            'reading',
            'listening'
        ];

        if (in_array($type, $optionBasedTypes, true) && !empty($question['options'])) {
            $value = trim((string)$rawAnswer);

            if (is_numeric($value)) {
                $selectedOptionId = (int)$value;

                $option = safeOne(
                    $pdo,
                    "
                    SELECT *
                    FROM core_exam_options
                    WHERE id = ?
                      AND question_id = ?
                    LIMIT 1
                    ",
                    [$selectedOptionId, $questionId]
                );

                if ($option && (int)($option['is_correct'] ?? 0) === 1) {
                    $score = $marks;
                    $isCorrect = 1;
                } else {
                    $score = 0;
                    $isCorrect = 0;
                }
            } else {
                $answerText = $value;
                $studentAnswer = normalizeAnswerText($answerText);
                $rightAnswer = normalizeAnswerText($correctAnswer);

                if ($studentAnswer !== '' && $studentAnswer === $rightAnswer) {
                    $score = $marks;
                    $isCorrect = 1;
                } else {
                    $score = 0;
                    $isCorrect = 0;
                }
            }
        } elseif ($type === 'fill_blank') {
            $answerText = trim((string)$rawAnswer);
            $studentAnswer = normalizeAnswerText($answerText);
            $rightAnswer = normalizeAnswerText($correctAnswer);

            $acceptedAnswers = array_filter(
                array_map('trim', explode('|', $rightAnswer))
            );

            if (in_array($studentAnswer, $acceptedAnswers, true)) {
                $score = $marks;
                $isCorrect = 1;
            } else {
                $score = 0;
                $isCorrect = 0;
            }
        } else {
            $answerText = trim((string)$rawAnswer);
            $score = 0;
            $isCorrect = null;
        }

        return [
            'answer_text' => $answerText !== '' ? $answerText : null,
            'selected_option_id' => $selectedOptionId,
            'score' => $score,
            'is_correct' => $isCorrect
        ];
    }
}

/*
|--------------------------------------------------------------------------
| Recalculate Score
|--------------------------------------------------------------------------
*/

if (!function_exists('recalculateAttemptScore')) {
    function recalculateAttemptScore(PDO $pdo, int $attemptId): void
    {
        $attempt = safeOne(
            $pdo,
            "SELECT * FROM core_exam_attempts WHERE id = ? LIMIT 1",
            [$attemptId]
        );

        if (!$attempt) {
            return;
        }

        $exam = safeOne(
            $pdo,
            "SELECT * FROM core_exams WHERE id = ? LIMIT 1",
            [(int)$attempt['exam_id']]
        );

        if (!$exam) {
            return;
        }

        $totalRow = safeOne(
            $pdo,
            "
            SELECT COALESCE(SUM(marks), 0) AS total_marks
            FROM core_exam_questions
            WHERE exam_id = ?
            ",
            [(int)$exam['id']]
        );

        $totalMarks = (float)($totalRow['total_marks'] ?? 0);

        if ($totalMarks <= 0) {
            $totalMarks = (float)($exam['total_marks'] ?? 0);
        }

        $scoreRow = safeOne(
            $pdo,
            "
            SELECT
                COALESCE(SUM(score_awarded), 0) AS score,
                SUM(CASE WHEN is_correct IS NULL THEN 1 ELSE 0 END) AS manual_pending
            FROM core_exam_answers
            WHERE attempt_id = ?
            ",
            [$attemptId]
        );

        $score = (float)($scoreRow['score'] ?? 0);
        $manualPending = (int)($scoreRow['manual_pending'] ?? 0);

        $percentage = $totalMarks > 0
            ? round(($score / $totalMarks) * 100, 2)
            : 0.00;

        $passingMarks = (float)($exam['passing_marks'] ?? 0);

        if ($manualPending > 0) {
            $attemptStatus = 'submitted';
            $resultStatus = 'pending';
        } else {
            $attemptStatus = 'graded';
            $resultStatus = $score >= $passingMarks ? 'pass' : 'fail';
        }

        $updates = [
            'total_score = ?',
            'percentage = ?',
            'result_status = ?',
            'status = ?',
            'submitted_at = COALESCE(submitted_at, NOW())',
            'updated_at = NOW()'
        ];

        $values = [
            $score,
            $percentage,
            $resultStatus,
            $attemptStatus
        ];

        if (columnExists($pdo, 'core_exam_attempts', 'auto_graded_score')) {
            $autoScoreRow = safeOne(
                $pdo,
                "
                SELECT COALESCE(SUM(a.score_awarded), 0) AS auto_score
                FROM core_exam_answers a
                INNER JOIN core_exam_questions q ON q.id = a.question_id
                WHERE a.attempt_id = ?
                  AND q.question_type IN (
                        'multiple_choice',
                        'true_false',
                        'fill_blank',
                        'reading',
                        'listening'
                  )
                ",
                [$attemptId]
            );

            $updates[] = 'auto_graded_score = ?';
            $values[] = (float)($autoScoreRow['auto_score'] ?? 0);
        }

        if (columnExists($pdo, 'core_exam_attempts', 'manual_graded_score')) {
            $manualScoreRow = safeOne(
                $pdo,
                "
                SELECT COALESCE(SUM(a.score_awarded), 0) AS manual_score
                FROM core_exam_answers a
                INNER JOIN core_exam_questions q ON q.id = a.question_id
                WHERE a.attempt_id = ?
                  AND q.question_type NOT IN (
                        'multiple_choice',
                        'true_false',
                        'fill_blank',
                        'reading',
                        'listening'
                  )
                ",
                [$attemptId]
            );

            $updates[] = 'manual_graded_score = ?';
            $values[] = (float)($manualScoreRow['manual_score'] ?? 0);
        }

        $values[] = $attemptId;

        $sql = "
            UPDATE core_exam_attempts
            SET " . implode(', ', $updates) . "
            WHERE id = ?
        ";

        $pdo->prepare($sql)->execute($values);
    }
}

/*
|--------------------------------------------------------------------------
| POST Actions
|--------------------------------------------------------------------------
*/

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    $action = (string)($_POST['action'] ?? '');

    /*
    |--------------------------------------------------------------------------
    | AJAX Autosave
    |--------------------------------------------------------------------------
    */

    if ($action === 'autosave_exam') {
        header('Content-Type: application/json; charset=utf-8');

        try {
            verifyStudentExamCsrf();

            $postedExamId = (int)($_POST['exam_id'] ?? 0);
            $postedAttemptId = (int)($_POST['attempt_id'] ?? 0);
            $answers = $_POST['answers'] ?? [];

            if (!is_array($answers)) {
                $answers = [];
            }

            $attempt = safeOne(
                $pdo,
                "
                SELECT *
                FROM core_exam_attempts
                WHERE id = ?
                  AND exam_id = ?
                  AND student_id = ?
                  AND status = 'in_progress'
                LIMIT 1
                ",
                [$postedAttemptId, $postedExamId, $studentId]
            );

            if (!$attempt) {
                throw new Exception('Attempt not found.');
            }

            $attempt = expireAttemptIfNeeded($pdo, $attempt);

            if ((string)($attempt['status'] ?? '') !== 'in_progress') {
                throw new Exception('Attempt expired.');
            }

            if (!tableExists($pdo, 'core_exam_autosaves')) {
                throw new Exception('Exam autosave storage is not installed. Ask the administrator to run the database upgrade.');
            }

            $answersJson = json_encode($answers, JSON_UNESCAPED_UNICODE);

            $exists = safeOne(
                $pdo,
                "
                SELECT id
                FROM core_exam_autosaves
                WHERE attempt_id = ?
                LIMIT 1
                ",
                [$postedAttemptId]
            );

            if ($exists) {
                $stmt = $pdo->prepare("
                    UPDATE core_exam_autosaves
                    SET answers_json = ?, updated_at = NOW()
                    WHERE attempt_id = ?
                ");

                $stmt->execute([$answersJson, $postedAttemptId]);
            } else {
                $stmt = $pdo->prepare("
                    INSERT INTO core_exam_autosaves (
                        attempt_id,
                        exam_id,
                        student_id,
                        answers_json,
                        saved_at,
                        updated_at
                    ) VALUES (
                        ?, ?, ?, ?, NOW(), NOW()
                    )
                ");

                $stmt->execute([
                    $postedAttemptId,
                    $postedExamId,
                    $studentId,
                    $answersJson
                ]);
            }

            if (columnExists($pdo, 'core_exam_attempts', 'last_autosave_at')) {
                $pdo->prepare("
                    UPDATE core_exam_attempts
                    SET last_autosave_at = NOW(), updated_at = NOW()
                    WHERE id = ?
                ")->execute([$postedAttemptId]);
            } else {
                $pdo->prepare("
                    UPDATE core_exam_attempts
                    SET updated_at = NOW()
                    WHERE id = ?
                ")->execute([$postedAttemptId]);
            }

            echo json_encode([
                'success' => true,
                'message' => trText('autosaved'),
                'saved_at' => date('h:i:s A')
            ], JSON_UNESCAPED_UNICODE);

        } catch (Throwable $e) {
            echo json_encode([
                'success' => false,
                'message' => $e->getMessage()
            ], JSON_UNESCAPED_UNICODE);
        }

        exit;
    }

    /*
    |--------------------------------------------------------------------------
    | AJAX Security Event
    |--------------------------------------------------------------------------
    */

    if ($action === 'log_exam_event') {
        header('Content-Type: application/json; charset=utf-8');

        try {
            verifyStudentExamCsrf();

            $postedExamId = (int)($_POST['exam_id'] ?? 0);
            $postedAttemptId = (int)($_POST['attempt_id'] ?? 0);
            $eventType = trim((string)($_POST['event_type'] ?? 'unknown'));

            $attempt = safeOne(
                $pdo,
                "
                SELECT *
                FROM core_exam_attempts
                WHERE id = ?
                  AND exam_id = ?
                  AND student_id = ?
                LIMIT 1
                ",
                [$postedAttemptId, $postedExamId, $studentId]
            );

            if (!$attempt) {
                throw new Exception('Attempt not found.');
            }

            if (columnExists($pdo, 'core_exam_attempts', 'suspicious_events_count')) {
                $pdo->prepare("
                    UPDATE core_exam_attempts
                    SET suspicious_events_count = suspicious_events_count + 1,
                        updated_at = NOW()
                    WHERE id = ?
                ")->execute([$postedAttemptId]);
            }

            logExamActivity(
                $pdo,
                $postedExamId,
                $postedAttemptId,
                $studentId,
                $eventType,
                'Security event recorded.'
            );

            echo json_encode(['success' => true], JSON_UNESCAPED_UNICODE);

        } catch (Throwable $e) {
            echo json_encode(['success' => false], JSON_UNESCAPED_UNICODE);
        }

        exit;
    }

    /*
    |--------------------------------------------------------------------------
    | Start Exam
    |--------------------------------------------------------------------------
    */

    if ($action === 'start_exam') {
        try {
            verifyStudentExamCsrf();

            $postedExamId = (int)($_POST['exam_id'] ?? 0);
            $examCode = trim((string)($_POST['exam_code'] ?? ''));

            $exam = getStudentExam($pdo, $postedExamId, $courseId);

            if (!$exam) {
                throw new Exception('Exam was not found.');
            }
            if (function_exists('isStudentActiveInCourse') && !isStudentActiveInCourse($pdo, $studentId, (int)$exam['course_id'])) {
                throw new Exception('This course is archived or inactive, so new exam attempts are not allowed.');
            }

            $openCheck = isExamOpenForStudent($exam);

            if (!$openCheck['open']) {
                throw new Exception($openCheck['message']);
            }

            $activeAttempt = getActiveAttempt($pdo, (int)$exam['id'], $studentId);

            if ($activeAttempt) {
                $activeAttempt = expireAttemptIfNeeded($pdo, $activeAttempt);

                if ((string)($activeAttempt['status'] ?? '') === 'in_progress') {
                    redirectToUrl(
                        'exams.php?view=take'
                        . '&course_id=' . (int)$courseId
                        . '&exam_id=' . (int)$exam['id']
                        . '&attempt_id=' . (int)$activeAttempt['id']
                    );
                }
            }

            $attemptCount = getAttemptCount($pdo, (int)$exam['id'], $studentId);
            $maxAttempts = max(1, (int)($exam['max_attempts'] ?? 1));

            if ($attemptCount >= $maxAttempts) {
                throw new Exception('You have already completed this exam.');
            }

            if ((int)($exam['require_exam_code'] ?? 0) === 1) {
                $realCode = trim((string)($exam['exam_code'] ?? ''));

                if ($examCode === '') {
                    throw new Exception('Please enter the exam code.');
                }

                if (strtoupper($examCode) !== strtoupper($realCode)) {
                    logExamActivity(
                        $pdo,
                        (int)$exam['id'],
                        null,
                        $studentId,
                        'wrong_exam_code',
                        'Student entered wrong exam code.'
                    );

                    throw new Exception('Invalid exam code.');
                }
            }

            $questionsCount = safeCount(
                $pdo,
                "
                SELECT COUNT(*)
                FROM core_exam_questions
                WHERE exam_id = ?
                ",
                [(int)$exam['id']]
            );

            if ($questionsCount <= 0) {
                throw new Exception('This exam has no questions yet.');
            }

            $attempt = createStudentAttempt($pdo, $exam, $studentId, $examCode);

            if (!$attempt) {
                throw new Exception('Could not create exam attempt.');
            }

            redirectToUrl(
                'exams.php?view=take'
                . '&course_id=' . (int)$courseId
                . '&exam_id=' . (int)$exam['id']
                . '&attempt_id=' . (int)$attempt['id']
            );

        } catch (Throwable $e) {
            $errorMessage = $e->getMessage();
            $view = 'lobby';
            $examId = (int)($_POST['exam_id'] ?? $examId);
        }
    }

    /*
    |--------------------------------------------------------------------------
    | Submit Exam
    |--------------------------------------------------------------------------
    */

    if ($action === 'submit_exam') {
        try {
            verifyStudentExamCsrf();

            $postedExamId = (int)($_POST['exam_id'] ?? 0);
            $postedAttemptId = (int)($_POST['attempt_id'] ?? 0);
            $answers = $_POST['answers'] ?? [];

            if (!is_array($answers)) {
                $answers = [];
            }

            $exam = getStudentExam($pdo, $postedExamId, $courseId);

            if (!$exam) {
                throw new Exception('Exam was not found.');
            }

            $attempt = safeOne(
                $pdo,
                "
                SELECT *
                FROM core_exam_attempts
                WHERE id = ?
                  AND exam_id = ?
                  AND student_id = ?
                  AND status = 'in_progress'
                LIMIT 1
                ",
                [$postedAttemptId, $postedExamId, $studentId]
            );

            if (!$attempt) {
                throw new Exception('Attempt was not found or already submitted.');
            }

            $attempt = expireAttemptIfNeeded($pdo, $attempt);

            if ((string)($attempt['status'] ?? '') !== 'in_progress') {
                throw new Exception('Attempt expired.');
            }

            $questions = loadExamQuestions($pdo, $exam);

            if (!$questions) {
                throw new Exception('This exam has no questions.');
            }

            $pdo->beginTransaction();

            foreach ($questions as $question) {
                $questionId = (int)$question['id'];
                $rawAnswer = $answers[$questionId] ?? '';

                $grade = gradeStudentAnswer($pdo, $question, $rawAnswer);

                $existing = safeOne(
                    $pdo,
                    "
                    SELECT id
                    FROM core_exam_answers
                    WHERE attempt_id = ?
                      AND question_id = ?
                    LIMIT 1
                    ",
                    [$postedAttemptId, $questionId]
                );

                if ($existing) {
                    $stmt = $pdo->prepare("
                        UPDATE core_exam_answers
                        SET
                            answer_text = ?,
                            selected_option_id = ?,
                            is_correct = ?,
                            score_awarded = ?,
                            updated_at = NOW()
                        WHERE id = ?
                    ");

                    $stmt->execute([
                        $grade['answer_text'],
                        $grade['selected_option_id'],
                        $grade['is_correct'],
                        $grade['score'],
                        (int)$existing['id']
                    ]);
                } else {
                    $stmt = $pdo->prepare("
                        INSERT INTO core_exam_answers (
                            attempt_id,
                            exam_id,
                            question_id,
                            student_id,
                            answer_text,
                            selected_option_id,
                            is_correct,
                            score_awarded,
                            created_at,
                            updated_at
                        ) VALUES (
                            ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW()
                        )
                    ");

                    $stmt->execute([
                        $postedAttemptId,
                        $postedExamId,
                        $questionId,
                        $studentId,
                        $grade['answer_text'],
                        $grade['selected_option_id'],
                        $grade['is_correct'],
                        $grade['score']
                    ]);
                }
            }

            $pdo->prepare("
                UPDATE core_exam_attempts
                SET submitted_at = NOW(),
                    status = 'submitted',
                    updated_at = NOW()
                WHERE id = ?
            ")->execute([$postedAttemptId]);

            $pdo->commit();

            recalculateAttemptScore($pdo, $postedAttemptId);

            logExamActivity(
                $pdo,
                $postedExamId,
                $postedAttemptId,
                $studentId,
                'attempt_submitted',
                'Student submitted official exam.'
            );

            redirectToUrl(
                'exams.php?view=result'
                . '&course_id=' . (int)$courseId
                . '&exam_id=' . (int)$postedExamId
                . '&attempt_id=' . (int)$postedAttemptId
            );

        } catch (Throwable $e) {
            if ($pdo->inTransaction()) {
                $pdo->rollBack();
            }

            $errorMessage = $e->getMessage();
            $view = 'take';
            $examId = (int)($_POST['exam_id'] ?? $examId);
            $attemptId = (int)($_POST['attempt_id'] ?? $attemptId);
        }
    }
}

/*
|--------------------------------------------------------------------------
| Runtime Data
|--------------------------------------------------------------------------
*/

$availableExams = [];
$currentExam = null;
$currentAttempt = null;
$latestAttempt = null;
$examQuestions = [];
$autosavedAnswers = [];
$attemptAnswers = [];

/*
|--------------------------------------------------------------------------
| Available Exams
|--------------------------------------------------------------------------
*/

$availableExams = safeAll(
    $pdo,
    "
    SELECT
        e.*,
        c.title AS course_title,

        (
            SELECT COUNT(*)
            FROM core_exam_questions q
            WHERE q.exam_id = e.id
        ) AS questions_count,

        (
            SELECT COUNT(*)
            FROM core_exam_attempts a
            WHERE a.exam_id = e.id
              AND a.student_id = ?
              AND a.status <> 'cancelled'
        ) AS my_attempts_count,

        (
            SELECT a.id
            FROM core_exam_attempts a
            WHERE a.exam_id = e.id
              AND a.student_id = ?
              AND a.status = 'in_progress'
            ORDER BY a.id DESC
            LIMIT 1
        ) AS active_attempt_id,

        (
            SELECT a.id
            FROM core_exam_attempts a
            WHERE a.exam_id = e.id
              AND a.student_id = ?
              AND a.status <> 'cancelled'
            ORDER BY a.id DESC
            LIMIT 1
        ) AS latest_attempt_id,

        (
            SELECT a.percentage
            FROM core_exam_attempts a
            WHERE a.exam_id = e.id
              AND a.student_id = ?
              AND a.status <> 'cancelled'
            ORDER BY a.id DESC
            LIMIT 1
        ) AS latest_percentage,

        (
            SELECT a.result_status
            FROM core_exam_attempts a
            WHERE a.exam_id = e.id
              AND a.student_id = ?
              AND a.status <> 'cancelled'
            ORDER BY a.id DESC
            LIMIT 1
        ) AS latest_result_status

    FROM core_exams e

    INNER JOIN core_courses c ON c.id = e.course_id

    WHERE e.course_id = ?
      AND e.status = 'published'

    ORDER BY
        CASE WHEN e.start_at IS NULL THEN 0 ELSE 1 END ASC,
        e.start_at ASC,
        e.id DESC
    ",
    [
        $studentId,
        $studentId,
        $studentId,
        $studentId,
        $studentId,
        $courseId
    ]
);

/*
|--------------------------------------------------------------------------
| Current Exam
|--------------------------------------------------------------------------
*/

if ($examId > 0) {
    $currentExam = getStudentExam($pdo, $examId, $courseId);

    if (!$currentExam) {
        $errorMessage = 'Exam was not found or is not available.';
        $view = 'list';
    }
}

if ($currentExam) {
    $latestAttempt = getLatestAttempt($pdo, (int)$currentExam['id'], $studentId);

    if ($latestAttempt) {
        $latestAttempt = expireAttemptIfNeeded($pdo, $latestAttempt);
    }
}

/*
|--------------------------------------------------------------------------
| Lobby
|--------------------------------------------------------------------------
*/

if ($view === 'lobby') {
    if (!$currentExam) {
        $errorMessage = 'Exam was not found.';
        $view = 'list';
    } else {
        $openCheck = isExamOpenForStudent($currentExam);

        if (!$openCheck['open']) {
            $errorMessage = $openCheck['message'];
        }
    }
}

/*
|--------------------------------------------------------------------------
| Take Exam
|--------------------------------------------------------------------------
*/

if ($view === 'take') {
    if (!$currentExam) {
        $errorMessage = 'Exam was not found.';
        $view = 'list';
    } else {
        if ($attemptId <= 0) {
            $activeAttempt = getActiveAttempt($pdo, (int)$currentExam['id'], $studentId);

            if ($activeAttempt) {
                $attemptId = (int)$activeAttempt['id'];
            }
        }

        $currentAttempt = safeOne(
            $pdo,
            "
            SELECT *
            FROM core_exam_attempts
            WHERE id = ?
              AND exam_id = ?
              AND student_id = ?
            LIMIT 1
            ",
            [$attemptId, (int)$currentExam['id'], $studentId]
        );

        if (!$currentAttempt) {
            $errorMessage = 'Attempt was not found.';
            $view = 'lobby';
        } else {
            $currentAttempt = expireAttemptIfNeeded($pdo, $currentAttempt);

            if ((string)($currentAttempt['status'] ?? '') !== 'in_progress') {
                redirectToUrl(
                    'exams.php?view=result'
                    . '&course_id=' . (int)$courseId
                    . '&exam_id=' . (int)$currentExam['id']
                    . '&attempt_id=' . (int)$currentAttempt['id']
                );
            }

            $examQuestions = loadExamQuestions($pdo, $currentExam);

            if (tableExists($pdo, 'core_exam_autosaves')) {
                $autosave = safeOne(
                    $pdo,
                    "
                    SELECT *
                    FROM core_exam_autosaves
                    WHERE attempt_id = ?
                      AND student_id = ?
                    LIMIT 1
                    ",
                    [(int)$currentAttempt['id'], $studentId]
                );

                if ($autosave && !empty($autosave['answers_json'])) {
                    $decoded = json_decode((string)$autosave['answers_json'], true);

                    if (is_array($decoded)) {
                        $autosavedAnswers = $decoded;
                    }
                }
            }

            $existingAnswers = safeAll(
                $pdo,
                "
                SELECT *
                FROM core_exam_answers
                WHERE attempt_id = ?
                  AND student_id = ?
                ",
                [(int)$currentAttempt['id'], $studentId]
            );

            foreach ($existingAnswers as $answer) {
                $qid = (int)$answer['question_id'];

                if (!empty($answer['selected_option_id'])) {
                    $autosavedAnswers[$qid] = (string)$answer['selected_option_id'];
                } elseif (!empty($answer['answer_text'])) {
                    $autosavedAnswers[$qid] = (string)$answer['answer_text'];
                }
            }

            logExamActivity(
                $pdo,
                (int)$currentExam['id'],
                (int)$currentAttempt['id'],
                $studentId,
                'exam_opened',
                'Student opened exam page.'
            );
        }
    }
}

/*
|--------------------------------------------------------------------------
| Result
|--------------------------------------------------------------------------
*/

if ($view === 'result') {
    if (!$currentExam) {
        $errorMessage = 'Exam was not found.';
        $view = 'list';
    } else {
        if ($attemptId <= 0 && $latestAttempt) {
            $attemptId = (int)$latestAttempt['id'];
        }

        $currentAttempt = safeOne(
            $pdo,
            "
            SELECT *
            FROM core_exam_attempts
            WHERE id = ?
              AND exam_id = ?
              AND student_id = ?
              AND status <> 'cancelled'
            LIMIT 1
            ",
            [$attemptId, (int)$currentExam['id'], $studentId]
        );

        if (!$currentAttempt) {
            $errorMessage = 'Result was not found.';
            $view = 'list';
        } else {
            $attemptAnswers = safeAll(
                $pdo,
                "
                SELECT
                    ans.*,
                    q.question_text,
                    q.question_type,
                    q.correct_answer,
                    q.explanation,
                    q.marks,
                    opt.option_text AS selected_option_text
                FROM core_exam_answers ans
                INNER JOIN core_exam_questions q ON q.id = ans.question_id
                LEFT JOIN core_exam_options opt ON opt.id = ans.selected_option_id
                WHERE ans.attempt_id = ?
                  AND ans.student_id = ?
                ORDER BY q.sort_order ASC, q.id ASC
                ",
                [(int)$currentAttempt['id'], $studentId]
            );
        }
    }
}

/*
|--------------------------------------------------------------------------
| UI Computed Values
|--------------------------------------------------------------------------
*/

$remainingSeconds = 0;

if ($currentAttempt && !empty($currentAttempt['expires_at'])) {
    $expires = mysqlDateTimeToTimestamp($currentAttempt['expires_at']);

    if ($expires !== null) {
        $remainingSeconds = max(0, $expires - time());
    }
}

$totalQuestions = count($examQuestions);
$answeredCount = 0;

if ($examQuestions) {
    foreach ($examQuestions as $q) {
        $qid = (int)$q['id'];

        if (isset($autosavedAnswers[$qid]) && trim((string)$autosavedAnswers[$qid]) !== '') {
            $answeredCount++;
        }
    }
}

$progressPercent = $totalQuestions > 0
    ? (int)round(($answeredCount / $totalQuestions) * 100)
    : 0;
?>

<!DOCTYPE html>
<html lang="<?php echo e($lang); ?>" dir="<?php echo e($dir); ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

<title><?php echo e(trText('title')); ?></title>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=Tajawal:wght@400;500;700;800;900&display=swap" rel="stylesheet">

<style>
:root{
    --bg:#f5f7fb;
    --card:#ffffff;
    --dark:#07111f;
    --muted:#64748b;
    --line:#e2e8f0;
    --blue:#2563eb;
    --blue2:#1d4ed8;
    --purple:#7c3aed;
    --green:#059669;
    --red:#dc2626;
    --orange:#ea580c;
    --soft:#f8fafc;
    --radius:28px;
    --shadow:0 18px 45px rgba(15,23,42,.08);
    --shadow2:0 22px 70px rgba(37,99,235,.18);
}

*{
    box-sizing:border-box;
    margin:0;
    padding:0;
}

html{
    scroll-behavior:smooth;
}

body{
    min-height:100vh;
    background:
        radial-gradient(circle at top left, rgba(37,99,235,.16), transparent 30%),
        radial-gradient(circle at top right, rgba(124,58,237,.12), transparent 28%),
        linear-gradient(180deg,#f8fbff 0%,#eef2ff 100%);
    color:var(--dark);
    font-family:<?php echo $lang === 'ar' ? "'Tajawal',sans-serif" : "'Inter',sans-serif"; ?>;
    padding-bottom:104px;
}

a{
    color:inherit;
    text-decoration:none;
}

button,
input,
textarea{
    font-family:inherit;
}

.exam-app{
    width:100%;
    max-width:520px;
    margin:0 auto;
    padding:14px;
}

.mobile-top{
    position:sticky;
    top:0;
    z-index:100;
    margin:-14px -14px 14px;
    padding:14px 14px 12px;
    background:rgba(245,247,251,.88);
    backdrop-filter:blur(20px);
    border-bottom:1px solid rgba(226,232,240,.7);
}

.top-row{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:10px;
}

.brand-mini{
    display:flex;
    align-items:center;
    gap:10px;
    min-width:0;
}

.brand-mark{
    width:44px;
    height:44px;
    border-radius:18px;
    background:linear-gradient(135deg,#0f172a,#2563eb,#7c3aed);
    color:white;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:14px;
    font-weight:900;
    box-shadow:0 14px 32px rgba(37,99,235,.25);
    flex-shrink:0;
}

.brand-text{
    min-width:0;
}

.brand-text strong{
    display:block;
    font-size:16px;
    font-weight:900;
    letter-spacing:-.4px;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
}

.brand-text span{
    display:block;
    margin-top:3px;
    color:var(--muted);
    font-size:11px;
    font-weight:800;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
}

.icon-btn{
    width:44px;
    height:44px;
    border:0;
    border-radius:17px;
    background:#fff;
    border:1px solid var(--line);
    display:flex;
    align-items:center;
    justify-content:center;
    font-weight:900;
    box-shadow:0 10px 25px rgba(15,23,42,.06);
}

.hero{
    position:relative;
    overflow:hidden;
    border-radius:32px;
    padding:22px;
    color:white;
    background:
        radial-gradient(circle at top right,rgba(255,255,255,.22),transparent 34%),
        linear-gradient(135deg,#08111f,#1e3a8a,#4c1d95);
    box-shadow:var(--shadow2);
    margin-bottom:16px;
}

.hero:after{
    content:"";
    position:absolute;
    width:150px;
    height:150px;
    border-radius:50%;
    right:-70px;
    bottom:-70px;
    background:rgba(255,255,255,.11);
}

.hero-kicker{
    position:relative;
    z-index:2;
    display:inline-flex;
    padding:7px 10px;
    border-radius:999px;
    background:rgba(255,255,255,.14);
    border:1px solid rgba(255,255,255,.18);
    font-size:11px;
    font-weight:900;
    margin-bottom:12px;
}

.hero h1{
    position:relative;
    z-index:2;
    font-size:27px;
    line-height:1.2;
    font-weight:900;
    letter-spacing:-.8px;
    margin-bottom:8px;
}

.hero p{
    position:relative;
    z-index:2;
    color:#dbeafe;
    font-size:13px;
    line-height:1.7;
    font-weight:750;
}

.hero-course{
    position:relative;
    z-index:2;
    margin-top:16px;
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:10px;
    padding:12px;
    border-radius:22px;
    background:rgba(255,255,255,.12);
    border:1px solid rgba(255,255,255,.16);
}

.hero-course strong{
    display:block;
    font-size:13px;
    font-weight:900;
}

.hero-course span{
    display:block;
    margin-top:4px;
    color:#cbd5e1;
    font-size:11px;
    font-weight:800;
}

.btn{
    min-height:48px;
    border:0;
    border-radius:18px;
    padding:0 16px;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    gap:8px;
    font-size:13px;
    font-weight:900;
    cursor:pointer;
    transition:.18s ease;
}

.btn:active{
    transform:scale(.98);
}

.btn-primary{
    color:white;
    background:linear-gradient(135deg,var(--blue),var(--purple));
    box-shadow:0 16px 36px rgba(37,99,235,.22);
}

.btn-dark{
    color:white;
    background:#0f172a;
}

.btn-light{
    color:#0f172a;
    background:#fff;
    border:1px solid var(--line);
}

.btn-success{
    color:white;
    background:linear-gradient(135deg,#059669,#10b981);
}

.btn-muted{
    color:#475569;
    background:#f1f5f9;
}

.btn-full{
    width:100%;
}

.notice{
    padding:14px 15px;
    border-radius:20px;
    margin-bottom:14px;
    font-size:13px;
    font-weight:800;
    line-height:1.7;
}

.notice-error{
    color:#b91c1c;
    background:#fef2f2;
    border:1px solid #fecaca;
}

.notice-success{
    color:#047857;
    background:#ecfdf5;
    border:1px solid #a7f3d0;
}

.section-head{
    display:flex;
    align-items:flex-end;
    justify-content:space-between;
    gap:10px;
    margin:18px 2px 12px;
}

.section-title{
    font-size:21px;
    font-weight:900;
    letter-spacing:-.6px;
}

.section-sub{
    color:var(--muted);
    font-size:11px;
    font-weight:850;
    margin-top:4px;
}

.exam-list{
    display:grid;
    gap:13px;
}

.exam-card{
    position:relative;
    overflow:hidden;
    background:rgba(255,255,255,.96);
    border:1px solid rgba(226,232,240,.9);
    border-radius:30px;
    padding:16px;
    box-shadow:var(--shadow);
}

.exam-card:before{
    content:"";
    position:absolute;
    width:130px;
    height:130px;
    right:-68px;
    top:-68px;
    border-radius:50%;
    background:radial-gradient(circle,rgba(37,99,235,.13),transparent 70%);
}

.exam-card-top{
    position:relative;
    z-index:2;
    display:flex;
    justify-content:space-between;
    align-items:flex-start;
    gap:10px;
    margin-bottom:12px;
}

.exam-icon{
    width:56px;
    height:56px;
    border-radius:22px;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:26px;
    background:linear-gradient(135deg,#eff6ff,#f5f3ff);
    border:1px solid #e0e7ff;
    flex-shrink:0;
}

.status-pill{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    padding:8px 10px;
    border-radius:999px;
    font-size:10px;
    font-weight:900;
    white-space:nowrap;
}

.is-open{
    background:#ecfdf5;
    color:#047857;
}

.is-waiting{
    background:#fff7ed;
    color:#c2410c;
}

.is-closed{
    background:#fef2f2;
    color:#b91c1c;
}

.is-done{
    background:#eff6ff;
    color:#1d4ed8;
}

.exam-name{
    position:relative;
    z-index:2;
    font-size:18px;
    font-weight:900;
    line-height:1.45;
    margin-bottom:5px;
}

.exam-type{
    position:relative;
    z-index:2;
    color:var(--muted);
    font-size:12px;
    font-weight:800;
    line-height:1.6;
}

.exam-stats{
    position:relative;
    z-index:2;
    display:grid;
    grid-template-columns:repeat(3,1fr);
    gap:8px;
    margin:14px 0;
}

.stat-box{
    background:#f8fafc;
    border:1px solid #edf2f7;
    border-radius:18px;
    padding:10px 8px;
    text-align:center;
}

.stat-box span{
    display:block;
    color:var(--muted);
    font-size:9px;
    font-weight:900;
    text-transform:uppercase;
    margin-bottom:5px;
}

.stat-box strong{
    display:block;
    font-size:13px;
    font-weight:900;
}

.exam-meta{
    position:relative;
    z-index:2;
    display:grid;
    gap:8px;
    margin-bottom:13px;
}

.meta-pill{
    background:#f8fafc;
    border:1px solid #e2e8f0;
    border-radius:17px;
    padding:10px 12px;
    color:#334155;
    font-size:12px;
    font-weight:850;
    line-height:1.55;
}

.exam-actions{
    position:relative;
    z-index:2;
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:9px;
}

.exam-actions.one{
    grid-template-columns:1fr;
}

.empty-card,
.panel{
    background:#fff;
    border:1px solid var(--line);
    border-radius:30px;
    box-shadow:var(--shadow);
    padding:22px;
}

.empty-card{
    text-align:center;
    color:var(--muted);
    font-weight:850;
    line-height:1.8;
}

.lobby-card{
    background:#fff;
    border:1px solid var(--line);
    border-radius:32px;
    box-shadow:var(--shadow);
    padding:16px;
}

.lobby-hero{
    display:flex;
    gap:13px;
    align-items:center;
    padding:16px;
    border-radius:28px;
    color:white;
    background:
        radial-gradient(circle at top right,rgba(255,255,255,.18),transparent 34%),
        linear-gradient(135deg,#0f172a,#1e3a8a,#312e81);
    margin-bottom:14px;
}

.lobby-icon{
    width:66px;
    height:66px;
    border-radius:24px;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:30px;
    background:rgba(255,255,255,.13);
    border:1px solid rgba(255,255,255,.20);
    flex-shrink:0;
}

.lobby-title{
    font-size:21px;
    font-weight:900;
    line-height:1.35;
}

.lobby-sub{
    margin-top:5px;
    color:#dbeafe;
    font-size:12px;
    font-weight:800;
    line-height:1.5;
}

.rules{
    display:grid;
    gap:9px;
    margin:14px 0;
}

.rule{
    display:flex;
    gap:10px;
    align-items:flex-start;
    background:#f8fafc;
    border:1px solid #e2e8f0;
    border-radius:20px;
    padding:12px;
}

.rule-icon{
    width:36px;
    height:36px;
    border-radius:14px;
    display:flex;
    align-items:center;
    justify-content:center;
    background:#fff;
    flex-shrink:0;
}

.rule-text{
    color:#334155;
    font-size:13px;
    font-weight:850;
    line-height:1.7;
}

.input,
.answer-textarea{
    width:100%;
    border:1px solid #cbd5e1;
    background:#fff;
    outline:none;
    border-radius:20px;
    font-size:15px;
    font-weight:800;
}

.input{
    height:56px;
    padding:0 15px;
}

.answer-textarea{
    min-height:150px;
    resize:vertical;
    padding:15px;
    line-height:1.8;
}

.input:focus,
.answer-textarea:focus{
    border-color:var(--blue);
    box-shadow:0 0 0 5px rgba(37,99,235,.10);
}

.lobby-form{
    display:grid;
    gap:12px;
    margin-top:14px;
}

.bottom-nav{
    position:fixed;
    left:50%;
    bottom:14px;
    transform:translateX(-50%);
    z-index:200;
    width:calc(100% - 28px);
    max-width:520px;
    display:grid;
    grid-template-columns:repeat(3,1fr);
    gap:8px;
    padding:10px;
    border-radius:26px;
    background:rgba(255,255,255,.92);
    border:1px solid rgba(226,232,240,.95);
    box-shadow:0 20px 60px rgba(15,23,42,.14);
    backdrop-filter:blur(20px);
}

.nav-item{
    min-height:48px;
    border-radius:18px;
    display:flex;
    align-items:center;
    justify-content:center;
    flex-direction:column;
    gap:3px;
    color:#64748b;
    font-size:10px;
    font-weight:900;
}

.nav-item.active{
    color:white;
    background:linear-gradient(135deg,var(--blue),var(--purple));
}

.nav-item b{
    font-size:17px;
    line-height:1;
}

/* Take exam/result CSS */
.take-shell{
    display:grid;
    gap:12px;
}

.exam-sticky{
    position:sticky;
    top:70px;
    z-index:90;
    background:rgba(255,255,255,.94);
    backdrop-filter:blur(18px);
    border:1px solid rgba(226,232,240,.95);
    border-radius:26px;
    padding:12px;
    box-shadow:0 14px 38px rgba(15,23,42,.10);
}

.timer-row{
    display:flex;
    justify-content:space-between;
    align-items:center;
    gap:10px;
    margin-bottom:10px;
}

.timer-box{
    min-width:118px;
    border-radius:18px;
    padding:10px 12px;
    background:#0f172a;
    color:white;
    text-align:center;
}

.timer-label{
    font-size:9px;
    font-weight:900;
    color:#cbd5e1;
    margin-bottom:4px;
}

.timer-value{
    font-size:18px;
    font-weight:900;
}

.save-status{
    font-size:11px;
    font-weight:900;
    color:#64748b;
}

.progress-bar{
    height:9px;
    background:#e2e8f0;
    border-radius:999px;
    overflow:hidden;
}

.progress-fill{
    height:100%;
    width:<?php echo (int)$progressPercent; ?>%;
    background:linear-gradient(135deg,var(--blue),var(--purple));
}

.navigator{
    display:flex;
    gap:7px;
    overflow-x:auto;
    padding:10px 1px 2px;
    scrollbar-width:none;
}

.navigator::-webkit-scrollbar{
    display:none;
}

.nav-q{
    width:36px;
    height:36px;
    border:0;
    border-radius:14px;
    background:#f1f5f9;
    color:#334155;
    font-size:12px;
    font-weight:900;
    flex-shrink:0;
}

.nav-q.answered{
    background:#dbeafe;
    color:#1d4ed8;
}

.nav-q.review{
    background:#fff7ed;
    color:#c2410c;
}

.question-card{
    background:#fff;
    border:1px solid var(--line);
    border-radius:30px;
    padding:16px;
    box-shadow:var(--shadow);
}

.question-head{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:10px;
    margin-bottom:13px;
}

.question-badge,
.type-badge{
    display:inline-flex;
    padding:8px 11px;
    border-radius:999px;
    font-size:10px;
    font-weight:900;
}

.question-badge{
    background:#eff6ff;
    color:#1d4ed8;
}

.type-badge{
    background:#f5f3ff;
    color:#6d28d9;
}

.question-text{
    font-size:16px;
    font-weight:850;
    line-height:1.9;
    white-space:pre-line;
    margin-bottom:15px;
}

.reading-box,
.audio-box{
    border-radius:24px;
    padding:15px;
    margin-bottom:14px;
}

.reading-box{
    background:#0f172a;
    color:white;
}

.audio-box{
    background:#111827;
}

.audio-box audio{
    width:100%;
}

.media-title{
    font-size:11px;
    font-weight:900;
    color:#cbd5e1;
    margin-bottom:9px;
}

.reading-content{
    font-size:14px;
    line-height:2;
    white-space:pre-line;
}

.question-image{
    width:100%;
    border-radius:22px;
    border:1px solid var(--line);
    margin-bottom:14px;
}

.options-grid{
    display:grid;
    gap:10px;
}

.option-card{
    display:block;
    border:2px solid #e2e8f0;
    background:#f8fafc;
    border-radius:21px;
    padding:14px;
    font-size:14px;
    font-weight:850;
    line-height:1.7;
}

.option-card input{
    display:none;
}

.option-card:has(input:checked){
    border-color:var(--blue);
    background:#eff6ff;
    color:#1d4ed8;
}

.review-row{
    margin-top:12px;
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:10px;
}

.review-toggle{
    display:flex;
    align-items:center;
    gap:8px;
    color:#64748b;
    font-size:12px;
    font-weight:900;
}

.submit-bar{
    position:fixed;
    left:50%;
    bottom:14px;
    transform:translateX(-50%);
    z-index:220;
    width:calc(100% - 28px);
    max-width:520px;
    padding:10px;
    border-radius:26px;
    background:rgba(255,255,255,.94);
    border:1px solid var(--line);
    box-shadow:0 20px 60px rgba(15,23,42,.15);
    backdrop-filter:blur(20px);
}

.result-card{
    background:#fff;
    border:1px solid var(--line);
    border-radius:32px;
    padding:20px;
    box-shadow:var(--shadow);
    text-align:center;
}

.result-score{
    width:142px;
    height:142px;
    border-radius:50%;
    margin:8px auto 16px;
    display:flex;
    align-items:center;
    justify-content:center;
    flex-direction:column;
    color:white;
    background:linear-gradient(135deg,var(--blue),var(--purple));
    box-shadow:var(--shadow2);
}

.result-score strong{
    font-size:34px;
    font-weight:900;
}

.result-score span{
    font-size:11px;
    font-weight:900;
    color:#dbeafe;
}

.answer-review{
    display:grid;
    gap:10px;
    margin-top:15px;
}

.review-card{
    background:#fff;
    border:1px solid var(--line);
    border-radius:24px;
    padding:14px;
}

.review-card h3{
    font-size:14px;
    line-height:1.7;
    margin-bottom:8px;
}

.review-card p{
    color:#475569;
    font-size:13px;
    line-height:1.8;
}

@media (max-width:380px){
    .hero h1{font-size:24px;}
    .exam-stats{gap:6px;}
    .btn{font-size:12px;padding:0 12px;}
}
</style>
</head>
<body>

<div class="exam-app">

    <div class="mobile-top">
        <div class="top-row">
            <div class="brand-mini">
                <div class="brand-mark">SMI</div>
                <div class="brand-text">
                    <strong><?php echo e(trText('title')); ?></strong>
                    <span><?php echo e($studentName); ?> · <?php echo e($studentCode); ?></span>
                </div>
            </div>

            <a class="icon-btn" href="course-dashboard.php?course_id=<?php echo (int)$courseId; ?>">←</a>
        </div>
    </div>

    <?php if ($view === 'list'): ?>
        <section class="hero">
            <div class="hero-kicker">Premium Assessment Area</div>
            <h1><?php echo e(trText('title')); ?></h1>
            <p><?php echo e(trText('subtitle')); ?></p>
        </section>

        <div class="section-title"><?php echo e(trText('available_exams')); ?></div>

        <?php if (!$availableExams): ?>
            <div class="empty-card"><?php echo e(trText('no_exams')); ?></div>
        <?php else: ?>
            <div class="exam-list">
                <?php foreach ($availableExams as $exam): ?>
                    <article class="exam-card">
                        <div class="exam-card-top">
                            <div class="exam-icon"><?php echo e(examIcon((string)($exam['exam_type'] ?? ''))); ?></div>
                            <span class="status-pill <?php echo e(examStatusClass($exam)); ?>">
                                <?php echo e(examStatusLabel($exam)); ?>
                            </span>
                        </div>

                        <h2 class="exam-name"><?php echo e((string)($exam['title'] ?? 'Untitled Exam')); ?></h2>
                        <div class="exam-type"><?php echo e(examTypeLabel((string)($exam['exam_type'] ?? 'exam'))); ?></div>

                        <div class="exam-stats">
                            <div class="stat-box"><span>Duration</span><strong><?php echo e(formatMinutes($exam['duration_minutes'] ?? 60)); ?></strong></div>
                            <div class="stat-box"><span>Questions</span><strong><?php echo (int)($exam['questions_count'] ?? 0); ?></strong></div>
                            <div class="stat-box"><span>Attempts</span><strong><?php echo (int)($exam['my_attempts_count'] ?? 0); ?>/<?php echo (int)($exam['max_attempts'] ?? 1); ?></strong></div>
                        </div>

                        <div class="exam-actions one">
                            <a class="btn btn-primary"
                               href="exams.php?view=lobby&course_id=<?php echo (int)$courseId; ?>&exam_id=<?php echo (int)$exam['id']; ?>">
                                <?php echo e(trText('start_exam')); ?>
                            </a>
                        </div>
                    </article>
                <?php endforeach; ?>
            </div>
        <?php endif; ?>
    <?php endif; ?>
    <?php if ($view === 'lobby' && $currentExam): ?>

<section class="lobby-card">

    <div class="lobby-hero">
        <div class="lobby-icon">
            <?php echo e(examIcon((string)($currentExam['exam_type'] ?? 'exam'))); ?>
        </div>

        <div>
            <div class="lobby-title">
                <?php echo e((string)($currentExam['title'] ?? 'Exam')); ?>
            </div>
            <div class="lobby-sub">
                <?php echo e(examTypeLabel((string)($currentExam['exam_type'] ?? 'exam'))); ?>
                · <?php echo e(formatMinutes($currentExam['duration_minutes'] ?? 60)); ?>
            </div>
        </div>
    </div>

    <div class="rules">
        <div class="rule">
            <div class="rule-icon">🔒</div>
            <div class="rule-text"><?php echo e(trText('rule_1')); ?></div>
        </div>

        <div class="rule">
            <div class="rule-icon">💾</div>
            <div class="rule-text"><?php echo e(trText('rule_2')); ?></div>
        </div>

        <div class="rule">
            <div class="rule-icon">⏱️</div>
            <div class="rule-text"><?php echo e(trText('rule_3')); ?></div>
        </div>
    </div>

    <form method="post" class="lobby-form">
        <input type="hidden" name="csrf_token" value="<?php echo e($csrfToken); ?>">
        <input type="hidden" name="action" value="start_exam">
        <input type="hidden" name="course_id" value="<?php echo (int)$courseId; ?>">
        <input type="hidden" name="exam_id" value="<?php echo (int)$currentExam['id']; ?>">

        <?php if ((int)($currentExam['require_exam_code'] ?? 0) === 1): ?>
            <input class="input"
                   type="text"
                   name="exam_code"
                   placeholder="<?php echo e(trText('enter_code')); ?>"
                   required>
        <?php endif; ?>

        <button class="btn btn-primary btn-full" type="submit">
            🚀 <?php echo e(trText('start_exam')); ?>
        </button>
    </form>

</section>

<?php endif; ?>

<?php if ($view === 'take' && $currentExam && $currentAttempt): ?>

    <form method="post" id="examForm" class="take-shell">
        <input type="hidden" name="csrf_token" value="<?php echo e($csrfToken); ?>">
        <input type="hidden" name="action" value="submit_exam">
        <input type="hidden" name="course_id" value="<?php echo (int)$courseId; ?>">
        <input type="hidden" name="exam_id" value="<?php echo (int)$currentExam['id']; ?>">
        <input type="hidden" name="attempt_id" value="<?php echo (int)$currentAttempt['id']; ?>">

        <div class="exam-sticky">
            <div class="timer-row">
                <div>
                    <strong><?php echo e((string)($currentExam['title'] ?? 'Exam')); ?></strong>
                    <div class="save-status" id="saveStatus">
                        <?php echo e($answeredCount); ?>/<?php echo e($totalQuestions); ?>
                        <?php echo e(trText('answered')); ?>
                    </div>
                </div>

                <div class="timer-box">
                    <div class="timer-label"><?php echo e(trText('time_left')); ?></div>
                    <div class="timer-value" id="timer" data-seconds="<?php echo (int)$remainingSeconds; ?>">--:--</div>
                </div>
            </div>

            <div class="progress-bar">
                <div class="progress-fill" id="progressFill"></div>
            </div>

            <div class="navigator">
                <?php foreach ($examQuestions as $index => $question): ?>
                    <?php
                        $qid = (int)$question['id'];
                        $hasAns = isset($autosavedAnswers[$qid]) && trim((string)$autosavedAnswers[$qid]) !== '';
                    ?>
                    <button type="button"
                            class="nav-q <?php echo $hasAns ? 'answered' : ''; ?>"
                            data-target="q<?php echo (int)$qid; ?>">
                        <?php echo (int)($index + 1); ?>
                    </button>
                <?php endforeach; ?>
            </div>
        </div>

        <?php if (!$examQuestions): ?>

            <div class="empty-card">
                <?php echo e(trText('no_questions')); ?>
            </div>

        <?php else: ?>

            <?php foreach ($examQuestions as $index => $question): ?>

                <?php
                    $qid = (int)$question['id'];
                    $qType = (string)($question['question_type'] ?? '');
                    $savedValue = (string)($autosavedAnswers[$qid] ?? '');
                    $passage = getQuestionPassage($question);
                    $audio = getQuestionAudio($question);
                    $image = getQuestionImage($question);
                    $options = $question['options'] ?? [];
                ?>

                <section class="question-card" id="q<?php echo (int)$qid; ?>" data-question-id="<?php echo (int)$qid; ?>">
                    <div class="question-head">
                        <span class="question-badge">
                            <?php echo e(trText('question')); ?> <?php echo (int)($index + 1); ?>
                        </span>
                        <span class="type-badge">
                            <?php echo e(questionTypeLabel($qType)); ?>
                        </span>
                    </div>

                    <?php if ($passage !== ''): ?>
                        <div class="reading-box">
                            <div class="media-title">📖 Reading Passage</div>
                            <div class="reading-content"><?php echo nl2br(e($passage)); ?></div>
                        </div>
                    <?php endif; ?>

                    <?php if ($audio !== ''): ?>
                        <div class="audio-box">
                            <div class="media-title">🎧 Listening Audio</div>
                            <audio controls preload="metadata">
                                <source src="<?php echo e(resolveAssetUrl($audio)); ?>">
                            </audio>
                        </div>
                    <?php endif; ?>

                    <?php if ($image !== ''): ?>
                        <img class="question-image" src="<?php echo e(resolveAssetUrl($image)); ?>" alt="Question Image">
                    <?php endif; ?>

                    <div class="question-text">
                        <?php echo nl2br(e((string)($question['question_text'] ?? ''))); ?>
                    </div>

                    <?php if (!empty($options)): ?>

                        <div class="options-grid">
                            <?php foreach ($options as $option): ?>
                                <?php $optionId = (string)($option['id'] ?? ''); ?>

                                <label class="option-card">
                                    <input type="radio"
                                           name="answers[<?php echo (int)$qid; ?>]"
                                           value="<?php echo e($optionId); ?>"
                                           <?php echo $savedValue === $optionId ? 'checked' : ''; ?>>
                                    <?php echo e((string)($option['option_text'] ?? '')); ?>
                                </label>

                            <?php endforeach; ?>
                        </div>

                    <?php else: ?>

                        <textarea class="answer-textarea"
                                  name="answers[<?php echo (int)$qid; ?>]"
                                  placeholder="<?php echo e(trText('question')); ?>..."
                        ><?php echo e($savedValue); ?></textarea>

                    <?php endif; ?>

                    <div class="review-row">
                        <label class="review-toggle">
                            <input type="checkbox" class="review-check" data-qid="<?php echo (int)$qid; ?>">
                            <?php echo e(trText('mark_review')); ?>
                        </label>

                        <span class="save-status question-status" data-qid="<?php echo (int)$qid; ?>">
                            <?php echo $savedValue !== '' ? 'Answered' : 'Not answered'; ?>
                        </span>
                    </div>
                </section>

            <?php endforeach; ?>

        <?php endif; ?>

        <div class="submit-bar">
            <button class="btn btn-success btn-full" type="submit">
                ✅ <?php echo e(trText('submit_exam')); ?>
            </button>
        </div>
    </form>

<?php elseif ($view === 'result' && $currentExam && $currentAttempt): ?>

    <section class="result-card">
        <div class="result-score">
            <strong><?php echo e((string)round((float)($currentAttempt['percentage'] ?? 0), 1)); ?>%</strong>
            <span><?php echo e(trText('score')); ?></span>
        </div>

        <h2><?php echo e((string)($currentExam['title'] ?? 'Exam Result')); ?></h2>

        <p style="margin-top:8px;color:#64748b;font-weight:800;line-height:1.7;">
            <?php echo e(trText('status')); ?>:
            <?php echo e(ucfirst((string)($currentAttempt['result_status'] ?? 'pending'))); ?>
            ·
            <?php echo e(trText('attempt')); ?>:
            <?php echo e((string)($currentAttempt['attempt_number'] ?? 1)); ?>
        </p>

        <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:16px;">
            <a class="btn btn-primary"
               href="exams.php?course_id=<?php echo (int)$courseId; ?>">
                <?php echo e(trText('available_exams')); ?>
            </a>

            <a class="btn btn-light"
               href="course-dashboard.php?course_id=<?php echo (int)$courseId; ?>">
                <?php echo e(trText('course_dashboard')); ?>
            </a>
        </div>
    </section>

    <?php if ($attemptAnswers): ?>
        <div class="answer-review">
            <?php foreach ($attemptAnswers as $index => $ans): ?>
                <div class="review-card">
                    <h3>
                        <?php echo (int)($index + 1); ?>.
                        <?php echo e((string)($ans['question_text'] ?? 'Question')); ?>
                    </h3>

                    <p>
                        <strong>Your answer:</strong>
                        <?php
                            $displayAnswer = (string)($ans['selected_option_text'] ?? $ans['answer_text'] ?? '');
                            echo e($displayAnswer !== '' ? $displayAnswer : 'No answer');
                        ?>
                    </p>

                    <p>
                        <strong>Score:</strong>
                        <?php echo e((string)($ans['score_awarded'] ?? 0)); ?>
                        /
                        <?php echo e((string)($ans['marks'] ?? 0)); ?>
                    </p>

                    <?php if (!empty($ans['explanation'])): ?>
                        <p>
                            <strong>Explanation:</strong>
                            <?php echo e((string)$ans['explanation']); ?>
                        </p>
                    <?php endif; ?>
                </div>
            <?php endforeach; ?>
        </div>
    <?php endif; ?>

<?php endif; ?>

</div>

<?php if ($view !== 'take'): ?>
    <nav class="bottom-nav">
        <a class="nav-item active" href="exams.php?course_id=<?php echo (int)$courseId; ?>">
            <b>📝</b>
            Exams
        </a>

        <a class="nav-item" href="grades.php?course_id=<?php echo (int)$courseId; ?>">
            <b>📊</b>
            Grades
        </a>

        <a class="nav-item" href="course-dashboard.php?course_id=<?php echo (int)$courseId; ?>">
            <b>🏠</b>
            Course
        </a>
    </nav>
<?php endif; ?>

<script>
(function(){
    const form = document.getElementById('examForm');
    const timerEl = document.getElementById('timer');
    const saveStatus = document.getElementById('saveStatus');
    const progressFill = document.getElementById('progressFill');

    function collectAnswers(){
        if (!form) return new FormData();

        const data = new FormData();
        data.append('csrf_token', '<?php echo e($csrfToken); ?>');
        data.append('action', 'autosave_exam');
        data.append('course_id', '<?php echo (int)$courseId; ?>');
        data.append('exam_id', '<?php echo (int)($currentExam['id'] ?? 0); ?>');
        data.append('attempt_id', '<?php echo (int)($currentAttempt['id'] ?? 0); ?>');

        const fields = form.querySelectorAll('input[name^="answers["]:checked, textarea[name^="answers["], input[type="text"][name^="answers["]');
        fields.forEach(field => {
            data.append(field.name, field.value);
        });

        return data;
    }

    function updateProgress(){
        if (!form) return;

        const cards = Array.from(document.querySelectorAll('.question-card'));
        let answered = 0;

        cards.forEach((card, index) => {
            const qid = card.dataset.questionId;
            const checked = card.querySelector('input[type="radio"]:checked');
            const textarea = card.querySelector('textarea');
            const hasAnswer = checked || (textarea && textarea.value.trim() !== '');

            if (hasAnswer) answered++;

            const nav = document.querySelector('.nav-q[data-target="q' + qid + '"]');
            const status = document.querySelector('.question-status[data-qid="' + qid + '"]');

            if (nav) nav.classList.toggle('answered', !!hasAnswer);
            if (status) status.textContent = hasAnswer ? 'Answered' : 'Not answered';
        });

        const percent = cards.length ? Math.round((answered / cards.length) * 100) : 0;

        if (progressFill) progressFill.style.width = percent + '%';
        if (saveStatus) saveStatus.textContent = answered + '/' + cards.length + ' <?php echo e(trText('answered')); ?>';
    }

    let autosaveTimer = null;

    function autosave(){
        if (!form) return;

        if (saveStatus) saveStatus.textContent = 'Saving...';

        fetch('exams.php?course_id=<?php echo (int)$courseId; ?>', {
            method: 'POST',
            body: collectAnswers(),
            credentials: 'same-origin'
        })
        .then(res => res.json())
        .then(json => {
            updateProgress();

            if (saveStatus) {
                saveStatus.textContent = json.success
                    ? '<?php echo e(trText('autosaved')); ?> · ' + (json.saved_at || '')
                    : (json.message || 'Autosave failed');
            }
        })
        .catch(() => {
            if (saveStatus) saveStatus.textContent = 'Autosave failed';
        });
    }

    function scheduleAutosave(){
        updateProgress();
        clearTimeout(autosaveTimer);
        autosaveTimer = setTimeout(autosave, 900);
    }

    if (form) {
        form.addEventListener('input', scheduleAutosave);
        form.addEventListener('change', scheduleAutosave);

        form.addEventListener('submit', function(e){
            const ok = confirm('<?php echo e(trText('submit_warning')); ?>');
            if (!ok) e.preventDefault();
        });

        setInterval(autosave, 30000);
        updateProgress();
    }

    document.querySelectorAll('.nav-q').forEach(btn => {
        btn.addEventListener('click', () => {
            const target = document.getElementById(btn.dataset.target);
            if (target) {
                target.scrollIntoView({behavior:'smooth', block:'start'});
            }
        });
    });

    document.querySelectorAll('.review-check').forEach(check => {
        check.addEventListener('change', () => {
            const nav = document.querySelector('.nav-q[data-target="q' + check.dataset.qid + '"]');
            if (nav) nav.classList.toggle('review', check.checked);
        });
    });

    if (timerEl) {
        let seconds = parseInt(timerEl.dataset.seconds || '0', 10);

        function renderTimer(){
            const m = Math.floor(seconds / 60);
            const s = seconds % 60;

            timerEl.textContent =
                String(m).padStart(2,'0') + ':' + String(s).padStart(2,'0');

            if (seconds <= 300) {
                timerEl.parentElement.style.background = '#991b1b';
            }

            if (seconds <= 0) {
                autosave();
                if (form) form.submit();
                return;
            }

            seconds--;
        }

        renderTimer();
        setInterval(renderTimer, 1000);
    }

    if (form) {
        window.addEventListener('beforeunload', function(e){
            e.preventDefault();
            e.returnValue = '';
        });
    }
})();
</script>

</body>
</html>