/* ==========================================
   BGNU Exam Portal - JavaScript Logic
   Offline-First Exam System with Anti-Cheat
   ========================================== */

const API_BASE = 'https://bilalcode.site/exammode/api';

// State
let examState = {
    sessionToken: null,
    rollNo: null,
    studentEmail: null,
    studentName: null,
    questions: [],
    answers: {},
    currentIndex: 0,
    timeRemaining: 0,
    timerInterval: null,
    isOnline: navigator.onLine,
    examStarted: false,
    isTerminated: false,
    violations: []
};

// DOM Elements
const elements = {
    preExamScreen: document.getElementById('pre-exam-screen'),
    examScreen: document.getElementById('exam-screen'),
    resultScreen: document.getElementById('result-screen'),
    loadDataBtn: document.getElementById('load-data-btn'),
    loadStatus: document.getElementById('load-status'),
    rollNoInput: document.getElementById('roll-no'),
    studentEmailInput: document.getElementById('student-email'),
    studentNameInput: document.getElementById('student-name'),
    examInfo: document.getElementById('exam-info'),
    examTitle: document.getElementById('exam-title'),
    examDuration: document.getElementById('exam-duration'),
    examQuestions: document.getElementById('exam-questions'),
    timeDisplay: document.getElementById('time-display'),
    connectionStatus: document.getElementById('connection-status'),
    progressBar: document.getElementById('progress-bar'),
    progressText: document.getElementById('progress-text'),
    questionNumber: document.getElementById('question-number'),
    questionPrompt: document.getElementById('question-prompt'),
    optionsContainer: document.getElementById('options-container'),
    prevBtn: document.getElementById('prev-btn'),
    nextBtn: document.getElementById('next-btn'),
    questionDots: document.getElementById('question-dots'),
    submitBtn: document.getElementById('submit-btn'),
    timer: document.getElementById('timer'),
    resultIcon: document.getElementById('result-icon'),
    resultTitle: document.getElementById('result-title'),
    resultMessage: document.getElementById('result-message'),
    resultStats: document.getElementById('result-stats')
};

// ==================== INITIALIZATION ====================

document.addEventListener('DOMContentLoaded', () => {
    // Browser verification is now handled by PHP using X-BGNU-Browser header
    // If we reach this point, the browser is verified

    // Clear old localStorage data to ensure fresh start
    console.log('[BGNU Exam] Clearing old session data...');
    localStorage.removeItem('bgnu_exam_session');
    localStorage.removeItem('bgnu_exam_answers');

    // Check for saved exam session (will be empty now)
    loadSavedSession();

    // Online/Offline detection
    window.addEventListener('online', () => updateOnlineStatus(true));
    window.addEventListener('offline', () => updateOnlineStatus(false));
    updateOnlineStatus(navigator.onLine);

    // Event Listeners for buttons
    elements.loadDataBtn.addEventListener('click', loadExamData);
    elements.prevBtn.addEventListener('click', () => navigateQuestion(-1));
    elements.nextBtn.addEventListener('click', () => navigateQuestion(1));
    elements.submitBtn.addEventListener('click', submitExam);

    // ANTI-CHEAT: Registered but ONLY works when examState.examStarted is true
    // The handlers check examState.examStarted before doing anything
    document.addEventListener('visibilitychange', handleVisibilityChange);
    window.addEventListener('blur', handleWindowBlur);
    window.addEventListener('focus', handleWindowFocus);

    // Disable right-click (only during exam)
    document.addEventListener('contextmenu', (e) => {
        if (examState.examStarted && !examState.isTerminated) {
            e.preventDefault();
        }
    });

    // Disable keyboard shortcuts (only during exam)
    document.addEventListener('keydown', handleKeyDown);

    // Log that exam page is loaded
    console.log('[BGNU Exam] Page loaded - anti-cheat will activate when exam starts');
});

// ==================== BGNU BROWSER DETECTION ====================

function checkBGNUBrowser() {
    // Check for Flutter WebView handler
    if (window.flutter_inappwebview) {
        return true;
    }

    // Check User-Agent as fallback
    const ua = navigator.userAgent.toLowerCase();
    if (ua.includes('bgnu') || ua.includes('inappwebview')) {
        return true;
    }

    // Check for specific WebView characteristics
    // Flutter InAppWebView on Windows has specific properties
    if (navigator.platform && navigator.platform.includes('Win')) {
        // On Windows, check if running in a WebView context
        if (window.chrome && window.chrome.webview) {
            return true; // Windows WebView2
        }
    }

    return false;
}

