// quiz.js
/**
 * mkdocs-superquiz - Logique principale JavaScript
 */

window.QUIZ_CONFIG = window.QUIZ_CONFIG || {};

function t(key, fallback = "") {
    const keys = key.split('.');
    let value = window.QUIZ_CONFIG?.i18n;

    for (const k of keys) {
        if (value && typeof value === 'object') {
            value = value[k];
        } else {
            return fallback || key;
        }
    }
    return value || fallback || key;
}

let currentUnlockContext = null;

function createUnlockModal() {
    const modal = document.createElement('div');
    modal.id = 'mkq-unlock-modal';
    modal.className = 'mkq-modal';
    modal.innerHTML = `
        <div class="mkq-modal-content">
            <button class="mkq-modal-close" onclick="closeUnlockModal()">×</button>
            <h3 id="mkq-unlock-title">${t("ui.unlock_title", "Unlock Correction")}</h3>
            <div class="qr-code-section">
                <p>${t("ui.unlock_qr_instruction", "Ask your teacher to scan this QR code:")}</p>
                <div id="qr-code-container"></div>
            </div>
            <div class="unlock-input-section">
                <label for="mkq-unlock-code-input">${t("ui.unlock_code_label", "Unlock code (provided by teacher):")}</label>
                <input type="text" id="mkq-unlock-code-input" placeholder="${t("ui.unlock_code_placeholder", "e.g., A7F3E9C2")}">
                <button onclick="validateUnlockCode()">${t("ui.unlock_validate", "Validate")}</button>
            </div>
        </div>
    `;
    document.body.appendChild(modal);
}

function getSiteUrl() {
    const currentOrigin = window.location.origin;
    const currentPath = window.location.pathname;

    const baseElement = document.querySelector('base');
    if (baseElement && baseElement.href) {
        const baseUrl = new URL(baseElement.href);
        return baseUrl.origin + baseUrl.pathname.replace(/\/$/, '');
    }

    const pathParts = currentPath.split('/').filter(p => p);

    if (pathParts.length > 0) {
        const firstPart = pathParts[0];

        const isProjectName = !firstPart.includes('.html') &&
            !firstPart.includes('.') &&
            firstPart !== 'search' &&
            firstPart !== 'assets';

        if (currentPath.includes('/mkdocs-superquiz/')) {
            return currentOrigin + '/mkdocs-superquiz';
        }

        const knownPages = ['index', 'sample_quiz', 'search', 'sitemap'];
        if (isProjectName && !knownPages.includes(firstPart)) {
            return currentOrigin + '/' + firstPart;
        }
    }
    return currentOrigin;
}

function showUnlockModal(type, exerciseId = null, questionId = null) {
    const modal = document.getElementById('mkq-unlock-modal');
    if (!modal) return;

    const pageUuid = document.querySelector('.mkdocs-superquiz')?.dataset.pageUuid;
    if (!pageUuid) return;

    const siteUrl = getSiteUrl();

    const data = {
        type: type,
        page_id: pageUuid,
        page_title: document.title,
        site_url: siteUrl
    };

    if (type === 'exercise' || type === 'question') {
        data.exercise_id = exerciseId;

        const exerciseElement = document.querySelector(`[data-quiz-id="${exerciseId}"]`);
        if (exerciseElement) {
            const titleElement = exerciseElement.querySelector('.admonition-title');
            let title = titleElement ? titleElement.textContent.trim() : '';
            title = title
                .replace(/🔒/g, '').replace(/🔓/g, '').replace(/❌/g, '').replace(/🔐/g, '').replace(/✅/g, '')
                .replace(/\n/g, ' ').replace(/\s+/g, ' ').trim();
            data.exercise_title = title;
        }
    }

    if (type === 'question') {
        data.question_id = questionId;
        const questionElement = document.querySelector(`[data-quiz-id="${exerciseId}"] [data-question-id="${questionId}"]`);
        if (questionElement) {
            const textElement = questionElement.querySelector('.mkq-question-text');
            let questionText = textElement ? textElement.textContent.trim() : '';
            questionText = questionText
                .replace(/🔒/g, '').replace(/🔓/g, '').replace(/❌/g, '').replace(/🔐/g, '').replace(/✅/g, '')
                .replace(/\n/g, ' ').replace(/\s+/g, ' ').trim();
            data.question_text = questionText;
        }
    }

    currentUnlockContext = data;

    const titleElement = document.getElementById('mkq-unlock-title');
    if (titleElement) {
        if (type === 'page') {
            titleElement.textContent = t("ui.unlock_page_title", "Unlock All Page Quizzes");
        } else if (type === 'exercise') {
            titleElement.textContent = `${t("ui.unlock_quiz", "Unlock Quiz")} ${exerciseId}`;
        } else {
            titleElement.textContent = `${t("ui.unlock_quiz_question", "Unlock this quiz question")} ${questionId}`;
        }
    }

    generateQRCode(data);
    modal.classList.add('active');
}

function generateQRCode(data) {
    const container = document.getElementById('qr-code-container');
    if (!container) return;

    const jsonString = JSON.stringify(data);
    const utf8Bytes = new TextEncoder().encode(jsonString);
    let binaryString = '';
    for (let i = 0; i < utf8Bytes.length; i++) {
        binaryString += String.fromCharCode(utf8Bytes[i]);
    }
    const encodedData = btoa(binaryString);

    const unlockUrl = `${data.site_url}/quiz-unlock.html?data=${encodedData}`;

    if (typeof qrcode === 'undefined') {
        container.innerHTML = `<p style="color:red;">${t("ui.error_no_library", "Error: No QR Code library has been downloaded")}</p>`;
        return;
    }

    try {
        const qr = qrcode(0, 'H');
        qr.addData(unlockUrl);
        qr.make();

        const cellSize = 4;
        const margin = 4;
        const svgTag = qr.createSvgTag(cellSize, margin);

        container.innerHTML = svgTag;

        const svg = container.querySelector('svg');
        if (svg) {
            svg.style.display = 'block';
            svg.style.maxWidth = '256px';
            svg.style.height = 'auto';
            svg.style.margin = '0 auto';
            svg.style.padding = '10px';
            svg.style.background = 'white';
            svg.style.borderRadius = '8px';
            svg.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)';
        }
    } catch (error) {
        container.innerHTML = `<p style="color:red;">${t("ui.error_generating_qrcode", "Error generating QR Code")}</p>`;
    }
}

