// Split from public/app.js v1.7.7. Loaded by public/index.html.
function emptyQuizForm() {
  return {
    title: '',
    category: '',
    description: '',
    durationMinutes: 30,
    passMark: 50,
    negativeMarking: 0,
    retakeLimit: 0,
    scheduleStart: '',
    scheduleEnd: '',
    randomizeQuestions: false,
    randomizeAnswers: false,
    resultVisibility: 'immediate',
    certificateEnabled: true,
    status: 'published',
    assignedCourseIds: [],
    questions: [
      { type: 'mcq', text: '', options: ['', '', '', ''], correctIndex: 0, correctText: '', points: 1, explanation: '' },
    ],
  };
}

function quizzesView() {
  const quiz = state.editingQuiz;
  const courses = (state.data.courses || []).filter((course) => course.status === 'active');
  const quizSummaries = quizResultSummaries();
  const activeTab = state.quizEditorTab || 'general';
  if (quiz) return quizEditorPage(quiz, courses, activeTab);
  return html`
    <section class="panel workspace-hero">
      <div class="panel-header">
        <div>
          <h1>Quizzes</h1>
          <p class="muted">Build quizzes, manage reusable questions, assign courses, and track performance from one smart workspace.</p>
        </div>
        <div class="actions">
          <a class="btn secondary small" href="/api/export/quizzes.json" target="_blank">Export Quizzes</a>
        </div>
      </div>
      <div class="stats-grid">
        <div class="stat"><span class="muted">Total Quizzes</span><strong>${state.data.quizzes.length}</strong></div>
        <div class="stat"><span class="muted">Quiz Questions</span><strong>${state.data.quizzes.reduce((sum, item) => sum + item.questions.length, 0)}</strong></div>
        <div class="stat"><span class="muted">Submissions</span><strong>${(state.data.attempts || []).length}</strong></div>
      </div>
      <div class="workflow-grid quiz-workflow">
        <button class="workflow-card" data-action="new-quiz"><strong>Create Quiz</strong><span>General info, questions and publish settings</span></button>
        <button class="workflow-card" data-action="new-quiz"><strong>Question Builder</strong><span>MCQ, written, equation and explanation support</span></button>
        <button class="workflow-card" data-view="results"><strong>Check Results</strong><span>Submission summary, answer review and export</span></button>
      </div>
    </section>
    <section class="panel">
      <div class="panel-header">
        <div>
          <h2>Quiz List</h2>
          <p class="muted">Review status, assigned courses, question count, and quick performance signals.</p>
        </div>
        <button class="btn small" data-action="new-quiz">Add New Quiz</button>
      </div>
      ${quizListTable(quizSummaries)}
    </section>
    <section class="panel">
      <div class="panel-header">
        <div>
          <h2>Import</h2>
          <p class="muted">Bulk add quizzes when you already have structured content.</p>
        </div>
      </div>
      <form class="form-grid import-card" data-action="import-quizzes">
        <label class="field"><span>Import Quiz JSON</span><textarea name="json" placeholder='{"title":"Imported Quiz","questions":[{"type":"mcq","text":"2+2?","options":["3","4"],"correctIndex":1}]}'></textarea></label>
        <button class="btn secondary" type="submit">Import Quiz</button>
      </form>
    </section>
  `;
}