function showAccessDenied() {
    document.body.innerHTML = `
        <div style="
            display: flex;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            background: #0a0a0f;
            color: white;
            font-family: 'Inter', sans-serif;
            text-align: center;
        ">
            <div style="max-width: 500px; padding: 40px;">
                <h1 style="color: #ef4444; font-size: 2.5rem; margin-bottom: 20px;">🎓 Access Denied</h1>
                <p style="color: #a0a0b0; margin-bottom: 20px; font-size: 1.1rem;">
                    This exam can only be accessed through <strong style="color: white;">BGNU Exam Browser</strong>.
                </p>
                <p style="color: #a0a0b0; margin-bottom: 30px;">
                    Please download and install the browser to continue.
                </p>
                <a href="https://bilalcode.site/download-bgnu-browser" style="
                    display: inline-block;
                    padding: 14px 28px;
                    background: linear-gradient(135deg, #6366f1, #8b5cf6);
                    color: white;
                    text-decoration: none;
                    border-radius: 10px;
                    font-weight: 600;
                    transition: transform 0.2s;
                ">Download BGNU Browser</a>
            </div>
        </div>
    `;
}

// ==================== ANTI-CHEAT FUNCTIONS ====================

// Violation counter for warnings before termination
let violationWarnings = 0;
const MAX_WARNINGS = 2; // Terminate after 2 violations (give 1 chance)

// Debounce timer to prevent multiple violations from same event
let lastViolationTime = 0;
const VIOLATION_DEBOUNCE_MS = 3000; // 3 second debounce

function handleVisibilityChange() {
    if (!examState.examStarted || examState.isTerminated) return;

    if (document.hidden) {
        // Student switched tabs or minimized - this triggers on tab switch
        handleSecurityViolation('tab_switch', 'Tab switch or minimize detected');
    }
}

function handleWindowBlur() {
    if (!examState.examStarted || examState.isTerminated) return;

    // Distinguish between true window blur and temporary focus loss during clicks
    // International exam platforms use a small delay (150ms-300ms) to verify focus
    setTimeout(() => {
        if (!document.hasFocus() && !examState.isTerminated) {
            // Focus is still lost after 250ms - this is a real Alt+Tab or Minimize
            handleSecurityViolation('window_blur', 'Window lost focus (minimize/Alt+Tab)');
        } else {
            // Focus returned - this was just a click or momentary shift
            console.log('[BGNU Exam] False blur detected (click/interaction), ignoring.');
        }
    }, 250);
}

function handleWindowFocus() {
    // Window regained focus - can log but no action needed
    console.log('[BGNU Exam] Window focus regained');
}

// Central violation handler - records and terminates after MAX_WARNINGS
function handleSecurityViolation(type, description) {
    // Only trigger if exam is actually in progress
    if (!examState.examStarted || examState.isTerminated) return;

    // Debounce - prevent multiple violations within debounce period
    const now = Date.now();
    if (now - lastViolationTime < VIOLATION_DEBOUNCE_MS) {
        console.log('[BGNU Exam] Violation debounced (too soon after previous)');
        return;
    }
    lastViolationTime = now;

    violationWarnings++;
    const violationDesc = `${description} (Warning ${violationWarnings}/${MAX_WARNINGS})`;

    console.log(`[BGNU Exam] VIOLATION #${violationWarnings}: ${violationDesc}`);

    // Always record the violation to server
    recordViolation(type, violationDesc);

    if (violationWarnings >= MAX_WARNINGS) {
        // Terminate exam after 2 violations
        terminateExam(type, `Exam terminated: ${violationWarnings} security violations detected. Last violation: ${description}`);
    } else {
        // Show warning - this is their 1 chance
        showViolationWarning(
            `⚠️ WARNING ${violationWarnings}/${MAX_WARNINGS}: ${description}\n\n` +
            `This is your ONLY warning. If you try to minimize, switch tabs, or use Alt+Tab again, your exam will be TERMINATED immediately.`
        );
    }
}

function handleKeyDown(e) {
    if (!examState.examStarted || examState.isTerminated) return;

    // Block Alt key itself to prevent menu bar access
    if (e.key === 'Alt') {
        e.preventDefault();
        return false;
    }

    // Block Alt+Tab, Alt+F4, Ctrl+Tab, F11, etc.
    const blockedKeys = ['Tab', 'F4', 'F5', 'F11', 'Escape'];
    const isAltCombo = e.altKey && blockedKeys.includes(e.key);
    const isCtrlCombo = e.ctrlKey && ['Tab', 'w', 'W', 'n', 'N', 't', 'T'].includes(e.key);

    if (isAltCombo || isCtrlCombo) {
        e.preventDefault();
        e.stopPropagation();
        handleSecurityViolation('blocked_key', `Keyboard shortcut blocked: ${e.ctrlKey ? 'Ctrl' : 'Alt'}+${e.key}`);
        return false;
    }

    // Block Standalone F5 refresh
    if (e.key === 'F5') {
        e.preventDefault();
        e.stopPropagation();
        handleSecurityViolation('refresh_attempt', 'Page refresh attempt blocked');
        return false;
    }
}