function closeUnlockModal() {
    const modal = document.getElementById('mkq-unlock-modal');
    if (modal) modal.classList.remove('active');
    const input = document.getElementById('mkq-unlock-code-input');
    if (input) input.value = '';
}

async function validateUnlockCode() {
    const input = document.getElementById('mkq-unlock-code-input');
    if (!input) return;

    const code = input.value.trim().toUpperCase();
    if (!code) {
        alert(t("ui.please_enter_code", "Please enter a code"));
        return;
    }
    if (!currentUnlockContext) {
        alert(t("ui.error_no_unlocking_context", "Error: Unlocking context not found"));
        return;
    }

    const expectedCode = await calculateUnlockCode(currentUnlockContext);

    if (code === expectedCode) {
        unlockCorrections(currentUnlockContext);
        saveUnlockState(currentUnlockContext);
        closeUnlockModal();
    } else {
        alert(t("ui.error_incorrect_code", "Incorrect code. Check with your teacher."));
    }
}

async function calculateUnlockCode(context) {
    const teacherCodeHash = window.QUIZ_CONFIG.teacher_code_hash || '';
    let payload = teacherCodeHash + context.page_id + context.type;

    if (context.type === 'exercise' || context.type === 'question') {
        payload += (context.exercise_id || '');
    }
    if (context.type === 'question') {
        payload += (context.question_id || '');
    }

    const hash = await sha256(payload);
    return hash.substring(0, 8).toUpperCase();
}

async function sha256(str) {
    const buffer = new TextEncoder().encode(str);
    const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}

function updateLockIcon(element, unlocked) {
    if (!element) return;

    if (unlocked) {
        element.textContent = '🔓';
        element.classList.remove('locked');
        element.classList.add('unlocked');
        element.setAttribute('data-lock-state', 'unlocked');
        element.setAttribute('title', t("ui.unlocked_corrections", "Unlocked corrections"));
        element.onclick = null;
        element.style.cursor = 'default';
    } else {
        element.textContent = '🔒';
        element.classList.remove('unlocked');
        element.classList.add('locked');
        element.setAttribute('data-lock-state', 'locked');
        element.setAttribute('title', t("ui.lock_tooltip_locked", "Click to unlock corrections"));
    }
}

function shouldShowCorrections(quiz) {
    const lockIndicator = quiz.querySelector('.mkq-lock-indicator, .mkq-unlock-btn');

    if (!lockIndicator) return true;

    const lockState = lockIndicator.getAttribute('data-lock-state');

    if (lockState === 'locked-permanent') return false;
    if (lockState === 'unlocked') return true;

    if (lockState === 'locked') {
        const pageUuid = quiz.dataset.pageUuid;
        const quizId = quiz.dataset.quizId;
        const unlocks = JSON.parse(localStorage.getItem('mkq_unlocks') || '[]');
        const isUnlocked = unlocks.some(unlock =>
            unlock.page_id === pageUuid &&
            (unlock.type === 'page' || unlock.exercise_id === quizId)
        );
        return isUnlocked;
    }

    return true;
}

function unlockCorrections(context) {
    if (context.type === 'page') {
        document.querySelectorAll('.mkq-unlock-btn').forEach(btn => updateLockIcon(btn, true));
        document.querySelectorAll('.mkdocs-superquiz').forEach(quiz => {
            const quizId = quiz.dataset.quizId;
            if (quizId) validateQuiz(quizId);
        });
    } else if (context.type === 'exercise') {
        const exercise = document.querySelector(`[data-quiz-id="${context.exercise_id}"]`);
        if (exercise) {
            const lockBtn = exercise.querySelector('.mkq-unlock-btn');
            updateLockIcon(lockBtn, true);
            validateQuiz(context.exercise_id);
        }
    } else if (context.type === 'question') {
        const exercise = document.querySelector(`[data-quiz-id="${context.exercise_id}"]`);
        if (exercise) {
            const question = exercise.querySelector(`[data-question-id="${context.question_id}"]`);
            if (question) {
                const lockBtn = question.querySelector('.mkq-unlock-btn');
                updateLockIcon(lockBtn, true);
            }
            validateQuiz(context.exercise_id);
        }
    }
}

function saveUnlockState(context) {
    const unlocks = JSON.parse(localStorage.getItem('mkq_unlocks') || '[]');
    unlocks.push({
        page_id: context.page_id,
        type: context.type,
        exercise_id: context.exercise_id,
        question_id: context.question_id,
        timestamp: new Date().toISOString()
    });
    localStorage.setItem('mkq_unlocks', JSON.stringify(unlocks));
}

function restoreUnlockedCorrections() {
    const unlocks = JSON.parse(localStorage.getItem('mkq_unlocks') || '[]');
    const currentPageUuid = document.querySelector('.mkdocs-superquiz')?.dataset.pageUuid;
    if (!currentPageUuid) return;

    unlocks.forEach(unlock => {
        if (unlock.page_id === currentPageUuid) unlockCorrections(unlock);
    });
}

// ─────────────────────────────────────────────────────────────────────────────
// Scoring helpers
// ─────────────────────────────────────────────────────────────────────────────

function clampScore(score, pointsMax, minScore, clampMax) {
    let s = score;
    if (clampMax) s = Math.min(s, pointsMax);
    if (minScore !== null && minScore !== undefined) s = Math.max(s, Number(minScore));
    return s;
}

function arraysEqual(a, b) {
    if (a.length !== b.length) return false;
    for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
    return true;
}

function normalizeUnicodeAccents(str) {
    try {
        return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
    } catch {
        return str;
    }
}

function normalizeLatexLoose(str) {
    return str
        .replace(/\s+/g, '')
        .replace(/\*/g, '')
        .replace(/²/g, '^2')
        .replace(/³/g, '^3');
}