function quizEditorPage(quiz, courses, activeTab) {
  return html`
    <section class="panel quiz-editor-page">
      <div class="panel-header">
        <div>
          <h1>${quiz.id ? 'Edit Quiz' : 'Add New Quiz'}</h1>
          <p class="muted">Create exams and assign one or more courses. A course selection is required.</p>
        </div>
        <button class="btn secondary small" type="button" data-action="close-quiz-editor">Back to Quiz List</button>
      </div>
      <form class="quiz-builder" data-action="save-quiz">
        <input type="hidden" name="id" value="${escapeHtml(quiz.id || '')}">
        <div class="quiz-editor-summary">
          <div><span>Questions</span><strong>${(quiz.questions || []).length}</strong></div>
          <div><span>Duration</span><strong>${escapeHtml(String(quiz.durationMinutes || 30))}m</strong></div>
          <div><span>Pass Mark</span><strong>${escapeHtml(String(quiz.passMark || 50))}%</strong></div>
          <div><span>Status</span><strong>${escapeHtml(quiz.status || 'published')}</strong></div>
        </div>
        <div class="editor-tabs">
          ${quizEditorTabButton('general', 'General', activeTab)}
          ${quizEditorTabButton('questions', 'Questions', activeTab)}
          ${quizEditorTabButton('settings', 'Settings', activeTab)}
        </div>
        <div class="editor-tab-panel ${activeTab === 'general' ? 'active' : ''}">
          <div class="grid-2">
            <label class="field"><span>Quiz Title</span><input name="title" value="${escapeHtml(quiz.title)}" required></label>
            <label class="field"><span>Status</span>
              <select name="status">
                <option value="published" ${quiz.status !== 'draft' ? 'selected' : ''}>Published</option>
                <option value="draft" ${quiz.status === 'draft' ? 'selected' : ''}>Draft</option>
              </select>
            </label>
          </div>
          <label class="field"><span>Description</span><textarea name="description">${escapeHtml(quiz.description || '')}</textarea></label>
        </div>
        <div class="editor-tab-panel ${activeTab === 'questions' ? 'active' : ''}">
          <div id="questions">
            ${(quiz.questions || []).map((question, index) => questionEditor(question, index)).join('')}
          </div>
        </div>
        <div class="editor-tab-panel ${activeTab === 'settings' ? 'active' : ''}">
          <div class="grid-3">
            <label class="field"><span>Category</span><input name="category" value="${escapeHtml(quiz.category || '')}" placeholder="Quiz category"></label>
            <label class="field"><span>Duration Minutes</span><input name="durationMinutes" type="number" min="1" max="240" value="${quiz.durationMinutes || 30}"></label>
            <label class="field"><span>Pass Mark %</span><input name="passMark" type="number" min="0" max="100" value="${quiz.passMark || 50}"></label>
          </div>
          <div class="grid-3">
            <label class="field"><span>Negative Mark</span><input name="negativeMarking" type="number" min="0" max="10" step="0.25" value="${quiz.negativeMarking || 0}"></label>
            <label class="field"><span>Retake Limit</span><input name="retakeLimit" type="number" min="0" max="50" value="${quiz.retakeLimit || 0}"></label>
            <label class="field"><span>Result</span>
              <select name="resultVisibility">
                <option value="immediate" ${quiz.resultVisibility !== 'hidden' ? 'selected' : ''}>Show Immediately</option>
                <option value="hidden" ${quiz.resultVisibility === 'hidden' ? 'selected' : ''}>Hide from Student</option>
              </select>
            </label>
          </div>
          <div class="grid-2">
            <label class="field"><span>Schedule Start</span><input name="scheduleStart" type="datetime-local" value="${escapeHtml((quiz.scheduleStart || '').slice(0, 16))}"></label>
            <label class="field"><span>Schedule End</span><input name="scheduleEnd" type="datetime-local" value="${escapeHtml((quiz.scheduleEnd || '').slice(0, 16))}"></label>
          </div>
          <div class="actions">
            <label class="check"><input type="checkbox" name="randomizeQuestions" ${quiz.randomizeQuestions ? 'checked' : ''}> Random questions</label>
            <label class="check"><input type="checkbox" name="randomizeAnswers" ${quiz.randomizeAnswers ? 'checked' : ''}> Random answers</label>
            <label class="check"><input type="checkbox" name="certificateEnabled" ${quiz.certificateEnabled !== false ? 'checked' : ''}> Certificate</label>
          </div>
          ${courseAssignmentDropdown(quiz, courses)}
        </div>
        <div class="actions quiz-editor-actions">
          ${activeTab === 'questions' ? '<button class="btn secondary" type="button" data-action="add-question">Add Question</button>' : ''}
          <button class="btn" type="submit">Save Quiz</button>
          <button class="btn secondary" type="button" data-action="close-quiz-editor">Close</button>
        </div>
      </form>
    </section>
    ${state.pendingQuizClose ? unsavedQuizDialog() : ''}
    ${state.equationModal ? equationModalView() : ''}
  `;
}

function unsavedQuizDialog() {
  return html`
    <div class="confirm-backdrop">
      <section class="confirm-card">
        <div>
          <h2>Unsaved changes</h2>
          <p class="muted">You changed this quiz. Save your changes before going back to the quiz list?</p>
        </div>
        <div class="confirm-actions">
          <button class="btn" type="button" data-action="save-and-close-quiz">Save & Close</button>
          <button class="btn secondary" type="button" data-action="discard-and-close-quiz">Close Without Saving</button>
          <button class="btn secondary" type="button" data-action="cancel-quiz-close">Keep Editing</button>
        </div>
      </section>
    </div>
  `;
}