// Show warning overlay to student
function showViolationWarning(message) {
    // Remove existing warning if any
    const existing = document.getElementById('violation-warning');
    if (existing) existing.remove();

    // Create warning overlay using DOM (more reliable than template literals)
    const overlay = document.createElement('div');
    overlay.id = 'violation-warning';
    overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(239,68,68,0.95);display:flex;align-items:center;justify-content:center;z-index:10000;';

    const box = document.createElement('div');
    box.style.cssText = 'background:#1a1a2f;padding:40px;border-radius:20px;text-align:center;max-width:500px;box-shadow:0 20px 60px rgba(0,0,0,0.5);';

    const icon = document.createElement('div');
    icon.style.cssText = 'font-size:60px;margin-bottom:20px;';
    icon.textContent = '⚠️';

    const title = document.createElement('h2');
    title.style.cssText = 'color:#ef4444;margin-bottom:15px;font-size:1.5rem;';
    title.textContent = 'Security Warning';

    const msg = document.createElement('p');
    msg.style.cssText = 'color:#a0a0b0;margin-bottom:25px;line-height:1.6;white-space:pre-wrap;';
    msg.textContent = message; // This will display the actual message, not ${message}

    const btn = document.createElement('button');
    btn.style.cssText = 'padding:12px 30px;background:linear-gradient(135deg,#6366f1,#8b5cf6);color:white;border:none;border-radius:10px;font-size:16px;cursor:pointer;font-weight:600;';
    btn.textContent = 'I Understand';
    btn.onclick = function () { overlay.remove(); };

    box.appendChild(icon);
    box.appendChild(title);
    box.appendChild(msg);
    box.appendChild(btn);
    overlay.appendChild(box);
    document.body.appendChild(overlay);
}

function recordViolation(type, description) {
    const violation = {
        type: type,
        description: description,
        timestamp: new Date().toISOString()
    };
    examState.violations.push(violation);

    // Send to server
    if (examState.isOnline && examState.sessionToken) {
        fetch(`${API_BASE}/record-violation.php`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                session_token: examState.sessionToken,
                violation_type: type,
                description: description
            })
        }).catch(e => console.warn('Failed to record violation:', e));
    }
}

function terminateExam(reason, message) {
    if (examState.isTerminated) return;

    examState.isTerminated = true;
    clearInterval(examState.timerInterval);

    // Record the violation
    recordViolation(reason, message);

    // Notify server
    if (examState.isOnline && examState.sessionToken) {
        fetch(`${API_BASE}/terminate-exam.php`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                session_token: examState.sessionToken,
                reason: reason,
                message: message
            })
        }).catch(e => console.warn('Failed to terminate on server:', e));
    }

    // Show termination screen
    showTerminatedScreen(message);

    // Clear local session
    clearSession();

    // Notify parent (Flutter)
    notifyParent('exam_terminated', { reason: reason, message: message });
}

function showTerminatedScreen(message) {
    elements.preExamScreen.classList.add('hidden');
    elements.examScreen.classList.add('hidden');
    elements.resultScreen.classList.remove('hidden');

    elements.resultIcon.textContent = '🚫';
    elements.resultTitle.textContent = 'Exam Terminated';
    elements.resultMessage.textContent = message;
    elements.resultStats.innerHTML = `
        <div class="stat-item" style="grid-column: 1/-1;">
            <div class="stat-value" style="color: #ef4444;">CHEATING DETECTED</div>
            <div class="stat-label">Your exam has been invalidated</div>
        </div>
        <div style="grid-column: 1/-1; margin-top: 24px;">
            <button onclick="goBackToBrowser()" style="
                padding: 14px 32px;
                background: linear-gradient(135deg, #6366f1, #8b5cf6);
                color: white;
                border: none;
                border-radius: 12px;
                font-size: 16px;
                font-weight: 600;
                cursor: pointer;
                transition: transform 0.2s, box-shadow 0.2s;
            " onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'">
                ← Back to BGNU Browser
            </button>
        </div>
    `;
}

// ==================== PARENT COMMUNICATION (Flutter) ====================

function notifyParent(event, data) {
    // DISABLED: callHandler crashes Windows WebView when no handler is registered
    // TODO: Register handler in Flutter before re-enabling
    console.log('[BGNU Exam] Parent notification:', event, data);

    // Original code (disabled):
    // try {
    //     if (window.flutter_inappwebview) {
    //         window.flutter_inappwebview.callHandler('examEvent', { event, data });
    //     }
    // } catch (e) {
    //     console.log('Parent notification:', event, data);
    // }
}

// ==================== ONLINE STATUS ====================

function updateOnlineStatus(isOnline) {
    examState.isOnline = isOnline;
    const statusEl = elements.connectionStatus;
    const dot = statusEl.querySelector('.status-dot');
    const text = statusEl.querySelector('span:last-child');

    if (isOnline) {
        dot.classList.add('online');
        dot.classList.remove('offline');
        text.textContent = 'Online';
        elements.submitBtn.disabled = false;

        // Sync pending answers when back online
        syncPendingAnswers();
    } else {
        dot.classList.remove('online');
        dot.classList.add('offline');
        text.textContent = 'Offline';
    }
}

// ==================== LOAD EXAM DATA ====================