// compareAnswers now uses compare_answers config (per quiz payload preferred)
function compareAnswers(userAnswer, correctAnswer, compareConfig) {
    const cfg = compareConfig || window.QUIZ_CONFIG.gapfill || {};

    // Back-compat if old flags exist but compare_answers missing
    const ca = cfg.compare_answers && typeof cfg.compare_answers === 'object' ? cfg.compare_answers : cfg;

    let user = String(userAnswer ?? '');
    let correct = String(correctAnswer ?? '');

    const stripSpaces = (ca.strip_spaces !== false);
    if (stripSpaces) {
        user = user.trim();
        correct = correct.trim();
    }

    if (ca.ignore_spaces) {
        user = user.replace(/\s+/g, '');
        correct = correct.replace(/\s+/g, '');
    }

    // case mode
    const caseSensitive = (ca.case_sensitive === true && ca.ignore_case !== true);
    if (!caseSensitive) {
        user = user.toLowerCase();
        correct = correct.toLowerCase();
    }

    if (ca.ignore_accents) {
        user = normalizeUnicodeAccents(user);
        correct = normalizeUnicodeAccents(correct);
    }

    // latex
    const latex = ca.latex && typeof ca.latex === 'object' ? ca.latex : { mode: ca.strict_latex ? 'strict' : 'loose' };
    const latexMode = latex.mode || 'loose';
    if (latexMode !== 'strict') {
        user = normalizeLatexLoose(user);
        correct = normalizeLatexLoose(correct);
    } else {
        // strict: do nothing
    }

    return user === correct;
}

// Parse losing_mode keys for mcquiz: key like "[Paris, Londres]" -> list of strings
function parseBracketKey(key) {
    const s = String(key).trim();
    if (!s.startsWith('[') || !s.endsWith(']')) return null;
    const inner = s.slice(1, -1).trim();
    if (!inner) return [];
    return inner.split(',').map(x => x.trim()).filter(Boolean);
}

function scoreChoiceQuestion(questionData, selectedIndices) {
    const points = Number(questionData.points || 1);
    const scoringMode = questionData.scoring_mode || 'all_or_nothing';
    const defaultFalse = Number(questionData.default_false ?? 0);

    const correct = Array.isArray(questionData.correct_answers) ? questionData.correct_answers : [];
    const correctSet = new Set(correct);

    let nbGood = 0;
    let nbFalse = 0;
    selectedIndices.forEach(i => {
        if (correctSet.has(i)) nbGood++;
        else nbFalse++;
    });

    const nbGoodTotal = correct.length || 1;

    // base score
    let base = 0;
    const selSorted = [...selectedIndices].sort((a,b)=>a-b);
    const corSorted = [...correct].sort((a,b)=>a-b);
    const exact = arraysEqual(selSorted, corSorted);

    if (scoringMode === 'all_or_nothing') {
        base = exact ? points : 0;
    } else if (scoringMode === 'some_or_nothing') {
        if (nbFalse > 0) base = 0;
        else base = points * (nbGood / nbGoodTotal);
    } else { // proportional
        base = points * ((nbGood / nbGoodTotal) - (nbFalse / nbGoodTotal));
    }

    // losing_mode override
    const lm = questionData.losing_mode || null;
    if (lm && Array.isArray(lm.rules)) {
        const answersText = Array.isArray(questionData.answers_text) ? questionData.answers_text : [];
        const selectedTexts = selectedIndices.map(i => answersText[i] ?? '').filter(Boolean);

        let matchedRule = null;
        for (const r of lm.rules) {
            const key = r.key;
            const list = parseBracketKey(key);
            if (!list) continue;
            const a = [...selectedTexts].map(x => x.trim()).sort();
            const b = [...list].map(x => x.trim()).sort();
            if (arraysEqual(a, b)) {
                matchedRule = r;
                break;
            }
        }

        if (matchedRule) {
            base = Number(matchedRule.score);
        } else {
            // ambiguity resolution: if lm.default_false is defined, it wins over score_base
            if (lm.default_false !== null && lm.default_false !== undefined) {
                base = Number(lm.default_false);
            } else {
                // keep base as computed
            }
        }
    }

    const minScore = questionData.min_score ?? window.QUIZ_CONFIG.min_score ?? null;
    const clampMax = (questionData.clamp_max_score ?? window.QUIZ_CONFIG.clamp_max_score ?? true);
    return clampScore(base, points, minScore, clampMax);
}

function scoreScQuizQuestion(questionData, selectedIndex) {
    const points = Number(questionData.points || 1);
    const correct = Array.isArray(questionData.correct_answers) ? questionData.correct_answers : [];
    const correctIndex = correct.length ? correct[0] : 0;

    let base = (selectedIndex === correctIndex) ? points : 0;

    const lm = questionData.losing_mode || null;
    if (lm && Array.isArray(lm.rules)) {
        const answersText = Array.isArray(questionData.answers_text) ? questionData.answers_text : [];
        const selectedText = (selectedIndex >= 0 && selectedIndex < answersText.length) ? answersText[selectedIndex] : '';

        // For scquiz, rules store key as raw string; match by exact text string
        let matched = null;
        for (const r of lm.rules) {
            if (String(r.key).trim() === String(selectedText).trim()) {
                matched = r;
                break;
            }
        }

        if (matched) {
            base = Number(matched.score);
        } else {
            if (lm.default_false !== null && lm.default_false !== undefined) {
                base = Number(lm.default_false);
            }
        }
    }

    const minScore = questionData.min_score ?? window.QUIZ_CONFIG.min_score ?? null;
    const clampMax = (questionData.clamp_max_score ?? window.QUIZ_CONFIG.clamp_max_score ?? true);
    return clampScore(base, points, minScore, clampMax);
}