function quizEditorTabButton(tab, label, activeTab) {
  return html`
    <button class="editor-tab ${activeTab === tab ? 'active' : ''}" type="button" data-action="set-quiz-tab" data-tab="${tab}">
      ${label}
    </button>
  `;
}

function courseMultiSelect({
  courses,
  selectedCourseIds = [],
  inputName = 'courseIds',
  label = 'Courses',
  helpText = '',
  required = false,
  studentForm = false,
}) {
  const selectedNames = courses
    .filter((course) => selectedCourseIds.includes(course.id))
    .map((course) => course.name);
  const summary = selectedNames.length ? selectedNames.join(', ') : 'Select courses';
  return html`
    <div class="field"><span>${escapeHtml(label)}${required ? ' *' : ''}</span>
      <div class="multi-select" data-course-dropdown ${studentForm ? 'data-student-course-dropdown' : ''}>
        <button class="multi-select-trigger" type="button" data-action="toggle-course-dropdown" aria-expanded="false">
          <span data-course-summary>${escapeHtml(summary)}</span>
          <span class="multi-select-arrow" aria-hidden="true">⌄</span>
        </button>
        <div class="multi-select-menu" hidden>
          ${courses.length ? courses.map((course) => html`
            <button
              class="multi-select-option ${(selectedCourseIds).includes(course.id) ? 'selected' : ''}"
              type="button"
              data-action="toggle-course-option"
              data-course-id="${course.id}"
              data-course-name="${escapeHtml(course.name)}"
              aria-pressed="${(selectedCourseIds).includes(course.id) ? 'true' : 'false'}"
            >
              <input
                type="hidden"
                name="${escapeHtml(inputName)}"
                value="${course.id}"
                data-course-value
                ${(selectedCourseIds).includes(course.id) ? '' : 'disabled'}
              >
              <span class="multi-select-check" aria-hidden="true">✓</span>
              <span>${escapeHtml(course.name)}</span>
            </button>
          `).join('') : '<p class="muted multi-select-empty">No active courses available.</p>'}
        </div>
      </div>
      ${helpText ? `<span class="muted">${escapeHtml(helpText)}</span>` : ''}
    </div>
  `;
}

function selectedStudentCourseIds(form) {
  return [...form.querySelectorAll('[data-student-course-dropdown] input[data-course-value]:not(:disabled)')].map((input) => input.value);
}

function collectStudentCourseData(form) {
  const courseIds = selectedStudentCourseIds(form);
  return {
    courseIds,
    courseFees: courseIds.map((courseId) => ({
      courseId,
      discount: form.elements[`discount_${courseId}`]?.value || 0,
    })),
    initialPayments: courseIds.map((courseId) => ({
      courseId,
      amount: form.elements[`deposit_${courseId}`]?.value || 0,
    })),
    batchEnrollments: courseIds.map((courseId) => ({
      courseId,
      batchId: form.elements[`batch_${courseId}`]?.value || '',
    })).filter((item) => item.batchId),
  };
}

function refreshStudentCourseFinance(form) {
  const container = form?.querySelector('[data-student-course-finance]');
  if (!container) return;
  const student = form.dataset.id ? (state.data.students || []).find((item) => item.id === form.dataset.id) : null;
  container.innerHTML = studentCourseFinanceRows(selectedStudentCourseIds(form), student);
}

function updateStudentFinanceCalculation(input) {
  const row = input.closest('[data-course-finance-row]');
  if (!row) return;
  const fee = Math.max(0, Number(row.querySelector('[data-fixed-fee]')?.dataset.fixedFee || 0));
  const discountInput = row.querySelector('[data-discount-input]');
  const depositInput = row.querySelector('[data-deposit-input]');
  const discount = Math.min(fee, Math.max(0, Number(discountInput?.value || 0)));
  if (discountInput) discountInput.value = discount;
  const payable = Math.max(0, fee - discount);
  const deposit = Math.min(payable, Math.max(0, Number(depositInput?.value || 0)));
  if (depositInput) {
    depositInput.max = payable;
    depositInput.value = deposit;
  }
  const payableLabel = row.querySelector('[data-payable]');
  const dueLabel = row.querySelector('[data-finance-due]');
  if (payableLabel) payableLabel.textContent = formatMoney(payable);
  if (dueLabel && depositInput) dueLabel.textContent = formatMoney(payable - deposit);
}

