// Split from public/app.js v1.7.7. Loaded by public/index.html.
function activityView() {
  const filters = state.activityFilters || {};
  const search = String(filters.search || '').trim().toLowerCase();
  const role = filters.role || '';
  const activity = (state.data.activity || []).filter((item) => {
    if (role && item.userRole !== role) return false;
    if (!search) return true;
    return [item.userName, item.userRole, item.message, item.createdAt]
      .some((value) => String(value || '').toLowerCase().includes(search));
  });
  const riskyCount = activity.filter((item) => /delete|restore|cancel|backup|switch|reset/i.test(item.message || '')).length;
  return html`
    <section class="panel">
      <div class="panel-header"><div><h1>Activity Log</h1><p class="muted">Search who changed students, payments, quizzes, sessions and backups.</p></div></div>
      <div class="mini-stats">
        <div class="mini-stat"><span>Visible Logs</span><strong>${activity.length}</strong></div>
        <div class="mini-stat danger"><span>Sensitive Actions</span><strong>${riskyCount}</strong></div>
        <div class="mini-stat"><span>Total Logs</span><strong>${(state.data.activity || []).length}</strong></div>
      </div>
      <form class="report-filter" data-activity-filter>
        <input name="search" placeholder="Search user, role, activity" value="${escapeHtml(filters.search || '')}">
        <select name="role"><option value="">All Roles</option><option value="admin" ${role === 'admin' ? 'selected' : ''}>Admin</option><option value="manager" ${role === 'manager' ? 'selected' : ''}>Manager</option><option value="student" ${role === 'student' ? 'selected' : ''}>Student</option></select>
        <button class="btn ghost small" type="button" data-action="clear-activity-filter">Clear</button>
      </form>
      <div class="table-wrap">
        <table class="smart-table">
          <thead><tr><th>User</th><th>Activity</th><th>Risk</th><th>Time</th></tr></thead>
          <tbody>
            ${activity.map((item) => {
              const risky = /delete|restore|cancel|backup|switch|reset/i.test(item.message || '');
              return html`
              <tr><td>${escapeHtml(item.userName || item.userId || '-')}<br><span class="muted">${escapeHtml(item.userRole || '')}</span></td><td>${escapeHtml(item.message)}</td><td><span class="badge ${risky ? 'warning' : 'success'}">${risky ? 'sensitive' : 'normal'}</span></td><td>${formatDate(item.createdAt)}</td></tr>
            `}).join('') || '<tr><td colspan="4">No activity matches this filter.</td></tr>'}
          </tbody>
        </table>
      </div>
    </section>
    <section class="panel">
      <div class="panel-header"><h2>Email Result Log</h2></div>
      <div class="table-wrap">
        <table>
          <thead><tr><th>To</th><th>Subject</th><th>Body</th><th>Time</th></tr></thead>
          <tbody>
            ${(state.data.emailLogs || []).map((item) => html`
              <tr><td>${escapeHtml(item.to)}</td><td>${escapeHtml(item.subject)}</td><td>${escapeHtml(item.body)}</td><td>${formatDate(item.createdAt)}</td></tr>
            `).join('') || '<tr><td colspan="4">No email logs yet.</td></tr>'}
          </tbody>
        </table>
      </div>
    </section>
  `;
}