function scoreGapfillQuestion(questionData, userAnswers) {
    const points = Number(questionData.points || 1);
    const gaps = Array.isArray(questionData.gaps) ? questionData.gaps : [];
    const n = gaps.length || 1;

    const scoringMode = questionData.scoring_mode || 'proportional';
    const perGap = points / n;

    const lm = questionData.losing_mode || { gaps: [] };
    const compareCfg =
        questionData.compare_answers ||
        window.QUIZ_CONFIG.gapfill?.compare_answers ||
        window.QUIZ_CONFIG.gapfill ||
        {};

    // 1) Évalue chaque gap (correct / wrong / empty)
    let correctCount = 0;
    let anyWrongNonEmpty = false;
    const gapStates = []; // {isCorrect, isEmpty, ua}

    for (let i = 0; i < gaps.length; i++) {
        const gap = gaps[i];
        const ua = String(userAnswers[i] ?? '').trim();
        const accepted = Array.isArray(gap.answers) ? gap.answers : [];

        const isEmpty = (ua === '');
        const isCorrect = !isEmpty && accepted.some(ans => compareAnswers(ua, ans, compareCfg));

        if (isCorrect) correctCount++;
        if (!isCorrect && !isEmpty) anyWrongNonEmpty = true;

        gapStates.push({ isCorrect, isEmpty, ua });
    }

    // 2) score_base selon scoring_mode (SANS losing_mode)
    let total = 0;

    if (scoringMode === 'all_or_nothing') {
        total = (correctCount === gaps.length) ? points : 0;
    } else if (scoringMode === 'some_or_nothing') {
        // si au moins une mauvaise réponse NON VIDE -> 0, sinon proportionnel
        total = anyWrongNonEmpty ? 0 : (perGap * correctCount);
    } else {
        // proportional
        total = perGap * correctCount;
    }

    // 3) Apply losing_mode gap-par-gap (plus spécifique que scoring_mode)
    for (let i = 0; i < gaps.length; i++) {
        const st = gapStates[i];
        // if (st.isCorrect || st.isEmpty) continue;
        if (st.isCorrect) continue;

        const gLm = (lm.gaps && lm.gaps[i]) ? lm.gaps[i] : null;
        if (!gLm) continue;

        const rules = Array.isArray(gLm.rules) ? gLm.rules : [];
        const defFalse =
            (gLm.default_false !== null && gLm.default_false !== undefined) ? Number(gLm.default_false)
            : ((gLm.default !== null && gLm.default !== undefined) ? Number(gLm.default) : null); // alias backward

        let matched = null;
        for (const r of rules) {
            if (compareAnswers(st.ua, r.answer, compareCfg)) {
                matched = r;
                break;
            }
        }

        if (matched) {
            total += Number(matched.score);
        } else if (defFalse !== null) {
            total += defFalse;
        }
        // sinon: on ne rajoute rien (0)
    }

    const minScore = questionData.min_score ?? window.QUIZ_CONFIG.min_score ?? null;
    const clampMax = (questionData.clamp_max_score ?? window.QUIZ_CONFIG.clamp_max_score ?? true);
    return clampScore(total, points, minScore, clampMax);
}



function scoreDropdownQuestion(questionData, selectedIndices) {
    const points = Number(questionData.points || 1);
    const dropdowns = Array.isArray(questionData.dropdowns) ? questionData.dropdowns :
        (Array.isArray(questionData.dropdowns) ? questionData.dropdowns : questionData.dropdowns);

    const ddList = Array.isArray(questionData.dropdowns) ? questionData.dropdowns :
        (Array.isArray(questionData.dropdown) ? questionData.dropdown : questionData.dropdowns);

    const dds = Array.isArray(questionData.dropdowns) ? questionData.dropdowns :
        (Array.isArray(questionData.dropdowns) ? questionData.dropdowns : (questionData.dropdowns || []));

    const actual = Array.isArray(questionData.dropdowns) ? questionData.dropdowns : (questionData.dropdowns || questionData.dropdown ? [questionData.dropdown] : []);
    const n = actual.length || 1;
    const per = points / n;

    const scoringMode = questionData.scoring_mode || 'all_or_nothing';
    let total = 0;
    let anyWrong = false;

    const lm = questionData.losing_mode || { dropdowns: [] };

    for (let i = 0; i < actual.length; i++) {
        const dd = actual[i] || {};
        const correctIndex = Number(dd.correct_index ?? 0);
        const sel = (selectedIndices[i] ?? -1);

        const isCorrect = (sel >= 0 && sel === correctIndex);
        if (isCorrect) {
            total += per;
        } else {
            anyWrong = true;

            const ddLm = (lm.dropdowns && lm.dropdowns[i]) ? lm.dropdowns[i] : null;
            const opts = Array.isArray(dd.options) ? dd.options : [];
            const chosenText = (sel >= 0 && sel < opts.length) ? String(opts[sel]) : '';

            if (ddLm && Array.isArray(ddLm.rules) && chosenText) {
                let matched = null;
                for (const r of ddLm.rules) {
                    if (String(r.option).trim() === chosenText.trim()) {
                        matched = r;
                        break;
                    }
                }
                if (matched) {
                    total += Number(matched.score);
                } else {
                    if (ddLm.default_false !== null && ddLm.default_false !== undefined) {
                        total += Number(ddLm.default_false);
                    }
                }
            } else {
                // no losing mode -> 0 for this dropdown
            }
        }
    }

    if (scoringMode === 'all_or_nothing') {
        total = (total >= points - 1e-9) ? points : 0;
    } else if (scoringMode === 'some_or_nothing') {
        if (anyWrong) total = 0;
    } else {
        // proportional
    }

    const minScore = questionData.min_score ?? window.QUIZ_CONFIG.min_score ?? null;
    const clampMax = (questionData.clamp_max_score ?? window.QUIZ_CONFIG.clamp_max_score ?? true);
    return clampScore(total, points, minScore, clampMax);
}

// ─────────────────────────────────────────────────────────────────────────────
// Validation
// ─────────────────────────────────────────────────────────────────────────────

function validateQuiz(quizId) {
    const quiz = document.querySelector(`[data-quiz-id="${quizId}"]`);
    if (!quiz) return;

    const quizType = quiz.dataset.quizType;

    if (quizType === 'gapfill') {
        validateGapfillQuiz(quiz, quizId);
    } else if (quizType === 'dropdown') {
        validateDropdownQuiz(quiz, quizId);
    } else {
        validateChoiceQuiz(quiz, quizId);
    }

    saveAnswers(quizId);
}