function courseAssignmentDropdown(quiz, courses) {
  return courseMultiSelect({
    courses,
    selectedCourseIds: quiz.assignedCourseIds || [],
    inputName: 'assignedCourseIds',
    label: 'Assign Courses',
    helpText: 'এক বা একাধিক course নির্বাচন করুন। Course নির্বাচন না করলে quiz save হবে না।',
    required: true,
  });
}

function quizResultSummaries() {
  const attempts = state.data.attempts || [];
  return (state.data.quizzes || []).map((quiz) => {
    const quizAttempts = attempts.filter((attempt) => attempt.quizId === quiz.id);
    const passed = quizAttempts.filter((attempt) => attempt.passed).length;
    const pending = quizAttempts.filter((attempt) => attempt.reviewStatus === 'pending').length;
    const average = quizAttempts.length
      ? Math.round(quizAttempts.reduce((sum, attempt) => sum + Number(attempt.percentage || 0), 0) / quizAttempts.length)
      : 0;
    return { quiz, attempts: quizAttempts.length, passed, pending, average };
  });
}

function quizListTable(summaries) {
  if (!summaries.length) return '<p class="muted">No quizzes yet. Use Add New Quiz to create your first quiz.</p>';
  return html`
    <div class="table-wrap smart-table">
      <table>
        <thead><tr><th>Quiz</th><th>Category</th><th>Questions</th><th>Assigned</th><th>Average</th><th>Passed</th><th>Status</th><th>Actions</th></tr></thead>
        <tbody>
          ${summaries.map(({ quiz, attempts, passed, average }) => html`
            <tr>
              <td><strong>${escapeHtml(quiz.title)}</strong><br><span class="muted">${attempts} submissions</span></td>
              <td>${escapeHtml(primaryQuizCategory(quiz))}</td>
              <td>${quiz.questions.length}</td>
              <td>${(quiz.assignedCourseIds || []).length ? `${quiz.assignedCourseIds.length} course` : 'Not assigned'}</td>
              <td><strong>${average}%</strong></td>
              <td>${passed}</td>
              <td><span class="badge ${quiz.status === 'published' ? 'success' : ''}">${quiz.status}</span></td>
              <td>
                <div class="actions">
                  <button class="btn secondary small" data-action="edit-quiz" data-id="${quiz.id}">Edit</button>
                  <button class="btn secondary small" data-action="duplicate-quiz" data-id="${quiz.id}">Duplicate</button>
                  <button class="btn danger small" data-action="delete-quiz" data-id="${quiz.id}">Delete</button>
                </div>
              </td>
            </tr>
          `).join('')}
        </tbody>
      </table>
    </div>
  `;
}

function primaryQuizCategory(quiz) {
  return quiz.category || (quiz.questions || []).find((question) => question.category)?.category || '';
}

function questionEditor(question, index) {
  const options = [...(question.options || [])];
  while (options.length < 4) options.push('');
  const type = question.type || 'mcq';
  const correctIndex = type === 'true_false' && Number(question.correctIndex) > 1 ? 0 : Number(question.correctIndex || 0);
  const normalizedQuestion = { ...question, correctIndex };
  const optionFields = type === 'mcq'
    ? options.slice(0, 4).map((option, optionIndex) => questionChoiceEditor(normalizedQuestion, index, option, optionIndex)).join('')
    : type === 'true_false'
      ? ['True', 'False'].map((option, optionIndex) => questionChoiceEditor(normalizedQuestion, index, option, optionIndex, true)).join('')
      : '';
  return html`
    <div class="question-card" data-question-index="${index}">
      <div class="question-toolbar">
        <h3>Question ${index + 1}</h3>
        <div class="question-toolbar-controls">
          <label class="field"><span>Question Type</span>
            <select class="question-type-select" name="q_${index}_type" data-question-type-index="${index}">
              <option value="mcq" ${type === 'mcq' ? 'selected' : ''}>MCQ</option>
              <option value="true_false" ${type === 'true_false' ? 'selected' : ''}>True/False</option>
              <option value="short" ${type === 'short' ? 'selected' : ''}>Short Answer</option>
              <option value="written" ${type === 'written' ? 'selected' : ''}>Written</option>
            </select>
          </label>
          <label class="field mark-field"><span>Mark</span><input name="q_${index}_points" type="number" min="1" value="${question.points || 1}" placeholder="Mark"></label>
          <div class="question-action-group">
            <button class="btn secondary small equation-open-btn" type="button" data-action="open-equation-modal" data-target="q_${index}_text">fx Equation</button>
            <button class="btn secondary small question-remove-btn" type="button" data-action="remove-question" data-index="${index}" title="Remove question" aria-label="Remove question">×</button>
          </div>
        </div>
      </div>
      <label class="field"><span>Question Text</span><textarea name="q_${index}_text" placeholder="Question Text" data-math-input required>${escapeHtml(question.text || '')}</textarea></label>
      <div class="math-preview ${question.text ? '' : 'is-empty'}"><span class="preview-label">Student Preview</span><div>${renderMathText(question.text || '') || '<span class="muted">Preview will appear here.</span>'}</div></div>
      ${optionFields ? `<div class="choice-list">${optionFields}</div>` : ''}
      <div class="question-extra-grid ${type === 'written' ? 'single' : ''}">
        ${type === 'short' ? `<label class="field"><span>Short Answer Key</span><input name="q_${index}_correctText" value="${escapeHtml(question.correctText || '')}" placeholder="Short Answer Key" required></label>` : ''}
        <details class="question-extra" ${question.explanation || question.tag ? 'open' : ''}>
          <summary>Answer Explanation</summary>
          <label class="field"><span>Answer Explanation</span><textarea name="q_${index}_explanation" placeholder="Explain why the correct answer is right.">${escapeHtml(question.explanation || question.tag || '')}</textarea></label>
        </details>
      </div>
    </div>
  `;
}