function profileView() {
  const isStudent = state.user.role === 'student';
  return html`
    <section class="panel">
      <div class="panel-header">
        <div>
          <h1>Profile</h1>
          <p class="muted">Update your name or change password.</p>
        </div>
      </div>
      <form class="form-grid" data-action="profile">
        ${isStudent && state.user.photoDataUrl ? `<img class="profile-photo" src="${escapeHtml(state.user.photoDataUrl)}" alt="">` : ''}
        <label class="field"><span>Name</span><input name="name" value="${escapeHtml(state.user.name)}"></label>
        <label class="field"><span>Mobile Number</span><input name="mobile" value="${escapeHtml(state.user.mobile || state.user.studentMobile || '')}" required></label>
        ${isStudent ? html`
          <div class="grid-2">
            <label class="field"><span>Roll</span><input value="${escapeHtml(state.user.rollNumber || '')}" readonly></label>
            <label class="field"><span>Guardian Mobile</span><input value="${escapeHtml(state.user.guardianMobile || '')}" readonly></label>
          </div>
          <label class="field"><span>College</span><input name="college" value="${escapeHtml(state.user.college || '')}"></label>
          <div class="grid-2">
            <label class="field"><span>SSC Result</span><input name="sscResult" value="${escapeHtml(state.user.sscResult || '')}"></label>
            <label class="field"><span>SSC Passing Year</span><input name="sscPassingYear" value="${escapeHtml(state.user.sscPassingYear || '')}"></label>
            <label class="field"><span>HSC Result</span><input name="hscResult" value="${escapeHtml(state.user.hscResult || '')}"></label>
            <label class="field"><span>HSC Passing Year</span><input name="hscPassingYear" value="${escapeHtml(state.user.hscPassingYear || '')}"></label>
          </div>
          <label class="field"><span>Photo</span><input name="photoFile" type="file" accept="image/png,image/jpeg" data-image-input="photoDataUrl"></label>
          <input type="hidden" name="photoDataUrl" value="${escapeHtml(state.user.photoDataUrl || '')}">
          <label class="field"><span>Status</span><input value="${escapeHtml(state.user.status || '')}" readonly></label>
        ` : ''}
        <label class="field"><span>Email</span><input name="email" type="email" value="${escapeHtml(state.user.email || '')}"></label>
        <div class="grid-2">
          <label class="field"><span>Current Password</span><input name="currentPassword" type="password"></label>
          <label class="field"><span>New Password</span><input name="newPassword" type="password"></label>
        </div>
        <button class="btn" type="submit">Update Profile</button>
      </form>
    </section>
  `;
}

function studentExams() {
  const liveExams = state.data.liveExams || state.data.assigned || [];
  const previousExams = state.data.previousExams || [];
  const section = state.studentExamSection || 'live';
  const exams = section === 'previous' ? previousExams : liveExams;
  return html`
    <section class="panel">
      <div class="panel-header">
        <div>
          <h1>My Exams</h1>
          <p class="muted">Live exams are one-time official attempts. Previous exams are practice and can be taken multiple times.</p>
        </div>
      </div>
      <div class="section-tabs">
        <button class="section-tab ${section === 'live' ? 'active' : ''}" data-action="set-student-exam-section" data-section="live">Live Exams</button>
        <button class="section-tab ${section === 'previous' ? 'active' : ''}" data-action="set-student-exam-section" data-section="previous">Previous Exams</button>
      </div>
    </section>
    <section class="panel">
      <div class="student-exam-grid">
        ${exams.map((quiz) => html`
          <article class="student-exam-card ${section === 'live' ? 'live' : ''}">
            <div>
              <span class="badge ${section === 'live' ? 'danger' : ''}">${section === 'previous' ? 'Practice' : 'Live'}</span>
              <h3>${escapeHtml(quiz.title)}</h3>
              <p class="muted">${escapeHtml(quiz.description || (section === 'previous' ? 'Practice mode' : 'Official one-time exam'))}</p>
            </div>
            <div class="student-meta-row">
              <span>${escapeHtml(String(quiz.durationMinutes || 0))} min</span>
              <span>Pass ${escapeHtml(String(quiz.passMark || 0))}%</span>
              ${quiz.category ? `<span>${escapeHtml(quiz.category)}</span>` : ''}
            </div>
            <button class="btn ${section === 'previous' ? 'secondary' : ''} small" data-action="start-exam" data-id="${quiz.id}">${section === 'previous' ? 'Practice Again' : 'Start Exam'}</button>
          </article>
        `).join('') || `<div class="empty-state">No ${section === 'previous' ? 'previous' : 'live'} exams yet.</div>`}
      </div>
    </section>
  `;
}