async function loadExamData() {
    const rollNo = elements.rollNoInput.value.trim();
    const studentEmail = elements.studentEmailInput.value.trim();
    const studentName = elements.studentNameInput.value.trim();

    if (!rollNo || !studentEmail || !studentName) {
        showStatus('Please fill in all fields', 'error');
        return;
    }

    elements.loadDataBtn.disabled = true;
    showStatus('Loading exam data...', 'loading');

    try {
        const response = await fetch(`${API_BASE}/start-exam.php`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                roll_no: rollNo,
                student_email: studentEmail,
                student_name: studentName,
                exam_code: 'FLUTTER2026' // Flutter exam code
            })
        });

        const data = await response.json();

        if (!data.success) {
            throw new Error(data.message || 'Failed to load exam');
        }

        // Store exam data
        examState.sessionToken = data.session_token;
        examState.rollNo = rollNo;
        examState.studentEmail = studentEmail;
        examState.studentName = studentName;
        examState.questions = data.questions;
        examState.timeRemaining = data.exam.duration_minutes * 60;

        // Load any previous answers if resuming
        if (data.resumed) {
            examState.timeRemaining = data.time_remaining_seconds;
            loadSavedAnswers();
        }

        // Save to localStorage
        saveSession();

        showStatus('Exam loaded successfully!', 'success');

        // Show exam info
        elements.examInfo.style.display = 'block';
        elements.examTitle.textContent = data.exam.title;
        elements.examDuration.textContent = `${data.exam.duration_minutes} minutes`;
        elements.examQuestions.textContent = `${data.exam.total_questions} questions`;

        // Notify parent to enable lockdown
        notifyParent('exam_starting', {
            sessionToken: data.session_token,
            rollNo: rollNo
        });

        // Transition to exam after brief delay
        setTimeout(() => {
            startExam();
        }, 1000);

    } catch (error) {
        console.error('Load error:', error);

        // Try to load from localStorage if offline
        if (!navigator.onLine) {
            const saved = loadSavedSession();
            if (saved) {
                showStatus('Loaded from offline storage', 'success');
                setTimeout(() => startExam(), 1000);
                return;
            }
        }

        showStatus(error.message || 'Failed to load exam. Check connection.', 'error');
        elements.loadDataBtn.disabled = false;
    }
}

// ==================== EXAM FLOW ====================

function startExam() {
    examState.examStarted = true;

    elements.preExamScreen.classList.add('hidden');
    elements.examScreen.classList.remove('hidden');
    elements.submitBtn.classList.remove('hidden');

    // Notify parent that exam has officially started
    notifyParent('exam_started', {
        sessionToken: examState.sessionToken,
        rollNo: examState.rollNo,
        studentName: examState.studentName
    });

    // Activate fullscreen lockdown
    if (typeof ExamLockdown !== 'undefined') {
        ExamLockdown.init();
    }

    // Start timer
    startTimer();

    // Render first question
    renderQuestion(0);
    renderQuestionDots();
    updateProgress();
}

function renderQuestion(index) {
    if (examState.isTerminated) return;

    const question = examState.questions[index];
    if (!question) return;

    examState.currentIndex = index;

    // Update question display
    elements.questionNumber.textContent = `Question ${index + 1}`;
    elements.questionPrompt.textContent = question.question_prompt;

    // Render options
    const options = [
        { letter: 'A', text: question.choice_a },
        { letter: 'B', text: question.choice_b },
        { letter: 'C', text: question.choice_c },
        { letter: 'D', text: question.choice_d }
    ];

    const savedAnswers = examState.answers[question.question_id] || [];

    elements.optionsContainer.innerHTML = options.map(opt => `
        <div class="option-item ${savedAnswers.includes(opt.letter) ? 'selected' : ''}" 
             data-letter="${opt.letter}" onclick="selectOption('${opt.letter}')">
            <div class="option-checkbox"></div>
            <div class="option-letter">${opt.letter}</div>
            <div class="option-text">${opt.text}</div>
        </div>
    `).join('');

    // Update navigation buttons
    elements.prevBtn.disabled = index === 0;
    elements.nextBtn.textContent = index === examState.questions.length - 1 ? 'Finish' : 'Next →';

    // Update dots
    updateQuestionDots();
}

function selectOption(letter) {
    if (examState.isTerminated) return;

    const question = examState.questions[examState.currentIndex];
    const questionId = question.question_id;

    // Toggle selection (multi-select support)
    if (!examState.answers[questionId]) {
        examState.answers[questionId] = [];
    }

    const idx = examState.answers[questionId].indexOf(letter);
    if (idx > -1) {
        examState.answers[questionId].splice(idx, 1);
    } else {
        examState.answers[questionId].push(letter);
    }

    // Save to localStorage immediately
    saveAnswers();

    // Sync to server if online
    if (examState.isOnline) {
        syncAnswer(questionId, examState.answers[questionId]);
    }

    // Re-render to show selection
    renderQuestion(examState.currentIndex);
    updateProgress();
}

function navigateQuestion(direction) {
    if (examState.isTerminated) return;

    const newIndex = examState.currentIndex + direction;

    if (newIndex >= 0 && newIndex < examState.questions.length) {
        renderQuestion(newIndex);
    } else if (newIndex >= examState.questions.length) {
        // Show submit confirmation
        elements.submitBtn.scrollIntoView({ behavior: 'smooth' });
    }
}