function equationModalView() {
  const modal = state.equationModal || {};
  const latex = modal.latex || '\\sum_{i=1}^{\\infty}\\frac{1}{n^2}=\\frac{\\pi^2}{6}';
  const groups = [
    ['Basic', [['+', '+'], ['-', '-'], ['\\times', '×'], ['\\div', '÷'], ['=', '='], ['\\ne', '≠'], ['\\approx', '≈'], ['\\le', '≤'], ['\\ge', '≥']]],
    ['Fraction & Root', [['\\frac{}{}', 'a/b'], ['\\sqrt{}', '√x'], ['\\sqrt[]{}', 'ⁿ√x'], ['^{}', 'x²'], ['_{}', 'x₁'], ['^{}_{}', 'x²₁']]],
    ['Greek', [['\\pi', 'π'], ['\\theta', 'θ'], ['\\alpha', 'α'], ['\\beta', 'β'], ['\\gamma', 'γ'], ['\\lambda', 'λ'], ['\\mu', 'μ']]],
    ['Calculus', [['\\sum_{}^{}', 'Σ'], ['\\int_{}^{}', '∫'], ['\\lim_{}', 'lim'], ['\\infty', '∞'], ['\\partial', '∂']]],
    ['Trig & Log', [['\\sin', 'sin'], ['\\cos', 'cos'], ['\\tan', 'tan'], ['\\log', 'log'], ['\\ln', 'ln']]],
    ['Brackets', [['\\left(\\right)', '( )'], ['\\left[\\right]', '[ ]'], ['\\left\\{\\right\\}', '{ }'], ['\\left|\\right|', '| |']]],
  ];
  return html`
    <div class="modal-backdrop equation-backdrop">
      <section class="modal-card modal-wide equation-modal">
        <div class="panel-header">
          <div>
            <h2>Equation Editor</h2>
            <p class="muted">Write visually here. The preview below matches what students will see.</p>
          </div>
          <button class="btn secondary small" type="button" data-action="close-equation-modal">Close</button>
        </div>
        <div class="equation-workspace">
          <div class="equation-compose">
            <label class="field">
              <span>Visual Equation</span>
              <math-field class="equation-mathfield" data-equation-field value="${escapeHtml(latex)}" virtual-keyboard-mode="manual">${escapeHtml(latex)}</math-field>
            </label>
            <div class="equation-palette">
              ${groups.map(([name, items]) => html`
                <div class="equation-group">
                  <strong>${escapeHtml(name)}</strong>
                  <div class="equation-symbol-grid">
                    ${items.map(([value, label]) => `<button class="equation-symbol" type="button" data-action="equation-template" data-value="${escapeHtml(value)}">${escapeHtml(label)}</button>`).join('')}
                  </div>
                </div>
              `).join('')}
            </div>
          </div>
          <aside class="equation-preview-panel">
            <span class="preview-label">Student Preview</span>
            <div class="equation-live-preview" data-equation-preview>${renderMathFormula(latex, true)}</div>
            <p class="muted">Click Insert to place this equation in Question Text.</p>
          </aside>
        </div>
        <div class="actions">
          <button class="btn" type="button" data-action="apply-equation">Insert</button>
          <button class="btn secondary" type="button" data-action="close-equation-modal">Cancel</button>
        </div>
      </section>
    </div>
  `;
}