function youtubeEmbedUrl(url) {
  const text = String(url || '').trim();
  const match = text.match(/(?:youtu\.be\/|youtube\.com\/(?:watch\?v=|embed\/|shorts\/))([a-zA-Z0-9_-]{6,})/);
  return match ? `https://www.youtube.com/embed/${match[1]}` : text;
}

function lectureView() {
  const recordedClasses = state.data.recordedClasses || [];
  return html`
    <section class="panel">
      <div class="panel-header"><div><h1>Lecture</h1><p class="muted">Assigned recorded classes play inside this site.</p></div></div>
      <div class="student-exam-grid">
        ${recordedClasses.map((item) => html`
          <article class="student-exam-card video-watermark-card">
            <div>
              <span class="badge">Recorded</span>
              <h3>${escapeHtml(item.title)}</h3>
              <p class="muted">${escapeHtml(item.subject || '')}</p>
            </div>
            <div class="video-frame"><iframe src="${escapeHtml(youtubeEmbedUrl(item.videoUrl))}" title="${escapeHtml(item.title)}" allowfullscreen></iframe></div>
            <span class="student-watermark">${escapeHtml(state.user.name)} · ${escapeHtml(state.user.rollNumber || state.user.mobile || state.user.studentMobile || '')}</span>
          </article>
        `).join('') || '<div class="empty-state">No lectures assigned yet.</div>'}
      </div>
    </section>
  `;
}

function myPaymentView() {
  const finance = state.data.finance || {};
  const payments = state.data.payments || [];
  return html`
    <section class="panel">
      <div class="panel-header"><div><h1>My Payment</h1><p class="muted">Course fee, discount, paid amount, due and receipts.</p></div></div>
      <div class="student-home-grid">
        <article class="student-kpi-card"><span>Total Payable</span><strong>${formatMoney(finance.totalPayable || 0)}</strong></article>
        <article class="student-kpi-card success"><span>Total Paid</span><strong>${formatMoney(finance.totalPaid || 0)}</strong></article>
        <article class="student-kpi-card danger"><span>Total Due</span><strong>${formatMoney(finance.totalDue || 0)}</strong></article>
      </div>
    </section>
    <section class="panel"><div class="table-wrap"><table><thead><tr><th>Course</th><th>Fee</th><th>Discount</th><th>Paid</th><th>Due</th></tr></thead><tbody>${(finance.enrollments || []).map((item) => `<tr><td>${escapeHtml(item.courseName)}</td><td>${formatMoney(item.fee)}</td><td>${formatMoney(item.discount)}</td><td>${formatMoney(item.paid)}</td><td><strong>${formatMoney(item.due)}</strong></td></tr>`).join('') || '<tr><td colspan="5">No course fee information.</td></tr>'}</tbody></table></div></section>
    <section class="panel"><div class="panel-header"><h2>Payment History</h2></div><div class="table-wrap"><table><thead><tr><th>Receipt</th><th>Course</th><th>Amount</th><th>Date</th><th>Status</th><th>PDF</th></tr></thead><tbody>${payments.map((payment) => `<tr><td>${escapeHtml(payment.receiptNumber)}</td><td>${escapeHtml(payment.courseName)}</td><td>${formatMoney(payment.amount)}</td><td>${formatDate(payment.paidAt)}</td><td>${escapeHtml(payment.status)}</td><td><a class="btn secondary small" href="/api/payments/${payment.id}/receipt.pdf" target="_blank">PDF</a></td></tr>`).join('') || '<tr><td colspan="6">No payments yet.</td></tr>'}</tbody></table></div></section>
  `;
}