function validateChoiceQuiz(quiz, quizId) {
    const questions = quiz.querySelectorAll('.mkq-question[data-question-id]');
    let totalPoints = 0;
    let earnedPoints = 0;

    const encryptedData = quiz.dataset.encrypted;
    const correctionData = decryptAnswers(encryptedData);

    if (!correctionData) {
        alert(t("ui.error_downloading_corrections", "Error downloading corrections"));
        return;
    }

    const showCorrection = shouldShowCorrections(quiz);

    questions.forEach((questionEl) => {
        const questionId = parseInt(questionEl.dataset.questionId, 10);
        const qData = correctionData.questions.find(q => q.number === questionId);
        if (!qData) return;

        totalPoints += Number(qData.points || 1);

        const inputs = questionEl.querySelectorAll('input[type="checkbox"], input[type="radio"]');
        const selected = [];
        inputs.forEach((input, idx) => {
            if (input.checked) selected.push(idx);
        });

        let score = 0;
        if (correctionData.quiz_type === 'scquiz') {
            const selectedIndex = selected.length ? selected[0] : -1;
            score = scoreScQuizQuestion(qData, selectedIndex);
        } else {
            score = scoreChoiceQuestion(qData, selected);
        }

        earnedPoints += score;

        if (showCorrection) {
            const correctIndices = qData.correct_answers || [];
            inputs.forEach((input, idx) => {
                const label = input.closest('.mkq-answer');
                const feedback = label.querySelector('.mkq-answer-feedback');

                label.classList.remove('correct', 'incorrect');
                if (feedback) {
                    feedback.style.display = 'none';
                    feedback.textContent = '';
                    feedback.classList.remove('correct', 'incorrect');
                }

                if (correctIndices.includes(idx)) {
                    label.classList.add('correct');
                    if (feedback) {
                        feedback.textContent = t("feedback.correct", "Correct");
                        feedback.classList.add('correct');
                        feedback.style.display = 'inline';
                    }
                } else if (selected.includes(idx)) {
                    label.classList.add('incorrect');
                    if (feedback) {
                        feedback.textContent = t("feedback.incorrect", "Incorrect");
                        feedback.classList.add('incorrect');
                        feedback.style.display = 'inline';
                    }
                }
            });
        }
    });

    displayScorePoints(quizId, earnedPoints, totalPoints);
}

function validateGapfillQuiz(quiz, quizId) {
    const questions = quiz.querySelectorAll('.mkq-question[data-question-id]');
    let totalPoints = 0;
    let earnedPoints = 0;

    const encryptedData = quiz.dataset.encrypted;
    const correctionData = decryptAnswers(encryptedData);
    if (!correctionData) {
        alert(t("ui.error_downloading_corrections", "Error downloading corrections"));
        return;
    }

    const showCorrection = shouldShowCorrections(quiz);
    const droppedElements = [];

    questions.forEach((questionEl) => {
        const questionId = parseInt(questionEl.dataset.questionId, 10);
        const qData = correctionData.questions.find(q => q.number === questionId);
        if (!qData) return;

        totalPoints += Number(qData.points || 1);

        const gapInputs = questionEl.querySelectorAll('.mkq-gap-input');
        const userAnswers = [];
        gapInputs.forEach((input) => userAnswers.push(input.value));

        const score = scoreGapfillQuestion(qData, userAnswers);
        earnedPoints += score;

        if (!showCorrection) return;

        // feedback per gap (existing behavior preserved as much as possible)
        gapInputs.forEach((input, gapIndex) => {
            const userAnswer = input.value.trim();
            const gap = qData.gaps[gapIndex];
            if (!gap) return;

            const compareCfg = qData.compare_answers || correctionData.compare_answers || window.QUIZ_CONFIG.gapfill?.compare_answers || window.QUIZ_CONFIG.gapfill;
            const isCorrect = gap.answers.some(answer => compareAnswers(userAnswer, answer, compareCfg));

            const nextSibling = input.nextSibling;
            if (nextSibling && nextSibling.classList?.contains('mkq-gap-correction-wrapper')) {
                nextSibling.remove();
            }

            if (isCorrect) {
                input.style.display = '';
                input.classList.add('correct');
                input.classList.remove('incorrect');
            } else {
                input.style.display = 'none';
                input.classList.remove('correct');
                input.classList.add('incorrect');

                const wrapper = document.createElement('span');
                wrapper.className = 'mkq-gap-correction-wrapper';

                const label = document.createElement('span');
                label.className = 'mkq-gap-wrong-label';
                label.innerHTML = `<s>${userAnswer || t("ui.empty_answer", "(empty)")}</s>`;
                wrapper.appendChild(label);

                const dropdownId = `mkq-dropdown-${quizId}-q${questionId}-gap${gapIndex}`;
                const dropdown = createGapfillMathJaxDropdown(dropdownId, gap.answers);
                wrapper.appendChild(dropdown);

                input.after(wrapper);
                droppedElements.push(wrapper);
            }
        });
    });

    displayScorePoints(quizId, earnedPoints, totalPoints);

    if (droppedElements.length > 0) {
        setTimeout(() => {
            if (window.MathJax?.typesetPromise) {
                MathJax.typesetPromise(droppedElements).catch(() => {});
            }
        }, 150);
    }
}