function questionChoiceEditor(question, questionIndex, option, optionIndex, fixed = false) {
  return html`
    <label class="choice-row">
      <input type="radio" name="q_${questionIndex}_correct" value="${optionIndex}" ${Number(question.correctIndex) === optionIndex ? 'checked' : ''}>
      <input name="q_${questionIndex}_option_${optionIndex}" value="${escapeHtml(option)}" placeholder="Choice ${optionIndex + 1}" ${fixed ? 'readonly' : 'required'}>
    </label>
  `;
}

function resultsTable(attempts, includeStudent) {
  if (!attempts.length) return `<p class="muted">No results yet.</p>`;
  return html`
    <div class="table-toolbar">
      <div><strong>${attempts.length}</strong><span class="muted">submissions</span></div>
    </div>
    <div class="table-wrap">
      <table class="smart-table">
        <thead>
          <tr>
            ${includeStudent ? '<th>Student</th>' : ''}
            ${includeStudent ? '<th>Quiz</th><th>Score</th><th>Status</th><th>Review</th><th>Submitted</th><th>Actions</th>' : '<th>Quiz</th><th>Status</th><th>Submitted</th><th>Mark</th><th>(-) Mark</th><th>Question</th>'}
          </tr>
        </thead>
        <tbody>
          ${attempts.map((attempt) => html`
            <tr>
              ${includeStudent ? `<td>${escapeHtml(attempt.studentName)}</td>` : ''}
              ${includeStudent ? html`
                <td>${escapeHtml(attempt.quizTitle)}</td>
                <td>${attempt.earned ?? attempt.correct}/${attempt.total} (${attempt.percentage}%)</td>
                <td><span class="badge ${attempt.passed ? 'success' : 'danger'}">${attempt.passed ? 'Passed' : 'Failed'}</span></td>
                <td><span class="badge">${attempt.reviewStatus || 'graded'}</span></td>
                <td>${formatDate(attempt.submittedAt)}</td>
                <td><div class="actions">${attempt.reviewStatus === 'pending' ? `<button class="btn secondary small" data-action="review-attempt" data-id="${attempt.id}">Review</button>` : ''}<button class="btn secondary small" data-action="view-attempt-answers" data-id="${attempt.id}">View Answers</button></div></td>
              ` : html`
                <td>${escapeHtml(attempt.quizTitle)}</td>
                <td><span class="badge ${attempt.passed ? 'success' : 'danger'}">${attempt.passed ? 'Passed' : 'Failed'}</span></td>
                <td>${formatDate(attempt.submittedAt)}</td>
                <td>${escapeHtml(String(attempt.earned ?? attempt.correct ?? 0))}/${escapeHtml(String(attempt.total ?? 0))}</td>
                <td>${escapeHtml(String(attempt.negativeMark ?? attempt.negative ?? 0))}</td>
                <td>${escapeHtml(String(attempt.questionCount ?? (attempt.answers ? Object.keys(attempt.answers || {}).length : '-')))}</td>
              `}
            </tr>
          `).join('')}
        </tbody>
      </table>
    </div>
  `;
}

function resultStats(attempts) {
  const passed = attempts.filter((attempt) => attempt.passed).length;
  const pending = attempts.filter((attempt) => attempt.reviewStatus === 'pending').length;
  const average = attempts.length
    ? Math.round(attempts.reduce((sum, attempt) => sum + Number(attempt.percentage || 0), 0) / attempts.length)
    : 0;
  return { passed, pending, average };
}