// ==================== QUESTION DOTS ====================

function renderQuestionDots() {
    elements.questionDots.innerHTML = examState.questions.map((q, i) => `
        <div class="dot" data-index="${i}" onclick="jumpToQuestion(${i})"></div>
    `).join('');
}

function updateQuestionDots() {
    const dots = elements.questionDots.querySelectorAll('.dot');
    dots.forEach((dot, i) => {
        const question = examState.questions[i];
        const isAnswered = examState.answers[question.question_id]?.length > 0;

        dot.classList.toggle('answered', isAnswered);
        dot.classList.toggle('current', i === examState.currentIndex);
    });
}

function jumpToQuestion(index) {
    if (examState.isTerminated) return;
    renderQuestion(index);
}

// ==================== PROGRESS ====================

function updateProgress() {
    const answered = Object.values(examState.answers).filter(a => a.length > 0).length;
    const total = examState.questions.length;
    const percent = (answered / total) * 100;

    elements.progressBar.style.setProperty('--progress', `${percent}%`);
    elements.progressText.textContent = `${answered} / ${total}`;
}

// ==================== TIMER ====================

function startTimer() {
    updateTimerDisplay();

    examState.timerInterval = setInterval(() => {
        if (examState.isTerminated) {
            clearInterval(examState.timerInterval);
            return;
        }

        examState.timeRemaining--;
        updateTimerDisplay();

        // Save time to localStorage every 10 seconds
        if (examState.timeRemaining % 10 === 0) {
            saveSession();
        }

        // Auto-submit when time runs out
        if (examState.timeRemaining <= 0) {
            clearInterval(examState.timerInterval);
            submitExam(true);
        }

        // Warning at 5 minutes
        if (examState.timeRemaining === 300) {
            elements.timer.style.color = '#f59e0b';
        }

        // Critical at 1 minute
        if (examState.timeRemaining === 60) {
            elements.timer.style.color = '#ef4444';
        }
    }, 1000);
}

function updateTimerDisplay() {
    const minutes = Math.floor(examState.timeRemaining / 60);
    const seconds = examState.timeRemaining % 60;
    elements.timeDisplay.textContent = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
}

// ==================== LOCAL STORAGE ====================

function saveSession() {
    const sessionData = {
        sessionToken: examState.sessionToken,
        rollNo: examState.rollNo,
        studentEmail: examState.studentEmail,
        studentName: examState.studentName,
        questions: examState.questions,
        timeRemaining: examState.timeRemaining,
        examStarted: examState.examStarted,
        savedAt: new Date().toISOString()
    };
    localStorage.setItem('bgnu_exam_session', JSON.stringify(sessionData));
}

function saveAnswers() {
    localStorage.setItem('bgnu_exam_answers', JSON.stringify(examState.answers));
}

function loadSavedSession() {
    try {
        const sessionData = localStorage.getItem('bgnu_exam_session');
        const answersData = localStorage.getItem('bgnu_exam_answers');

        if (sessionData) {
            const session = JSON.parse(sessionData);
            examState.sessionToken = session.sessionToken;
            examState.rollNo = session.rollNo;
            examState.studentEmail = session.studentEmail;
            examState.studentName = session.studentName;
            examState.questions = session.questions;
            examState.timeRemaining = session.timeRemaining;

            // Pre-fill form
            if (elements.rollNoInput) elements.rollNoInput.value = session.rollNo || '';
            if (elements.studentEmailInput) elements.studentEmailInput.value = session.studentEmail || '';
            if (elements.studentNameInput) elements.studentNameInput.value = session.studentName || '';
        }

        if (answersData) {
            examState.answers = JSON.parse(answersData);
        }

        return sessionData !== null && examState.questions && examState.questions.length > 0;
    } catch (e) {
        console.error('Failed to load saved session:', e);
        return false;
    }
}

function loadSavedAnswers() {
    const saved = localStorage.getItem('bgnu_exam_answers');
    if (saved) {
        examState.answers = JSON.parse(saved);
    }
}

function clearSession() {
    localStorage.removeItem('bgnu_exam_session');
    localStorage.removeItem('bgnu_exam_answers');
}

// ==================== SYNC TO SERVER ====================

async function syncAnswer(questionId, selectedChoices) {
    if (!examState.isOnline || examState.isTerminated) return;

    // Skip sync if no choices selected
    if (!selectedChoices || selectedChoices.length === 0) {
        console.log('[BGNU Exam] Skipping sync for empty answer on question:', questionId);
        return;
    }

    console.log('[BGNU Exam] Syncing answer:', { questionId, selectedChoices, sessionToken: examState.sessionToken?.substring(0, 20) });

    try {
        // Sync individual answer
        const answerResponse = await fetch(`${API_BASE}/submit-answer.php`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                session_token: examState.sessionToken,
                question_id: questionId,
                selected_choice: selectedChoices.join(','),
                response_time_seconds: 0
            })
        });

        const answerResult = await answerResponse.json();
        console.log('[BGNU Exam] Answer sync result:', answerResult);

        if (!answerResult.success) {
            console.error('[BGNU Exam] Answer sync failed:', answerResult);
        }

        // Also sync progress
        await fetch(`${API_BASE}/sync-progress.php`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                session_token: examState.sessionToken,
                student_email: examState.studentEmail,
                student_name: examState.studentName,
                roll_no: examState.rollNo,
                exam_code: 'FLUTTER2026',
                answers: examState.answers,
                time_remaining: examState.timeRemaining,
                current_question: examState.currentIndex + 1,
                total_questions: examState.questions.length
            })
        });
    } catch (e) {
        console.error('[BGNU Exam] Sync failed:', e);
    }
}