function examView() {
  const quiz = state.takingQuiz;
  return html`
    <main class="exam-page">
      <section class="exam-card">
        <div class="exam-header">
          <div>
            <h1>${escapeHtml(quiz.title)}</h1>
            <p class="muted">${escapeHtml(quiz.description || '')}</p>
          </div>
          <div class="timer" id="timer" data-seconds="${quiz.durationMinutes * 60}">${quiz.durationMinutes}:00</div>
        </div>
        <form class="form-grid" data-action="submit-exam" data-id="${quiz.id}">
          <div class="warning-box">
            <strong>Exam integrity</strong>
            <span>Tab switch/copy/paste warnings: <b id="warning-count">${state.examWarnings}</b>. ${state.examSavedAt ? `Last autosave: ${formatDate(state.examSavedAt)}` : 'Autosave will run while you answer.'}</span>
          </div>
          ${quiz.questions.map((question, index) => html`
            <div class="question-card">
              <h3>${index + 1}. ${renderMathText(question.text)}</h3>
              ${question.type === 'short'
                ? `<input name="${question.id}" placeholder="Type your answer" required>`
                : question.type === 'written'
                  ? `<textarea name="${question.id}" placeholder="Write your answer" required></textarea>`
                  : `<div class="answer-list">
                      ${question.options.map((option) => {
                        const optionText = typeof option === 'object' ? option.text : option;
                        const optionValue = typeof option === 'object' ? option.value : question.options.indexOf(option);
                        return html`
                          <label class="answer-option">
                            <input type="radio" name="${question.id}" value="${optionValue}" required>
                            <span>${renderMathText(optionText)}</span>
                          </label>
                        `;
                      }).join('')}
                    </div>`}
            </div>
          `).join('')}
          <div class="actions">
            <button class="btn secondary" type="button" data-action="cancel-exam">Cancel</button>
            <button class="btn" type="submit">Submit Exam</button>
          </div>
        </form>
      </section>
    </main>
  `;
}