function quizResultsTable() {
  const summaries = quizResultSummaries();
  if (!summaries.length) return '<p class="muted">No quiz results yet.</p>';
  return html`
    <div class="table-toolbar">
      <div><strong>${summaries.length}</strong><span class="muted">quizzes with result summary</span></div>
      <div class="actions">
        <a class="btn secondary small export-action" data-format="Excel" href="/api/export/results.xlsx">All Results</a>
      </div>
    </div>
    <div class="table-wrap smart-table">
      <table>
        <thead>
          <tr><th>Quiz</th><th>Category</th><th>Average Score</th><th>Passed Users</th><th>Unread Results</th><th>Submissions</th><th>Status</th><th>Actions</th></tr>
        </thead>
        <tbody>
          ${summaries.map(({ quiz, attempts, passed, pending, average }) => html`
            <tr>
              <td><strong>${escapeHtml(quiz.title)}</strong><br><span class="muted">${quiz.questions.length} questions</span></td>
              <td>${escapeHtml(primaryQuizCategory(quiz))}</td>
              <td><strong>${average}%</strong></td>
              <td>${passed}</td>
              <td><strong>${pending}</strong></td>
              <td>${attempts}</td>
              <td><span class="badge ${quiz.status === 'published' ? 'success' : ''}">${quiz.status}</span></td>
              <td>
                <div class="actions result-actions">
                  <button class="btn secondary small" data-action="view-quiz-submissions" data-id="${quiz.id}">See Result</button>
                  <a class="btn secondary small" href="/api/export/results.xlsx?quizId=${encodeURIComponent(quiz.id)}">Export Result</a>
                </div>
              </td>
            </tr>
          `).join('')}
        </tbody>
      </table>
    </div>
  `;
}

function quizSubmissionList(attempts) {
  if (!attempts.length) return '<div class="nested-submissions empty">No submissions for this quiz yet.</div>';
  return html`
    <div class="nested-submissions">
      <div class="nested-submissions-head">
        <span>Student</span>
        <span>Score</span>
        <span>Status</span>
        <span>Review</span>
        <span>Submitted</span>
        <span>Actions</span>
      </div>
      ${attempts.map((attempt) => html`
        <div class="nested-submission-row">
          <strong>${escapeHtml(attempt.studentName)}</strong>
          <span>${attempt.earned ?? attempt.correct}/${attempt.total} (${attempt.percentage}%)</span>
          <span><span class="badge ${attempt.passed ? 'success' : 'danger'}">${attempt.passed ? 'Passed' : 'Failed'}</span></span>
          <span><span class="badge">${attempt.reviewStatus || 'graded'}</span></span>
          <span>${formatDate(attempt.submittedAt)}</span>
          <span>
            <div class="actions">
              ${attempt.reviewStatus === 'pending' ? `<button class="btn secondary small" data-action="review-attempt" data-id="${attempt.id}">Review</button>` : ''}
              <button class="btn secondary small" data-action="view-attempt-answers" data-id="${attempt.id}">View Answers</button>
            </div>
          </span>
        </div>
      `).join('')}
    </div>
  `;
}

function quizSubmissionHistoryView() {
  const quiz = (state.data.quizzes || []).find((item) => item.id === state.viewingQuizResultsId);
  if (!quiz) {
    return html`
      <section class="panel">
        <div class="panel-header">
          <h1>Submission History</h1>
          <button class="btn secondary small" data-action="back-to-results">Back to Results</button>
        </div>
        <p class="muted">Quiz result not found.</p>
      </section>
    `;
  }
  const attempts = [...(state.data.attempts || [])]
    .filter((attempt) => attempt.quizId === quiz.id)
    .reverse();
  const stats = resultStats(attempts);
  return html`
    <section class="panel">
      <div class="panel-header">
        <div>
          <h1>Submission History</h1>
          <p class="muted">${escapeHtml(quiz.title)} · ${escapeHtml(primaryQuizCategory(quiz))}</p>
        </div>
        <div class="actions">
          <a class="btn secondary small" href="/api/export/results.xlsx?quizId=${encodeURIComponent(quiz.id)}">Export Excel</a>
          <button class="btn secondary small" data-action="back-to-results">Back to Results</button>
        </div>
      </div>
      <div class="stats-grid">
        <div class="stat"><span class="muted">Submissions</span><strong>${attempts.length}</strong></div>
        <div class="stat"><span class="muted">Average Score</span><strong>${stats.average}%</strong></div>
        <div class="stat"><span class="muted">Passed Users</span><strong>${stats.passed}</strong></div>
      </div>
    </section>
    <section class="panel">
      <div class="panel-header">
        <h2>Examinee Details</h2>
      </div>
      ${quizSubmissionDetails(attempts)}
    </section>
  `;
}