async function syncPendingAnswers() {
    if (!examState.isOnline || !examState.sessionToken || examState.isTerminated) return;

    try {
        // Sync all answers
        for (const [qid, choices] of Object.entries(examState.answers)) {
            if (choices.length > 0) {
                await fetch(`${API_BASE}/submit-answer.php`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        session_token: examState.sessionToken,
                        question_id: parseInt(qid),
                        selected_choice: choices.join(','),
                        response_time_seconds: 0
                    })
                });
            }
        }
        console.log('All pending answers synced');
    } catch (e) {
        console.warn('Failed to sync pending answers:', e);
    }
}

// ==================== SUBMIT EXAM ====================

async function submitExam(autoSubmit = false) {
    if (examState.isTerminated) return;

    if (!examState.isOnline) {
        alert('You are offline. Please connect to the internet to submit your exam.');
        return;
    }

    if (!autoSubmit) {
        const answered = Object.values(examState.answers).filter(a => a.length > 0).length;
        const total = examState.questions.length;

        if (answered < total) {
            const confirm = window.confirm(`You have answered ${answered} of ${total} questions. Are you sure you want to submit?`);
            if (!confirm) return;
        }
    }

    clearInterval(examState.timerInterval);
    elements.submitBtn.disabled = true;
    elements.submitBtn.textContent = 'Submitting...';

    try {
        // First sync all answers
        await syncPendingAnswers();

        // Then submit exam
        const response = await fetch(`${API_BASE}/submit-exam.php`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                session_token: examState.sessionToken
            })
        });

        const data = await response.json();

        if (data.success) {
            showResult(data.result, autoSubmit);
            clearSession();
            notifyParent('exam_completed', { result: data.result });
        } else {
            throw new Error(data.error || 'Submission failed');
        }
    } catch (e) {
        console.error('Submit error:', e);
        alert('Failed to submit. Your answers are saved locally. Please try again.');
        elements.submitBtn.disabled = false;
        elements.submitBtn.textContent = '✅ Submit Exam';
    }
}

function showResult(result, wasAutoSubmit) {
    elements.examScreen.classList.add('hidden');
    elements.resultScreen.classList.remove('hidden');

    console.log('[BGNU Exam] Result received:', result);

    // Use fallbacks
    const score = result?.score ?? 0;
    const maxScore = result?.max_score ?? examState.questions.length;
    const percentage = result?.percentage ?? 0;
    const passed = result?.passed ?? false;
    const totalQuestions = result?.total_questions ?? examState.questions.length;
    const totalAnswered = result?.total_answered ?? 0;

    // Calculate counts from examState.answers and questions
    const correctQuestions = [];
    const wrongQuestions = [];
    const notAttemptedQuestions = [];

    examState.questions.forEach((q, idx) => {
        const qid = q.question_id;
        const studentAnswer = examState.answers[qid] || [];
        const correctAnswer = q.correct_shuffled ? q.correct_shuffled.split(',') : [];

        if (studentAnswer.length === 0) {
            notAttemptedQuestions.push({ ...q, index: idx + 1, studentAnswer: [] });
        } else {
            // Compare answers
            const studentSorted = [...studentAnswer].sort();
            const correctSorted = [...correctAnswer].sort();
            const isCorrect = JSON.stringify(studentSorted) === JSON.stringify(correctSorted);

            if (isCorrect) {
                correctQuestions.push({ ...q, index: idx + 1, studentAnswer });
            } else {
                wrongQuestions.push({ ...q, index: idx + 1, studentAnswer, correctAnswer });
            }
        }
    });

    // Store for modal access
    window.examResultDetails = { correctQuestions, wrongQuestions, notAttemptedQuestions };

    if (wasAutoSubmit) {
        elements.resultIcon.textContent = '⏰';
        elements.resultTitle.textContent = 'Time\'s Up!';
        elements.resultMessage.textContent = 'Your exam has been auto-submitted.';
    } else {
        elements.resultIcon.textContent = passed ? '🎉' : '📝';
        elements.resultTitle.textContent = passed ? 'Congratulations!' : 'Exam Submitted';
        elements.resultMessage.textContent = passed ? 'You passed the exam!' : 'Your answers have been recorded.';
    }

    elements.resultStats.innerHTML = `
        <div class="stat-item">
            <div class="stat-value">${score}/${maxScore}</div>
            <div class="stat-label">Score</div>
        </div>
        <div class="stat-item">
            <div class="stat-value">${percentage}%</div>
            <div class="stat-label">Percentage</div>
        </div>
        <div class="stat-item clickable" onclick="showQuestionDetails('correct')" style="cursor: pointer; transition: transform 0.2s;" onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'">
            <div class="stat-value" style="color: #22c55e;">✓ ${correctQuestions.length}</div>
            <div class="stat-label">Correct</div>
        </div>
        <div class="stat-item clickable" onclick="showQuestionDetails('wrong')" style="cursor: pointer; transition: transform 0.2s;" onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'">
            <div class="stat-value" style="color: #ef4444;">✗ ${wrongQuestions.length}</div>
            <div class="stat-label">Wrong</div>
        </div>
        <div class="stat-item clickable" onclick="showQuestionDetails('notAttempted')" style="cursor: pointer; transition: transform 0.2s;" onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'">
            <div class="stat-value" style="color: #f59e0b;">○ ${notAttemptedQuestions.length}</div>
            <div class="stat-label">Not Attempted</div>
        </div>
        <div style="grid-column: 1/-1; margin-top: 24px; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;">
            <button onclick="goBackToBrowser()" style="
                padding: 14px 32px;
                background: linear-gradient(135deg, #6366f1, #8b5cf6);
                color: white;
                border: none;
                border-radius: 12px;
                font-size: 16px;
                font-weight: 600;
                cursor: pointer;
                transition: transform 0.2s, box-shadow 0.2s;
            " onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'">
                ← Back to BGNU Browser
            </button>
            <button onclick="showLeaderboard()" style="
                padding: 14px 32px;
                background: transparent;
                border: 2px solid #f59e0b;
                color: #f59e0b;
                border-radius: 12px;
                font-size: 16px;
                font-weight: 600;
                cursor: pointer;
                transition: transform 0.2s, box-shadow 0.2s;
            " onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'">
                🏆 View Leaderboard
            </button>
        </div>
    `;
}