function instituteView() {
  const institute = state.institute || state.data?.institute || {};
  const readonly = state.user.role !== 'admin';
  const section = state.instituteSection || 'profile';
  return html`
    <section class="panel">
      <div class="panel-header">
        <div>
          <h1>Institute</h1>
          <p class="muted">Manage institute profile and SMS gateway settings separately.</p>
        </div>
      </div>
      <div class="section-tabs">
        <button class="section-tab ${section === 'profile' ? 'active' : ''}" data-action="set-institute-section" data-section="profile">Institute Profile</button>
        <button class="section-tab ${section === 'sms' ? 'active' : ''}" data-action="set-institute-section" data-section="sms">SMS Gateway Settings</button>
      </div>
    </section>
    ${section === 'sms' ? html`
      <form class="form-grid" data-action="save-sms-settings">
        ${smsSettingsFields(institute.smsSettings || {}, readonly)}
        ${readonly ? '<p class="muted">Only Admin can edit SMS gateway settings.</p>' : '<button class="btn" type="submit">Save SMS Settings</button>'}
      </form>
      ${readonly ? '' : smsTestPanel()}
      ${smsLogsPanel()}
    ` : html`
      <section class="panel">
        <div class="panel-header"><div><h2>Institute Profile</h2><p class="muted">Manage coaching identity, contact information, branding and document headers.</p></div></div>
        <form class="form-grid" data-action="save-institute-profile">
          <div class="grid-2">
            <label class="field"><span>Institute Name *</span><input name="name" value="${escapeHtml(institute.name || '')}" required ${readonly ? 'readonly' : ''}></label>
            <label class="field"><span>Tagline</span><input name="tagline" value="${escapeHtml(institute.tagline || '')}" ${readonly ? 'readonly' : ''}></label>
          </div>
          <div class="grid-3">
            <label class="field"><span>Registration / EIIN</span><input name="registrationNo" value="${escapeHtml(institute.registrationNo || '')}" ${readonly ? 'readonly' : ''}></label>
            <label class="field"><span>Phone *</span><input name="phone" value="${escapeHtml(institute.phone || '')}" required ${readonly ? 'readonly' : ''}></label>
            <label class="field"><span>Email</span><input name="email" type="email" value="${escapeHtml(institute.email || '')}" ${readonly ? 'readonly' : ''}></label>
          </div>
          <div class="grid-2">
            <label class="field"><span>Website</span><input name="website" value="${escapeHtml(institute.website || '')}" placeholder="https://example.com" ${readonly ? 'readonly' : ''}></label>
            <label class="field"><span>Support Contact</span><input name="supportContact" value="${escapeHtml(institute.supportContact || '')}" ${readonly ? 'readonly' : ''}></label>
          </div>
          <label class="field"><span>Address</span><textarea name="address" ${readonly ? 'readonly' : ''}>${escapeHtml(institute.address || '')}</textarea></label>
          <div class="grid-2">
            <label class="field"><span>Primary Color</span><input name="primaryColor" type="color" value="${escapeHtml(institute.primaryColor || '#2563eb')}" ${readonly ? 'disabled' : ''}></label>
            <label class="field"><span>Secondary Color</span><input name="secondaryColor" type="color" value="${escapeHtml(institute.secondaryColor || '#38bdf8')}" ${readonly ? 'disabled' : ''}></label>
          </div>
          <div class="grid-2">
            <label class="field"><span>Logo</span><input name="logoFile" type="file" accept="image/png,image/jpeg,image/svg+xml" data-image-input="logoDataUrl" ${readonly ? 'disabled' : ''}></label>
            <label class="field"><span>Favicon</span><input name="faviconFile" type="file" accept="image/png,image/jpeg,image/svg+xml" data-image-input="faviconDataUrl" ${readonly ? 'disabled' : ''}></label>
          </div>
          <input type="hidden" name="logoDataUrl" value="${escapeHtml(institute.logoDataUrl || '')}">
          <input type="hidden" name="faviconDataUrl" value="${escapeHtml(institute.faviconDataUrl || '')}">
          <div class="institute-preview">
            ${institute.logoDataUrl ? `<img src="${escapeHtml(institute.logoDataUrl)}" alt="">` : '<div class="institute-logo-placeholder">Logo</div>'}
            <div>
              <strong>${escapeHtml(institute.name || 'Institute Name')}</strong>
              <span>${escapeHtml(institute.phone || '')}${institute.email ? ` · ${escapeHtml(institute.email)}` : ''}</span>
            </div>
          </div>
          <label class="field"><span>Receipt Note</span><textarea name="receiptNote" ${readonly ? 'readonly' : ''}>${escapeHtml(institute.receiptNote || '')}</textarea></label>
          <label class="field"><span>Admission Terms</span><textarea name="admissionTerms" ${readonly ? 'readonly' : ''}>${escapeHtml(institute.admissionTerms || '')}</textarea></label>
          ${readonly ? '<p class="muted">Only Admin can edit institute profile.</p>' : '<button class="btn" type="submit">Save Institute Profile</button>'}
        </form>
      </section>
    `}
  `;
}

function checked(value) {
  return value ? 'checked' : '';
}

function selectedValue(value, expected) {
  return String(value || '') === String(expected || '') ? 'selected' : '';
}