function validateDropdownQuiz(quiz, quizId) {
    const questions = quiz.querySelectorAll('.mkq-question[data-question-id]');
    let totalPoints = 0;
    let earnedPoints = 0;

    const encryptedData = quiz.dataset.encrypted;
    const correctionData = decryptAnswers(encryptedData);
    if (!correctionData) {
        alert(t("ui.error_downloading_corrections", "Error downloading corrections"));
        return;
    }

    const showCorrection = shouldShowCorrections(quiz);

    questions.forEach((questionEl) => {
        const questionId = parseInt(questionEl.dataset.questionId, 10);
        const qData = correctionData.questions.find(q => q.number === questionId);
        if (!qData) return;

        totalPoints += Number(qData.points || 1);

        const dropdownEls = Array.from(questionEl.querySelectorAll('.mkq-custom-dropdown'));
        const ddDataList = Array.isArray(qData.dropdowns) ? qData.dropdowns : (qData.dropdown ? [qData.dropdown] : []);

        const count = Math.min(dropdownEls.length, ddDataList.length);
        const selected = [];

        for (let i = 0; i < count; i++) {
            const dropdown = dropdownEls[i];
            const rawValue = dropdown.dataset.selectedValue;
            const isEmpty = (rawValue === undefined || rawValue === null || rawValue === '');
            selected.push(isEmpty ? -1 : parseInt(rawValue, 10));
        }

        const score = scoreDropdownQuestion(qData, selected);
        earnedPoints += score;

        if (!showCorrection) return;

        // Keep your correction UI logic (simplified): mark correct/incorrect per dropdown
        for (let i = 0; i < count; i++) {
            const dropdown = dropdownEls[i];
            const ddData = ddDataList[i];

            const rawValue = dropdown.dataset.selectedValue;
            const isEmpty = (rawValue === undefined || rawValue === null || rawValue === '');
            const selectedIndex = isEmpty ? -1 : parseInt(rawValue, 10);

            const correctIndex = ddData.correct_index;
            const allOptions = ddData.options || [];
            const correctOption = allOptions[correctIndex] || '';

            const isCorrect = !isEmpty && (selectedIndex === correctIndex);

            const next = dropdown.nextSibling;
            if (next && next.classList?.contains('mkq-dropdown-correction-wrapper') && next.dataset?.forId === dropdown.id) {
                next.remove();
            }

            if (isCorrect) {
                dropdown.style.display = '';
                dropdown.classList.remove('incorrect');
                dropdown.classList.add('correct');
            } else {
                let wrongAnswerHTML;
                if (isEmpty) {
                    wrongAnswerHTML = t("ui.empty_answer", "(empty)");
                } else {
                    const rawOptionText = allOptions[selectedIndex];
                    wrongAnswerHTML = rawOptionText ? convertLatexDelimiters(rawOptionText) : t("ui.empty_answer", "(empty)");
                }

                dropdown.style.display = 'none';

                const wrapper = document.createElement('span');
                wrapper.className = 'mkq-dropdown-correction-wrapper';
                wrapper.dataset.forId = dropdown.id;
                wrapper.style.cssText = `display:inline-flex;align-items:center;gap:.5em;position:relative;`;

                const wrongLabel = document.createElement('span');
                wrongLabel.className = 'mkq-gap-wrong-label';
                wrongLabel.innerHTML = wrongAnswerHTML;
                wrapper.appendChild(wrongLabel);

                const correctDropdown = document.createElement('div');
                correctDropdown.className = 'mkq-custom-dropdown correct';
                correctDropdown.style.cssText = `display:inline-block;pointer-events:none;`;

                const correctBtn = document.createElement('button');
                correctBtn.type = 'button';
                correctBtn.className = 'mkq-custom-dropdown-btn correct';
                correctBtn.style.cursor = 'default';

                const correctValueSpan = document.createElement('span');
                correctValueSpan.className = 'mkq-custom-dropdown-value';
                correctValueSpan.innerHTML = convertLatexDelimiters(correctOption);

                const arrow = document.createElement('span');
                arrow.className = 'mkq-custom-dropdown-arrow';
                arrow.textContent = '✓';
                arrow.style.color = 'green';

                correctBtn.appendChild(correctValueSpan);
                correctBtn.appendChild(arrow);
                correctDropdown.appendChild(correctBtn);
                wrapper.appendChild(correctDropdown);

                dropdown.after(wrapper);

                setTimeout(() => {
                    if (window.MathJax?.typesetPromise) {
                        MathJax.typesetPromise([wrapper]).catch(() => {});
                    }
                }, 150);
            }
        }
    });

    displayScorePoints(quizId, earnedPoints, totalPoints);
}

// ─────────────────────────────────────────────────────────────────────────────
// Dropdown interactions
// ─────────────────────────────────────────────────────────────────────────────

function toggleDropdownQuiz(button) {
    const dropdown = button.closest('.mkq-custom-dropdown');
    const options = dropdown.querySelector('.mkq-custom-dropdown-options');
    const isOpen = options.style.display === 'block';

    document.querySelectorAll('.mkq-custom-dropdown-options').forEach(opt => opt.style.display = 'none');
    options.style.display = isOpen ? 'none' : 'block';
}

function selectDropdownQuizOption(optionElement) {
    const dropdown = optionElement.closest('.mkq-custom-dropdown');
    const button = dropdown.querySelector('.mkq-custom-dropdown-btn');
    const valueSpan = button.querySelector('.mkq-custom-dropdown-value');
    const optionsDiv = dropdown.querySelector('.mkq-custom-dropdown-options');

    valueSpan.innerHTML = optionElement.innerHTML;

    dropdown.querySelectorAll('.mkq-custom-dropdown-option').forEach(opt => opt.classList.remove('selected'));
    optionElement.classList.add('selected');

    dropdown.dataset.selectedValue = optionElement.dataset.value;
    optionsDiv.style.display = 'none';

    if (window.MathJax?.typesetPromise) {
        MathJax.typesetPromise([valueSpan]).catch(() => {});
    }
}

document.addEventListener('click', (e) => {
    if (!e.target.closest('.mkq-custom-dropdown')) {
        document.querySelectorAll('.mkq-custom-dropdown-options').forEach(opt => opt.style.display = 'none');
    }
});

// ─────────────────────────────────────────────────────────────────────────────
// Gapfill correction dropdown (unchanged helpers)
/// ─────────────────────────────────────────────────────────────────────────────

function convertLatexDelimiters(text) {
    let result = text;
    result = result.replace(/\$\$(.*?)\$\$/g, '\\[$1\\]');
    result = result.replace(/\$([^\$]+)\$/g, '\\($1\\)');
    return result;
}

function createGapfillMathJaxDropdown(id, answers) {
    const container = document.createElement('div');
    container.className = 'mkq-custom-select';
    container.id = id;
    container.setAttribute('role', 'combobox');
    container.setAttribute('aria-haspopup', 'listbox');
    container.setAttribute('aria-expanded', 'false');

    const button = document.createElement('button');
    button.className = 'mkq-custom-select-btn';
    button.type = 'button';
    button.setAttribute('aria-controls', `${id}-listbox`);

    const valueSpan = document.createElement('span');
    valueSpan.className = 'mkq-custom-select-value';
    valueSpan.innerHTML = convertLatexDelimiters(answers[0]);
    button.appendChild(valueSpan);

    const arrow = document.createElement('span');
    arrow.className = 'mkq-custom-select-arrow';
    arrow.textContent = '▾';
    arrow.setAttribute('aria-hidden', 'true');

    const listbox = document.createElement('div');
    listbox.className = 'mkq-custom-select-listbox';
    listbox.id = `${id}-listbox`;
    listbox.setAttribute('role', 'listbox');
    listbox.setAttribute('tabindex', '-1');

    answers.forEach((answer, index) => {
        const option = document.createElement('div');
        option.className = 'mkq-custom-select-option';
        option.setAttribute('role', 'option');
        option.setAttribute('tabindex', index === 0 ? '0' : '-1');
        option.setAttribute('aria-selected', index === 0 ? 'true' : 'false');
        option.dataset.value = answer;
        option.innerHTML = convertLatexDelimiters(answer);

        option.addEventListener('click', () => {
            selectGapfillOption(container, button, valueSpan, listbox, option);
        });

        option.addEventListener('keydown', (e) => {
            if (e.key === 'Enter' || e.key === ' ') {
                e.preventDefault();
                selectGapfillOption(container, button, valueSpan, listbox, option);
            }
        });

        listbox.appendChild(option);
    });

    button.addEventListener('click', () => {
        toggleGapfillDropdown(container, listbox);
    });

    listbox.addEventListener('keydown', (e) => {
        handleGapfillKeyboardNav(e, container, listbox);
    });

    container.appendChild(button);
    container.appendChild(arrow);
    container.appendChild(listbox);

    document.addEventListener('click', (e) => {
        if (!container.contains(e.target)) {
            container.setAttribute('aria-expanded', 'false');
        }
    });

    setTimeout(() => {
        if (window.MathJax?.typesetPromise) {
            MathJax.typesetPromise([container]).catch(() => {});
        }
    }, 50);

    return container;
}