function quizSubmissionDetails(attempts) {
  if (!attempts.length) return '<p class="muted">No submissions for this quiz yet.</p>';
  return html`
    <div class="submission-detail-list">
      ${attempts.map((attempt) => html`
        <article class="submission-detail-card">
          <div class="submission-detail-header">
            <div>
              <h3>${escapeHtml(attempt.studentName)}</h3>
              <div class="submission-summary">
                <span><small>Submitted</small><strong>${formatDate(attempt.submittedAt)}</strong></span>
                <span><small>Score</small><strong>${attempt.earned ?? attempt.correct}/${attempt.total} (${attempt.percentage}%)</strong></span>
                <span><small>Result</small><strong class="${attempt.passed ? 'summary-success' : 'summary-danger'}">${attempt.passed ? 'Passed' : 'Failed'}</strong></span>
                <span><small>Review</small><strong>${attempt.reviewStatus || 'graded'}</strong></span>
              </div>
            </div>
            <div class="actions">
              ${attempt.reviewStatus === 'pending' ? `<button class="btn secondary small" data-action="review-attempt" data-id="${attempt.id}">Review</button>` : ''}
              <button class="btn secondary small" data-action="view-attempt-answers" data-id="${attempt.id}">Details</button>
            </div>
          </div>
        </article>
      `).join('')}
    </div>
  `;
}

function resultReviewView() {
  const attempts = state.data.attempts || [];
  const attempt = attempts.find((item) => item.id === state.reviewingAttemptId);
  const returnToQuiz = Boolean(state.viewingQuizResultsId);
  const backButton = returnToQuiz
    ? '<button class="btn secondary small" data-action="back-to-quiz-submissions">Back to Examinees</button>'
    : '<button class="btn secondary small" data-action="back-to-results">Back to Results</button>';
  if (!attempt) {
    return html`
      <section class="panel">
        <div class="panel-header">
          <h1>Result Details</h1>
          ${backButton}
        </div>
        <p class="muted">Result not found.</p>
      </section>
    `;
  }
  return html`
    <section class="panel">
      <div class="panel-header">
        <div>
          <h1>Result Details</h1>
          <p class="muted">${escapeHtml(attempt.studentName)} · ${escapeHtml(attempt.quizTitle)} · ${formatDate(attempt.submittedAt)}</p>
        </div>
        ${backButton}
      </div>
      <div class="stats-grid">
        <div class="stat"><span class="muted">Score</span><strong>${attempt.earned ?? attempt.correct}/${attempt.total}</strong></div>
        <div class="stat"><span class="muted">Percentage</span><strong>${attempt.percentage}%</strong></div>
        <div class="stat"><span class="muted">Status</span><strong>${attempt.passed ? 'Passed' : 'Failed'}</strong></div>
      </div>
    </section>
    <section class="panel">
      <div class="panel-header">
        <h2>Answer Details</h2>
      </div>
      ${attemptAnswerDetails(attempt)}
    </section>
  `;
}

function attemptAnswerDetails(attempt) {
  const details = attempt.details || [];
  if (!details.length || attempt.reviewStatus === 'hidden') {
    return '<p class="muted">Answer details are not available for this result.</p>';
  }
  return html`
    <div class="answer-review">
      ${details.map((detail, index) => {
        const selected = answerText(detail, detail.selectedIndex, detail.answer);
        const correct = detail.type === 'written'
                ? 'Manual review required'
          : detail.type === 'short'
            ? detail.correctText || '-'
            : answerText(detail, detail.correctIndex, '');
        return html`
          <div class="answer-review-card ${detail.isCorrect ? 'correct' : 'wrong'}">
            <div class="answer-review-title">
              <strong>${index + 1}. ${renderMathText(detail.questionText || `Question ${index + 1}`)}</strong>
              <span class="badge ${detail.isCorrect ? 'success' : detail.type === 'written' ? '' : 'danger'}">
                ${detail.type === 'written' ? 'Manual' : detail.isCorrect ? 'Correct' : 'Wrong'}
              </span>
            </div>
            <div class="grid-2">
              <p><span class="muted">Your answer</span><br><strong>${renderMathText(selected || '-')}</strong></p>
              <p><span class="muted">Correct answer</span><br><strong>${renderMathText(correct || '-')}</strong></p>
            </div>
            ${detail.explanation ? `<div class="answer-explanation"><span class="muted">Answer Explanation</span><p>${escapeHtml(detail.explanation)}</p></div>` : ''}
          </div>
        `;
      }).join('')}
    </div>
  `;
}

function answerText(detail, index, fallback) {
  const options = detail.options || [];
  if (index !== null && index !== undefined && index !== '' && Number.isInteger(Number(index)) && options[Number(index)] !== undefined) {
    return options[Number(index)];
  }
  return fallback || '';
}