function smsSettingsFields(settings = {}, readonly = false) {
  const toggles = settings.toggles || {};
  const templates = settings.templates || {};
  const disabled = readonly ? 'disabled' : '';
  return html`
    <section class="panel">
      <div class="panel-header"><div><h2>SMS Gateway Settings</h2><p class="muted">Turn SMS features on/off and configure REVE SMS or any HTTP SMS provider.</p></div></div>
      <div class="message">REVE setup: enable SMS, select POST + JSON, set params as apikey, secretkey, callerID, toUser, messageContent, hash. Paste the REVE HTTP API URL in Request URL.</div>
      <div class="message">OTP rule: only Login OTP uses OTP format. Payment, result and notification SMS must use their own templates.</div>
      <label class="field checkbox-line"><input name="smsEnabled" type="checkbox" ${checked(settings.enabled)} ${disabled}> <span>Enable SMS System</span></label>
      <div class="grid-3">
        <label class="field"><span>Provider</span><select name="smsPreset" ${disabled}><option value="reve" ${settings.preset !== 'custom' ? 'selected' : ''}>REVE SMS</option><option value="custom" ${settings.preset === 'custom' ? 'selected' : ''}>Custom HTTP</option></select></label>
        <label class="field"><span>Provider Name</span><input name="smsProviderName" value="${escapeHtml(settings.providerName || 'REVE SMS')}" ${readonly ? 'readonly' : ''}></label>
        <label class="field"><span>Request URL</span><input name="smsRequestUrl" value="${escapeHtml(settings.requestUrl || '')}" placeholder="https://..." ${readonly ? 'readonly' : ''}></label>
      </div>
      <div class="grid-3">
        <label class="field"><span>Method</span><select name="smsMethod" ${disabled}><option value="POST" ${settings.method !== 'GET' ? 'selected' : ''}>POST</option><option value="GET" ${settings.method === 'GET' ? 'selected' : ''}>GET</option></select></label>
        <label class="field"><span>Request Type</span><select name="smsRequestType" ${disabled}><option value="json" ${settings.requestType === 'json' ? 'selected' : ''}>JSON</option><option value="form" ${settings.requestType === 'form' ? 'selected' : ''}>Form</option><option value="query" ${settings.requestType === 'query' ? 'selected' : ''}>Query</option></select></label>
        <label class="field"><span>Sender / Caller ID</span><input name="smsSenderId" value="${escapeHtml(settings.senderId || '')}" ${readonly ? 'readonly' : ''}></label>
      </div>
      <div class="grid-2">
        <label class="field"><span>API Key</span><input name="smsApiKey" value="${escapeHtml(settings.apiKey || '')}" ${readonly ? 'readonly' : ''}></label>
        <label class="field"><span>Secret Key</span><input name="smsSecretKey" type="password" value="${escapeHtml(settings.secretKey || '')}" placeholder="Leave unchanged to keep old secret" ${readonly ? 'readonly' : ''}></label>
      </div>
      <div class="grid-3">
        <label class="field"><span>API Key Param</span><input name="smsApiKeyParam" value="${escapeHtml(settings.apiKeyParam || 'apikey')}" ${readonly ? 'readonly' : ''}></label>
        <label class="field"><span>Secret Key Param</span><input name="smsSecretKeyParam" value="${escapeHtml(settings.secretKeyParam || 'secretkey')}" ${readonly ? 'readonly' : ''}></label>
        <label class="field"><span>Sender Param</span><input name="smsSenderParam" value="${escapeHtml(settings.senderParam || 'callerID')}" ${readonly ? 'readonly' : ''}></label>
      </div>
      <div class="grid-3">
        <label class="field"><span>To Param</span><input name="smsToParam" value="${escapeHtml(settings.toParam || 'toUser')}" ${readonly ? 'readonly' : ''}></label>
        <label class="field"><span>Message Param</span><input name="smsMessageParam" value="${escapeHtml(settings.messageParam || 'messageContent')}" ${readonly ? 'readonly' : ''}></label>
        <label class="field"><span>Hash Param</span><input name="smsHashParam" value="${escapeHtml(settings.hashParam || 'hash')}" ${readonly ? 'readonly' : ''}></label>
      </div>
      <div class="grid-2">
        <label class="field"><span>Hash Algorithm</span><select name="smsHashAlgorithm" ${disabled}><option value="none" ${settings.hashAlgorithm === 'none' ? 'selected' : ''}>None</option><option value="md5" ${settings.hashAlgorithm === 'md5' ? 'selected' : ''}>MD5</option><option value="sha256" ${settings.hashAlgorithm === 'sha256' ? 'selected' : ''}>SHA-256</option></select></label>
        <label class="field"><span>Hash Template</span><input name="smsHashTemplate" value="${escapeHtml(settings.hashTemplate || '')}" placeholder="{apiKey}{secretKey}{to}{message}" ${readonly ? 'readonly' : ''}></label>
      </div>
      <label class="field"><span>Extra Params</span><textarea name="smsExtraParams" rows="3" placeholder="key=value&#10;route=masking" ${readonly ? 'readonly' : ''}>${escapeHtml(settings.extraParams || '')}</textarea></label>
      <div class="grid-3">
        <label class="field checkbox-line"><input name="smsToggleLoginOtp" type="checkbox" ${checked(toggles.loginOtp)} ${disabled}> <span>Login OTP</span></label>
        <label class="field checkbox-line"><input name="smsToggleStudentPayment" type="checkbox" ${checked(toggles.studentPayment)} ${disabled}> <span>Student Payment</span></label>
        <label class="field checkbox-line"><input name="smsToggleTeacherPayment" type="checkbox" ${checked(toggles.teacherPayment)} ${disabled}> <span>Teacher Payment</span></label>
        <label class="field checkbox-line"><input name="smsToggleEmployeePayment" type="checkbox" ${checked(toggles.employeePayment)} ${disabled}> <span>Employee Payment</span></label>
        <label class="field checkbox-line"><input name="smsToggleReferencePayment" type="checkbox" ${checked(toggles.referencePayment)} ${disabled}> <span>Reference Payment</span></label>
        <label class="field checkbox-line"><input name="smsToggleResultSms" type="checkbox" ${checked(toggles.resultSms)} ${disabled}> <span>Result SMS</span></label>
      </div>
      <div class="grid-2">
        <label class="field"><span>Login OTP Template</span><textarea name="smsTemplateLoginOtp" rows="3" ${readonly ? 'readonly' : ''}>${escapeHtml(templates.loginOtp || '')}</textarea><small class="muted">OTP only. Required format: (Retina) Your Retina OTP is: {otp}. Please do not share your OTP with anyone.</small></label>
        <label class="field"><span>Student Payment Template</span><textarea name="smsTemplateStudentPayment" rows="2" ${readonly ? 'readonly' : ''}>${escapeHtml(templates.studentPayment || '')}</textarea></label>
        <label class="field"><span>Teacher Payment Template</span><textarea name="smsTemplateTeacherPayment" rows="2" ${readonly ? 'readonly' : ''}>${escapeHtml(templates.teacherPayment || '')}</textarea></label>
        <label class="field"><span>Employee Payment Template</span><textarea name="smsTemplateEmployeePayment" rows="2" ${readonly ? 'readonly' : ''}>${escapeHtml(templates.employeePayment || '')}</textarea></label>
        <label class="field"><span>Reference Payment Template</span><textarea name="smsTemplateReferencePayment" rows="2" ${readonly ? 'readonly' : ''}>${escapeHtml(templates.referencePayment || '')}</textarea></label>
        <label class="field"><span>Result SMS Template</span><textarea name="smsTemplateResultSms" rows="2" ${readonly ? 'readonly' : ''}>${escapeHtml(templates.resultSms || '')}</textarea></label>
        <label class="field"><span>Quiz Submit Result Template</span><textarea name="smsTemplateQuizResult" rows="2" ${readonly ? 'readonly' : ''}>${escapeHtml(templates.quizResult || '')}</textarea></label>
      </div>
    </section>
  `;
}

