document.addEventListener('DOMContentLoaded', () => { let timerInterval; let currentQuizData = []; let isCheatingDetected = false; const uploadContainer = document.getElementById('upload-container'); const quizContainer = document.getElementById('quiz-container'); const resultContainer = document.getElementById('result-container'); const loadingOverlay = document.getElementById('loading-overlay'); const fileInput = document.getElementById('file-input'); const numQuestionsInput = document.getElementById('num-questions'); const difficultyLevelInput = document.getElementById('difficulty-level'); const quizTimeInput = document.getElementById('quiz-time'); const generateQuizBtn = document.getElementById('generate-quiz-btn'); const uploadErrorDiv = document.getElementById('upload-error'); const timerElement = document.querySelector('#timer span'); const quizQuestionsDiv = document.getElementById('quiz-questions'); const submitQuizBtn = document.getElementById('submit-quiz-btn'); const scoreElement = document.getElementById('score'); const resultDetailsDiv = document.getElementById('result-details'); const retryQuizBtn = document.getElementById('retry-quiz-btn'); generateQuizBtn.addEventListener('click', handleGenerateQuiz); submitQuizBtn.addEventListener('click', () => handleSubmitQuiz(false)); retryQuizBtn.addEventListener('click', retryQuiz); function restoreQuizSession() { const savedQuiz = sessionStorage.getItem('activeQuiz'); const savedTime = sessionStorage.getItem('quizTimeLeft'); if (savedQuiz && savedTime) { console.log("Phát hiện bài làm dở, đang khôi phục..."); currentQuizData = JSON.parse(savedQuiz); const remainingMinutes = Math.ceil(parseInt(savedTime, 10) / 60); displayQuiz(remainingMinutes, parseInt(savedTime, 10)); } } restoreQuizSession(); function enterFullScreen() { const elem = document.documentElement; if (elem.requestFullscreen) { elem.requestFullscreen(); } else if (elem.webkitRequestFullscreen) { elem.webkitRequestFullscreen(); } else if (elem.msRequestFullscreen) { elem.msRequestFullscreen(); } } function exitFullScreenHandler() { if (!document.fullscreenElement && !isCheatingDetected) { isCheatingDetected = true; alert("Phát hiện thoát toàn màn hình! Bài thi sẽ được nộp tự động."); handleSubmitQuiz(true); } } function visibilityChangeHandler() { if (document.hidden && !isCheatingDetected) { isCheatingDetected = true; alert("Phát hiện chuyển tab! Bài thi sẽ được nộp tự động."); handleSubmitQuiz(true); } } async function handleGenerateQuiz() { const file = fileInput.files[0]; if (!file) { uploadErrorDiv.textContent = 'Vui lòng chọn một file.'; uploadErrorDiv.classList.remove('d-none'); return; } enterFullScreen(); uploadErrorDiv.classList.add('d-none'); loadingOverlay.classList.remove('d-none'); const formData = new FormData(); formData.append('file', file); formData.append('action', 'quiz'); formData.append('num_questions', numQuestionsInput.value); formData.append('difficulty', difficultyLevelInput.value); const timeLimit = parseInt(quizTimeInput.value, 10) || 15; try { const response = await fetch('/process', { method: 'POST', body: formData }); const data = await response.json(); if (!response.ok || data.error) throw new Error(data.error); currentQuizData = data; sessionStorage.setItem('activeQuiz', JSON.stringify(currentQuizData)); displayQuiz(timeLimit); } catch (error) { uploadErrorDiv.textContent = `Lỗi: ${error.message}`; uploadErrorDiv.classList.remove('d-none'); if (document.fullscreenElement) document.exitFullscreen(); } finally { loadingOverlay.classList.add('d-none'); } } function displayQuiz(timeLimitInMinutes, remainingSeconds = null) { quizQuestionsDiv.innerHTML = ''; currentQuizData.forEach((item, index) => { const optionsHtml = item.options.map((option, i) => `
`).join(''); const questionBlock = document.createElement('div'); questionBlock.className = 'quiz-question'; questionBlock.id = `question-container-${index}`; questionBlock.innerHTML = `

${index + 1}. ${item.question}

${optionsHtml}
`; quizQuestionsDiv.appendChild(questionBlock); }); isCheatingDetected = false; document.addEventListener('fullscreenchange', exitFullScreenHandler); document.addEventListener('webkitfullscreenchange', exitFullScreenHandler); document.addEventListener('visibilitychange', visibilityChangeHandler); uploadContainer.classList.add('d-none'); resultContainer.classList.add('d-none'); quizContainer.classList.remove('d-none'); const startTime = remainingSeconds || timeLimitInMinutes * 60; startTimer(startTime); } function startTimer(durationInSeconds) { let timer = durationInSeconds; clearInterval(timerInterval); timerInterval = setInterval(() => { sessionStorage.setItem('quizTimeLeft', timer); const minutes = Math.floor(timer / 60); let seconds = timer % 60; seconds = seconds < 10 ? '0' + seconds : seconds; timerElement.textContent = `${minutes}:${seconds}`; if (--timer < 0) { clearInterval(timerInterval); alert('Hết giờ!'); handleSubmitQuiz(true); } }, 1000); } function handleSubmitQuiz(isAutoSubmit) { if (!isAutoSubmit && isCheatingDetected) return; clearInterval(timerInterval); sessionStorage.removeItem('activeQuiz'); sessionStorage.removeItem('quizTimeLeft'); document.removeEventListener('fullscreenchange', exitFullScreenHandler); document.removeEventListener('webkitfullscreenchange', exitFullScreenHandler); document.removeEventListener('visibilitychange', visibilityChangeHandler); if (document.fullscreenElement) document.exitFullscreen(); displayResults(); } async function displayResults() { let score = 0; resultDetailsDiv.innerHTML = ''; currentQuizData.forEach((item, index) => { const questionContainer = document.getElementById(`question-container-${index}`); const resultBlock = questionContainer.cloneNode(true); const selectedOption = questionContainer.querySelector(`input[name="question-${index}"]:checked`); const isCorrect = selectedOption && selectedOption.value === item.answer; if (isCorrect) { score++; resultBlock.classList.add('correct'); } else { resultBlock.classList.add('incorrect'); } resultBlock.querySelectorAll('input[type="radio"]').forEach(radio => { radio.disabled = true; if (radio.value === item.answer) { radio.nextElementSibling.classList.add('correct-answer-text'); } }); if (!isCorrect) { const explanationDiv = document.createElement('div'); explanationDiv.className = 'explanation'; explanationDiv.innerHTML = `
Đang tải giải thích...`; resultBlock.appendChild(explanationDiv); fetchExplanation(item.question, item.answer, explanationDiv); } resultDetailsDiv.appendChild(resultBlock); }); scoreElement.innerHTML = `Điểm của bạn: ${score} / ${currentQuizData.length}`; quizContainer.classList.add('d-none'); resultContainer.classList.remove('d-none'); } async function fetchExplanation(question, correctAnswer, element) { try { const response = await fetch('/explain', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ question, correct_answer: correctAnswer }) }); const data = await response.json(); element.innerHTML = ` Giải thích: ${data.explanation || 'Không có giải thích.'}`; } catch (error) { element.textContent = 'Lỗi khi tải giải thích.'; } } function retryQuiz() { sessionStorage.removeItem('activeQuiz'); sessionStorage.removeItem('quizTimeLeft'); currentQuizData = []; fileInput.value = ''; resultContainer.classList.add('d-none'); uploadContainer.classList.remove('d-none'); } });