// Show question details modal
function showQuestionDetails(type) {
    const data = window.examResultDetails;
    if (!data) return;

    let questions, title, color;
    if (type === 'correct') {
        questions = data.correctQuestions;
        title = '✓ Correct Answers';
        color = '#22c55e';
    } else if (type === 'wrong') {
        questions = data.wrongQuestions;
        title = '✗ Wrong Answers';
        color = '#ef4444';
    } else {
        questions = data.notAttemptedQuestions;
        title = '○ Not Attempted';
        color = '#f59e0b';
    }

    const overlay = document.createElement('div');
    overlay.id = 'question-details-overlay';
    overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.9);display:flex;align-items:center;justify-content:center;z-index:10000;overflow-y:auto;padding:20px;';

    let html = `
        <div style="background:#161B22;border-radius:16px;padding:24px;max-width:600px;max-height:80vh;overflow-y:auto;width:100%;">
            <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;position:sticky;top:-24px;background:#161B22;padding:10px 0;">
                <h2 style="color:${color};margin:0;">${title} (${questions.length})</h2>
                <button onclick="document.getElementById('question-details-overlay').remove()" style="background:none;border:none;color:white;font-size:24px;cursor:pointer;">×</button>
            </div>
    `;

    if (questions.length === 0) {
        html += '<p style="color:#8B949E;text-align:center;">No questions in this category.</p>';
    } else {
        questions.forEach(q => {
            html += `
                <div style="background:#0D1117;border:1px solid ${color}33;border-radius:10px;padding:16px;margin-bottom:12px;">
                    <div style="color:white;font-weight:600;margin-bottom:12px;">Q${q.index}: ${q.question_prompt}</div>
                    <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:12px;">
                        ${['A', 'B', 'C', 'D'].map(letter => {
                const optionKey = `choice_${letter.toLowerCase()}`;
                const optionText = q[optionKey] || '';
                const isSelected = q.studentAnswer && q.studentAnswer.includes(letter);
                const isCorrect = q.correct_shuffled && q.correct_shuffled.includes(letter);

                let bgColor = '#21262D';
                let borderColor = '#30363D';
                if (isCorrect) {
                    bgColor = 'rgba(34, 197, 94, 0.2)';
                    borderColor = '#22c55e';
                }
                if (isSelected && !isCorrect) {
                    bgColor = 'rgba(239, 68, 68, 0.2)';
                    borderColor = '#ef4444';
                }

                return `<div style="padding:10px;background:${bgColor};border:1px solid ${borderColor};border-radius:6px;font-size:13px;color:#c9d1d9;">
                                <span style="font-weight:bold;">${letter}.</span> ${optionText}
                                ${isCorrect ? '<span style="color:#22c55e;float:right;">✓</span>' : ''}
                                ${isSelected && !isCorrect ? '<span style="color:#ef4444;float:right;">✗</span>' : ''}
                            </div>`;
            }).join('')}
                    </div>
                    ${type !== 'notAttempted' ? `
                        <div style="font-size:12px;color:#8B949E;">
                            Your answer: <span style="color:${type === 'correct' ? '#22c55e' : '#ef4444'};">${q.studentAnswer ? q.studentAnswer.join(', ') : 'None'}</span>
                            ${type === 'wrong' ? ` | Correct: <span style="color:#22c55e;">${q.correct_shuffled || 'N/A'}</span>` : ''}
                        </div>
                    ` : '<div style="font-size:12px;color:#8B949E;">Correct answer: <span style="color:#22c55e;">' + (q.correct_shuffled || 'N/A') + '</span></div>'}
                </div>
            `;
        });
    }

    html += '</div>';
    overlay.innerHTML = html;

    overlay.addEventListener('click', (e) => {
        if (e.target === overlay) overlay.remove();
    });

    document.body.appendChild(overlay);
}