function toggleGapfillDropdown(container, listbox) {
    const isOpen = container.getAttribute('aria-expanded') === 'true';
    container.setAttribute('aria-expanded', !isOpen ? 'true' : 'false');
    if (!isOpen) listbox.focus();
}

function selectGapfillOption(container, button, valueSpan, listbox, option) {
    listbox.querySelectorAll('.mkq-custom-select-option').forEach(opt => opt.setAttribute('aria-selected', 'false'));
    option.setAttribute('aria-selected', 'true');

    valueSpan.innerHTML = option.innerHTML;

    if (valueSpan.innerHTML.includes('\\(') || valueSpan.innerHTML.includes('\\[')) {
        if (window.MathJax?.typesetPromise) {
            MathJax.typesetPromise([button]).catch(() => {});
        }
    }

    container.setAttribute('aria-expanded', 'false');
    button.focus();
}

function handleGapfillKeyboardNav(e, container, listbox) {
    const options = Array.from(listbox.querySelectorAll('.mkq-custom-select-option'));
    const current = document.activeElement.classList.contains('mkq-custom-select-option')
        ? document.activeElement
        : options[0];

    let idx = options.indexOf(current);

    if (e.key === 'Escape') {
        e.preventDefault();
        container.setAttribute('aria-expanded', 'false');
        container.querySelector('.mkq-custom-select-btn').focus();
    }
    if (e.key === 'ArrowDown') {
        e.preventDefault();
        options[Math.min(idx + 1, options.length - 1)].focus();
    }
    if (e.key === 'ArrowUp') {
        e.preventDefault();
        options[Math.max(idx - 1, 0)].focus();
    }
}

// ─────────────────────────────────────────────────────────────────────────────
// Display score (points)
// ─────────────────────────────────────────────────────────────────────────────

function displayScorePoints(quizId, earned, total) {
    const scoreElement = document.getElementById(`score-${quizId}`);
    if (!scoreElement) return;

    const e = Number(earned);
    const ttot = Number(total) > 0 ? Number(total) : 0;
    const pct = ttot > 0 ? (e / ttot) * 100 : 0;

    scoreElement.textContent = `${t("ui.score_label", "Score")}: ${e.toFixed(2)}/${ttot.toFixed(2)} (${pct.toFixed(1)}%)`;
    scoreElement.style.display = 'block';

    scoreElement.classList.remove('good', 'medium', 'bad');
    if (pct >= 75) scoreElement.classList.add('good');
    else if (pct >= 50) scoreElement.classList.add('medium');
    else scoreElement.classList.add('bad');
}

// ─────────────────────────────────────────────────────────────────────────────
// Crypto / storage
// ─────────────────────────────────────────────────────────────────────────────

function decryptAnswers(encryptedData) {
    try {
        const key = window.QUIZ_CONFIG.encryption_key || 'default-key-change-me';
        const encrypted = atob(encryptedData);

        const keyBytes = new TextEncoder().encode(key);
        const encryptedBytes = new Uint8Array(encrypted.split('').map(c => c.charCodeAt(0)));

        const decrypted = new Uint8Array(encryptedBytes.length);
        for (let i = 0; i < encryptedBytes.length; i++) {
            decrypted[i] = encryptedBytes[i] ^ keyBytes[i % keyBytes.length];
        }

        const jsonStr = new TextDecoder().decode(decrypted);
        return JSON.parse(jsonStr);
    } catch (e) {
        console.error(t("ui.error_decrypting", "Decrypting Error"), e);
        return null;
    }
}

function saveAnswers(quizId) {
    const quiz = document.querySelector(`[data-quiz-id="${quizId}"]`);
    if (!quiz) return;

    const answers = {};

    const checkedInputs = quiz.querySelectorAll('input[type="checkbox"]:checked, input[type="radio"]:checked');
    checkedInputs.forEach(input => { answers[input.id] = true; });

    const gapInputs = quiz.querySelectorAll('.mkq-gap-input');
    gapInputs.forEach(input => {
        if (input.value.trim() !== '') answers[input.id] = input.value;
    });

    const dropdowns = quiz.querySelectorAll('.mkq-custom-dropdown');
    dropdowns.forEach(dropdown => {
        if (dropdown.dataset.selectedValue) answers[dropdown.id] = dropdown.dataset.selectedValue;
    });

    if (Object.keys(answers).length > 0) {
        localStorage.setItem(`mkq_answers_${quizId}`, JSON.stringify(answers));
    } else {
        localStorage.removeItem(`mkq_answers_${quizId}`);
    }
}

function loadSavedAnswers() {
    const quizzes = document.querySelectorAll('.mkdocs-superquiz');

    quizzes.forEach(quiz => {
        const quizId = quiz.dataset.quizId;

        try {
            const savedAnswersJson = localStorage.getItem(`mkq_answers_${quizId}`);
            if (!savedAnswersJson) return;

            const savedAnswers = JSON.parse(savedAnswersJson);
            if (!savedAnswers || typeof savedAnswers !== 'object') {
                localStorage.removeItem(`mkq_answers_${quizId}`);
                return;
            }

            Object.keys(savedAnswers).forEach(inputId => {
                const input = document.getElementById(inputId);
                if (!input) return;

                const savedValue = savedAnswers[inputId];

                if (input.type === 'checkbox' || input.type === 'radio') {
                    if (typeof savedValue === 'boolean') input.checked = savedValue;
                } else if (input.classList.contains('mkq-gap-input')) {
                    input.value = String(savedValue);
                } else if (input.classList.contains('mkq-custom-dropdown')) {
                    input.dataset.selectedValue = savedValue;
                    const valueSpan = input.querySelector('.mkq-custom-dropdown-value');
                    const selectedOption = input.querySelector(`[data-value="${savedValue}"]`);
                    if (valueSpan && selectedOption) valueSpan.innerHTML = selectedOption.innerHTML;
                }
            });

        } catch (error) {
            localStorage.removeItem(`mkq_answers_${quizId}`);
        }
    });
}