function smsTestPanel() {
  return html`
    <section class="panel">
      <div class="panel-header"><div><h2>Test SMS</h2><p class="muted">Save settings first, then send a test SMS to confirm gateway response.</p></div></div>
      <form class="form-grid" data-action="test-sms-settings">
        <div class="grid-2">
          <label class="field"><span>Test Mobile *</span><input name="testMobile" placeholder="01XXXXXXXXX" required></label>
          <label class="field"><span>Test Message</span><input name="testMessage" value="Retina SMS gateway test message."></label>
        </div>
        <button class="btn secondary" type="submit">Save & Send Test SMS</button>
      </form>
    </section>
  `;
}

function smsLogsPanel() {
  const logs = state.data?.smsLogs || [];
  return html`
    <section class="panel">
      <div class="panel-header"><h2>Recent SMS Logs</h2></div>
      <div class="table-wrap"><table><thead><tr><th>To</th><th>Type</th><th>Status</th><th>Error / Response</th><th>Time</th></tr></thead><tbody>
        ${logs.slice(0, 12).map((log) => `<tr><td>${escapeHtml(log.to || '-')}</td><td>${escapeHtml(log.type || '-')}</td><td><span class="badge ${log.status === 'sent' ? 'success' : log.status === 'failed' ? 'danger' : 'warning'}">${escapeHtml(log.status || '-')}</span></td><td>${escapeHtml(log.error || log.providerResponse || '-')}</td><td>${formatDate(log.createdAt)}</td></tr>`).join('') || '<tr><td colspan="5">No SMS logs yet.</td></tr>'}
      </tbody></table></div>
    </section>
  `;
}