window.showQuestionDetails = showQuestionDetails;

// ==================== HELPERS ====================

function showStatus(message, type) {
    elements.loadStatus.textContent = message;
    elements.loadStatus.className = 'helper-text';

    if (type === 'error') {
        elements.loadStatus.style.color = '#ef4444';
    } else if (type === 'success') {
        elements.loadStatus.style.color = '#22c55e';
    } else {
        elements.loadStatus.style.color = '#a0a0b0';
    }
}

// Navigate back to BGNU Browser home
function goBackToBrowser() {
    // Notify Flutter that we want to exit exam mode
    notifyParent('exam_exit', { action: 'back_to_browser' });

    // Try multiple methods to go back
    if (window.history.length > 1) {
        // If there's history, go back
        window.history.back();
    } else {
        // Otherwise navigate to home/about:blank
        window.location.href = 'about:blank';
    }
}

// Make functions available globally for onclick handlers
window.selectOption = selectOption;
window.jumpToQuestion = jumpToQuestion;
window.goBackToBrowser = goBackToBrowser;
window.showLeaderboard = showLeaderboard;

// Show Leaderboard Modal
async function showLeaderboard() {
    // Create loading overlay
    const overlay = document.createElement('div');
    overlay.id = 'leaderboard-overlay';
    overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.9);display:flex;align-items:center;justify-content:center;z-index:10000;';
    overlay.innerHTML = '<div style="color:white;font-size:24px;">Loading leaderboard...</div>';
    document.body.appendChild(overlay);

    try {
        const response = await fetch(`${API_BASE}/leaderboard.php?exam_code=FLUTTER2026`);
        const data = await response.json();

        if (!data.success || !data.leaderboard) {
            throw new Error('Failed to load leaderboard');
        }

        const leaderboard = data.leaderboard;

        let html = `
            <div style="background:#161B22;border-radius:16px;padding:24px;max-width:500px;max-height:80vh;overflow-y:auto;width:90%;">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;">
                    <h2 style="color:white;margin:0;">🏆 Leaderboard</h2>
                    <button onclick="document.getElementById('leaderboard-overlay').remove()" style="background:none;border:none;color:white;font-size:24px;cursor:pointer;">×</button>
                </div>
        `;

        if (leaderboard.length === 0) {
            html += '<p style="color:#8B949E;text-align:center;">No results yet. Be the first!</p>';
        } else {
            leaderboard.forEach((entry, index) => {
                const rank = entry.rank || (index + 1);
                const isTopThree = rank <= 3;
                const rankColors = ['#FFD700', '#C0C0C0', '#CD7F32']; // Gold, Silver, Bronze
                const rankColor = isTopThree ? rankColors[rank - 1] : '#21262D';
                const passed = entry.passed;

                html += `
                    <div style="display:flex;align-items:center;padding:12px;background:${isTopThree ? 'rgba(255,183,3,0.1)' : '#0D1117'};border:1px solid ${isTopThree ? '#f59e0b' : '#30363D'};border-radius:10px;margin-bottom:8px;">
                        <div style="width:36px;height:36px;background:${rankColor};border-radius:50%;display:flex;align-items:center;justify-content:center;color:${isTopThree ? 'black' : 'white'};font-weight:bold;font-size:12px;">#${rank}</div>
                        <div style="flex:1;margin-left:12px;">
                            <div style="color:white;font-weight:600;">${entry.student_name || 'Unknown'}</div>
                        </div>
                        <div style="text-align:right;">
                            <div style="color:${passed ? '#22c55e' : '#ef4444'};font-weight:bold;font-size:16px;">${entry.percentage || 0}%</div>
                            <div style="color:#8B949E;font-size:12px;">${entry.score || 0}/${entry.max_score || 30}</div>
                        </div>
                    </div>
                `;
            });
        }

        html += '</div>';
        overlay.innerHTML = html;

    } catch (e) {
        console.error('Leaderboard error:', e);
        overlay.innerHTML = `
            <div style="background:#161B22;border-radius:16px;padding:24px;text-align:center;">
                <p style="color:#ef4444;margin-bottom:20px;">Failed to load leaderboard</p>
                <button onclick="document.getElementById('leaderboard-overlay').remove()" style="padding:12px 24px;background:#6366f1;color:white;border:none;border-radius:8px;cursor:pointer;">Close</button>
            </div>
        `;
    }
}