function refreshAllQuizzes() {
    const quizzes = document.querySelectorAll('.mkdocs-superquiz');
    if (quizzes.length === 0) return;

    const pageUuid = quizzes[0]?.dataset.pageUuid;

    quizzes.forEach(quiz => {
        const quizId = quiz.dataset.quizId;
        const quizType = quiz.dataset.quizType;

        if (quizType === 'gapfill') {
            quiz.querySelectorAll('.mkq-gap-correction-wrapper').forEach(wrapper => wrapper.remove());
            quiz.querySelectorAll('.mkq-gap-input').forEach(input => {
                input.value = '';
                input.style.display = '';
                input.classList.remove('correct', 'incorrect');
            });

        } else if (quizType === 'dropdown') {
            quiz.querySelectorAll('.mkq-dropdown-correction-wrapper').forEach(wrapper => wrapper.remove());
            quiz.querySelectorAll('.mkq-custom-dropdown').forEach(dropdown => {
                dropdown.style.display = '';
                dropdown.dataset.selectedValue = '';
                const valueSpan = dropdown.querySelector('.mkq-custom-dropdown-value');
                if (valueSpan) valueSpan.textContent = '--';
                dropdown.querySelectorAll('.mkq-custom-dropdown-option').forEach(opt => opt.classList.remove('selected'));
                dropdown.classList.remove('correct', 'incorrect');
            });

        } else {
            quiz.querySelectorAll('input[type="checkbox"], input[type="radio"]').forEach(input => {
                input.checked = false;
            });
        }

        quiz.querySelectorAll('.mkq-answer').forEach(answer => {
            answer.classList.remove('correct', 'incorrect');
            const feedback = answer.querySelector('.mkq-answer-feedback');
            if (feedback) {
                feedback.style.display = 'none';
                feedback.textContent = '';
                feedback.classList.remove('correct', 'incorrect');
            }
        });

        const scoreElement = document.getElementById(`score-${quizId}`);
        if (scoreElement) {
            scoreElement.style.display = 'none';
            scoreElement.textContent = '';
            scoreElement.classList.remove('good', 'medium', 'bad');
        }

        const lockBtn = quiz.querySelector('.mkq-unlock-btn, .mkq-lock-indicator');
        if (lockBtn && !lockBtn.classList.contains('unlocked')) {
            const originalState = lockBtn.getAttribute('data-lock-state');
            if (originalState === 'locked') updateLockIcon(lockBtn, false);
        }

        localStorage.removeItem(`mkq_answers_${quizId}`);
    });

    if (pageUuid) {
        const unlocks = JSON.parse(localStorage.getItem('mkq_unlocks') || '[]');
        const filteredUnlocks = unlocks.filter(unlock => unlock.page_id !== pageUuid);
        localStorage.setItem('mkq_unlocks', JSON.stringify(filteredUnlocks));
    }

    showRefreshNotification();
}

function showRefreshNotification() {
    const notification = document.createElement('div');
    notification.textContent = `✅ ${t("ui.all_quizzes_have_been_reset", "All Quizzes have been reset")}`;
    notification.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background: #4caf50;
        color: white;
        padding: 1rem 1.5rem;
        border-radius: 6px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
        z-index: 10000;
        font-weight: 500;
        font-size: 2em;
        animation: slideIn 0.3s ease-out;
    `;
    document.body.appendChild(notification);
    setTimeout(() => {
        notification.style.opacity = '0';
        notification.style.transition = 'opacity 0.3s';
        setTimeout(() => notification.remove(), 300);
    }, 2000);
}

function addRefreshButton() {
    const pageTitle = document.querySelector('.md-content h1');
    if (!pageTitle) return;

    const quizzes = document.querySelectorAll('.mkdocs-superquiz');
    if (quizzes.length === 0) return;

    const refreshBtn = document.createElement('button');
    refreshBtn.className = 'mkq-refresh-page-btn';
    refreshBtn.title = t("ui.reset_all_quizzes", "Reset all quizzes");
    refreshBtn.innerHTML = `
        <span class="mkq-btn-icon">🔄</span>
        <span class="mkq-btn-text">${t("ui.reset_all_quizzes", "Reset all quizzes")}</span>
    `;
    refreshBtn.addEventListener('click', () => refreshAllQuizzes());

    const unlockPageBtn = document.createElement('button');
    unlockPageBtn.className = 'mkq-unlock-page-btn';
    unlockPageBtn.title = t("ui.unlock_all_page_quizzes", "Unlock all page quizzes");
    unlockPageBtn.innerHTML = `
        <span class="mkq-btn-icon">🔓</span>
        <span class="mkq-btn-text">${t("ui.unlock_all_page_quizzes", "Unlock all page quizzes")}</span>
    `;
    unlockPageBtn.addEventListener('click', () => showUnlockModal('page'));

    const buttonsContainer = document.createElement('div');
    buttonsContainer.className = 'mkq-page-buttons';
    buttonsContainer.appendChild(unlockPageBtn);
    buttonsContainer.appendChild(refreshBtn);

    pageTitle.appendChild(buttonsContainer);
}

function clearAllQuizData() {
    const keys = Object.keys(localStorage);
    const quizKeys = keys.filter(key => key.startsWith('mkq_'));
    quizKeys.forEach(key => localStorage.removeItem(key));
    setTimeout(() => location.reload(), 1000);
}
window.clearAllQuizData = clearAllQuizData;

function initQuizPlugin() {
    if (!window.QUIZ_CONFIG || !window.QUIZ_CONFIG.i18n) return;

    createUnlockModal();
    restoreUnlockedCorrections();
    loadSavedAnswers();
    addRefreshButton();
}

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initQuizPlugin);
} else {
    initQuizPlugin();
}