function collectSmsSettings(formData) {
  return {
    enabled: formData.has('smsEnabled'),
    preset: formData.get('smsPreset'),
    providerName: formData.get('smsProviderName'),
    requestUrl: formData.get('smsRequestUrl'),
    method: formData.get('smsMethod'),
    requestType: formData.get('smsRequestType'),
    apiKey: formData.get('smsApiKey'),
    secretKey: formData.get('smsSecretKey'),
    senderId: formData.get('smsSenderId'),
    apiKeyParam: formData.get('smsApiKeyParam'),
    secretKeyParam: formData.get('smsSecretKeyParam'),
    senderParam: formData.get('smsSenderParam'),
    toParam: formData.get('smsToParam'),
    messageParam: formData.get('smsMessageParam'),
    hashParam: formData.get('smsHashParam'),
    hashAlgorithm: formData.get('smsHashAlgorithm'),
    hashTemplate: formData.get('smsHashTemplate'),
    extraParams: formData.get('smsExtraParams'),
    toggles: {
      loginOtp: formData.has('smsToggleLoginOtp'),
      studentPayment: formData.has('smsToggleStudentPayment'),
      teacherPayment: formData.has('smsToggleTeacherPayment'),
      employeePayment: formData.has('smsToggleEmployeePayment'),
      referencePayment: formData.has('smsToggleReferencePayment'),
      resultSms: formData.has('smsToggleResultSms'),
    },
    templates: {
      loginOtp: formData.get('smsTemplateLoginOtp'),
      studentPayment: formData.get('smsTemplateStudentPayment'),
      teacherPayment: formData.get('smsTemplateTeacherPayment'),
      employeePayment: formData.get('smsTemplateEmployeePayment'),
      referencePayment: formData.get('smsTemplateReferencePayment'),
      resultSms: formData.get('smsTemplateResultSms'),
      quizResult: formData.get('smsTemplateQuizResult'),
    },
  };
}

function institutePayloadFromCurrent(overrides = {}) {
  const institute = state.institute || state.data?.institute || {};
  return {
    name: institute.name || 'Student Management System',
    tagline: institute.tagline || '',
    registrationNo: institute.registrationNo || '',
    phone: institute.phone || '01796997871',
    email: institute.email || '',
    website: institute.website || '',
    address: institute.address || '',
    logoDataUrl: institute.logoDataUrl || '',
    faviconDataUrl: institute.faviconDataUrl || '',
    primaryColor: institute.primaryColor || '#2563eb',
    secondaryColor: institute.secondaryColor || '#38bdf8',
    receiptNote: institute.receiptNote || '',
    admissionTerms: institute.admissionTerms || '',
    supportContact: institute.supportContact || '',
    ...overrides,
  };
}
