// Split from public/app.js v1.7.7. Loaded by public/index.html.
function studentOverview() {
  const liveExams = state.data.liveExams || state.data.assigned || [];
  const previousExams = state.data.previousExams || [];
  const notifications = state.data.notifications || [];
  const finance = state.data.finance || {};
  const progress = state.data.progressReport || {};
  const recordedClasses = state.data.recordedClasses || [];
  const nextExam = liveExams[0];
  const dueAmount = Number(finance.totalDue || 0);
  return html`
    <section class="panel student-home-hero">
      <div class="student-hero-content">
        <div>
          <span class="student-eyebrow">Welcome back</span>
          <h1>${escapeHtml(state.user.name || 'Student')}</h1>
          <p class="muted">Live exams, payments, progress and lectures in one place.</p>
        </div>
        <div class="student-profile-chip">
          <strong>${escapeHtml(state.user.rollNumber || state.user.mobile || state.user.studentMobile || '-')}</strong>
          <span>${escapeHtml(state.data.activeSession?.name || '')}</span>
        </div>
      </div>
      <div class="student-home-grid">
        <article class="student-kpi-card primary">
          <span>Live Exams</span>
          <strong>${liveExams.length}</strong>
          <button class="btn small" data-view="exams">Go to Exams</button>
        </article>
        <article class="student-kpi-card">
          <span>Previous Exams</span>
          <strong>${previousExams.length}</strong>
          <button class="btn secondary small" data-view="exams">Practice</button>
        </article>
        <article class="student-kpi-card ${dueAmount > 0 ? 'danger' : 'success'}">
          <span>Payment Due</span>
          <strong>${formatMoney(finance.totalDue || 0)}</strong>
          <button class="btn secondary small" data-view="payments">View Payment</button>
        </article>
        <article class="student-kpi-card">
          <span>Average Mark</span>
          <strong>${escapeHtml(String(progress.summary?.average || 0))}</strong>
          <button class="btn secondary small" data-view="results">Progress</button>
        </article>
      </div>
    </section>
    <section class="student-dashboard-grid">
      <article class="panel student-focus-card">
        <div class="panel-header">
          <div>
            <h2>${nextExam ? 'Next Live Exam' : 'No Live Exam'}</h2>
            <p class="muted">${nextExam ? 'Ready when the exam window is open.' : 'New exams will appear here.'}</p>
          </div>
        </div>
        ${nextExam ? html`
          <h3>${escapeHtml(nextExam.title)}</h3>
          <p class="muted">${escapeHtml(nextExam.description || 'Official one-time exam')}</p>
          <div class="student-meta-row">
            <span>${escapeHtml(String(nextExam.durationMinutes || 0))} min</span>
            <span>Pass ${escapeHtml(String(nextExam.passMark || 0))}%</span>
          </div>
          <button class="btn" data-action="start-exam" data-id="${nextExam.id}">Start Exam</button>
        ` : html`<button class="btn secondary" data-view="exams">Check Exam List</button>`}
      </article>
      <article class="panel student-focus-card">
        <div class="panel-header">
          <div>
            <h2>Recorded Classes</h2>
            <p class="muted">Assigned lectures with protected player.</p>
          </div>
        </div>
        <strong class="student-big-number">${recordedClasses.length}</strong>
        <button class="btn secondary" data-view="lecture">Open Lectures</button>
      </article>
    </section>
    <section class="panel">
      <div class="panel-header"><div><h2>Messages / Notifications</h2><p class="muted">Latest notices from your institute.</p></div></div>
      <div class="notification-list">
        ${notifications.slice(0, 5).map((item) => html`
          <article class="notification-card">
            <div><strong>${escapeHtml(item.title)}</strong><span class="muted">${formatDate(item.createdAt)}</span></div>
            <p>${escapeHtml(item.body)}</p>
          </article>
        `).join('') || '<p class="muted">No notifications yet.</p>'}
      </div>
    </section>
  `;
}

function studentsView() {
  const students = state.data.students;
  const courses = state.data.courses || [];
  const section = state.studentSection || 'add';
  return html`
    <section class="panel">
      <div class="panel-header">
        <div>
          <h1>Students</h1>
          <p class="muted">Create student accounts, manage profiles, fees, details, printing and access.</p>
        </div>
      </div>
      <div class="section-tabs">
        <button class="section-tab ${section === 'add' ? 'active' : ''}" data-action="set-student-section" data-section="add">Add New Student</button>
        <button class="section-tab ${section === 'list' ? 'active' : ''}" data-action="set-student-section" data-section="list">Student List</button>
      </div>
    </section>
    ${section === 'add' ? studentForm(courses) : studentListView(students)}
    ${section === 'add' ? html`<section class="panel">
      <div class="panel-header">
        <div>
          <h2>CSV Import</h2>
          <p class="muted">One student per line: name,roll,student mobile,guardian mobile,college,course,email,password</p>
        </div>
      </div>
      <form class="form-grid" data-action="import-students">
        <textarea name="csv" placeholder="Rahim Uddin,REG-101,01711111111,01811111111,Rajshahi College,Medical Admission,rahim@example.com,pass123&#10;Karim Uddin,REG-102,01722222222,01822222222,City College,Academic,karim@example.com,pass123"></textarea>
        <button class="btn" type="submit">Import Students</button>
      </form>
    </section>` : ''}
    ${state.editingStudentId ? studentEditDialog() : ''}
    ${state.viewingStudentId ? studentDetailsDialog() : ''}
  `;
}

function studentForm(courses) {
  const draft = state.studentFormDraft || {};
  const sessionName = state.data?.activeSession?.name || '';
  return html`
    <section class="panel">
      <div class="panel-header"><div><h2>New Student Form</h2><p class="muted">Required: name, roll/registration number, and student mobile.</p></div></div>
      <form class="form-grid" data-action="add-student" data-student-form>
        <div class="form-section">
          <div class="form-section-title"><strong>Basic Info</strong><span>Name, roll and contact details</span></div>
          <div class="grid-3">
            <label class="field"><span>Name *</span><input name="name" placeholder="Student name" value="${escapeHtml(draft.name || '')}" required></label>
            <label class="field"><span>Roll / Reg. No.</span><input name="rollNumber" placeholder="Auto generated if blank" value="${escapeHtml(draft.rollNumber || '')}"></label>
            <label class="field"><span>Student Mobile *</span><input name="studentMobile" placeholder="01XXXXXXXXX" value="${escapeHtml(draft.studentMobile || '')}" required></label>
          </div>
          <div class="grid-2">
            <label class="field"><span>Guardian Mobile</span><input name="guardianMobile" placeholder="01XXXXXXXXX" value="${escapeHtml(draft.guardianMobile || '')}"></label>
            <label class="field"><span>College</span><input name="college" placeholder="College name" value="${escapeHtml(draft.college || '')}"></label>
          </div>
        </div>
        <div class="form-section">
          <div class="form-section-title"><strong>Course & Batch</strong><span>Course selection controls quiz access</span></div>
          <div class="grid-3">
            ${courseMultiSelect({
              courses: courses.filter((course) => course.status === 'active'),
              selectedCourseIds: draft.courseIds || [],
              inputName: 'courseIds',
              label: 'Courses',
              helpText: 'Select one or more courses.',
              studentForm: true,
            })}
            <label class="field"><span>Admission Date</span><input name="admissionDate" type="date"></label>
            <label class="field"><span>Coaching Session</span><input value="${escapeHtml(sessionName)}" readonly></label>
          </div>
        </div>
        <div class="form-section">
          <div class="form-section-title"><strong>Fee Setup</strong><span>Auto-calculated from selected courses</span></div>
          <div class="student-course-finance" data-student-course-finance>
            ${studentCourseFinanceRows(draft.courseIds || [], null)}
          </div>
        </div>
        <div class="form-section">
          <div class="form-section-title"><strong>Academic Info</strong><span>Optional education records and photo</span></div>
          <div class="grid-3">
            <label class="field"><span>SSC Result</span><input name="sscResult" value="${escapeHtml(draft.sscResult || '')}" placeholder="GPA / Grade"></label>
            <label class="field"><span>SSC Passing Year</span><input name="sscPassingYear" value="${escapeHtml(draft.sscPassingYear || '')}" placeholder="2024"></label>
            <label class="field"><span>Photo</span><input name="photoFile" type="file" accept="image/png,image/jpeg" data-image-input="photoDataUrl"></label>
          </div>
          <div class="grid-2">
            <label class="field"><span>HSC Result</span><input name="hscResult" value="${escapeHtml(draft.hscResult || '')}" placeholder="GPA / Grade"></label>
            <label class="field"><span>HSC Passing Year</span><input name="hscPassingYear" value="${escapeHtml(draft.hscPassingYear || '')}" placeholder="2026"></label>
          </div>
          <input type="hidden" name="photoDataUrl" value="${escapeHtml(draft.photoDataUrl || '')}">
        </div>
        <div class="form-section">
          <div class="form-section-title"><strong>Login & Reference</strong><span>Password, email and admission reference</span></div>
          <div class="grid-2">
            <label class="field"><span>Email</span><input name="email" type="email" placeholder="student@example.com" value="${escapeHtml(draft.email || '')}"></label>
            <label class="field"><span>Password</span><input name="password" placeholder="Default: student mobile"></label>
          </div>
          <div class="grid-3">
            <label class="field"><span>Referred By</span><input name="referenceName" placeholder="Referrer name"></label>
            <label class="field"><span>Referrer Mobile</span><input name="referenceMobile" placeholder="01XXXXXXXXX"></label>
            <label class="field"><span>Commission</span><input name="referenceCommissionAmount" type="number" min="0" step="0.01" placeholder="0"></label>
          </div>
          <label class="field"><span>Reference Type</span><select name="referenceType"><option value="">No reference</option><option>Student</option><option>Teacher</option><option>Employee</option><option>Other</option></select></label>
        </div>
        <button class="btn" type="submit">Add Student</button>
      </form>
    </section>
  `;
}

function studentListView(students) {
  const courses = state.data.courses || [];
  const batches = state.data.batches || [];
  const filters = currentReportFilters('students');
  const search = String(state.studentListSearch || '').trim().toLowerCase();
  const filteredStudents = students.filter((student) => {
    const fee = studentFinanceStatus(student);
    const matchesSearch = !search || [student.name, student.rollNumber, student.studentMobile, student.guardianMobile, student.college, student.email]
      .some((value) => String(value || '').toLowerCase().includes(search));
    if (!matchesSearch) return false;
    if (filters.courseId && !(student.courseIds || []).includes(filters.courseId)) return false;
    if (filters.batchId && !(student.batchEnrollments || []).some((item) => item.batchId === filters.batchId)) return false;
    if (filters.due && fee !== filters.due) return false;
    if (filters.status && student.status !== filters.status) return false;
    return true;
  });
  const activeStudents = students.filter((student) => student.status === 'active').length;
  const dueStudents = students.filter((student) => Number(student.finance?.totalDue || 0) > 0).length;
  const paidStudents = students.filter((student) => Number(student.finance?.totalDue || 0) <= 0 && Number(student.finance?.totalPayable || student.finance?.totalFee || 0) > 0).length;
  const visibleDue = filteredStudents.reduce((sum, student) => sum + Number(student.finance?.totalDue || 0), 0);
  return html`
    <section class="panel">
      <div class="panel-header">
        <div><h2>Student List</h2><p class="muted">Search, filter, edit, view details and print student records.</p></div>
        <input class="compact-search" data-student-search placeholder="Search name, roll or mobile" value="${escapeHtml(state.studentListSearch || '')}">
      </div>
      <div class="mini-stats">
        <div class="mini-stat"><span>Total Students</span><strong>${students.length}</strong></div>
        <div class="mini-stat"><span>Active</span><strong>${activeStudents}</strong></div>
        <div class="mini-stat danger"><span>Due Students</span><strong>${dueStudents}</strong></div>
        <div class="mini-stat success"><span>Paid Students</span><strong>${paidStudents}</strong></div>
      </div>
      <form class="report-filter student-filter" data-export-form="students">
        <div class="filter-fields">
          <select name="courseId"><option value="">All Courses</option>${courses.map((course) => `<option value="${course.id}" ${filters.courseId === course.id ? 'selected' : ''}>${escapeHtml(course.name)}</option>`).join('')}</select>
          <select name="batchId"><option value="">All Batches</option>${batches.map((batch) => `<option value="${batch.id}" ${filters.batchId === batch.id ? 'selected' : ''}>${escapeHtml(batch.name)}</option>`).join('')}</select>
          <select name="due"><option value="">All Fee Status</option><option value="due" ${filters.due === 'due' ? 'selected' : ''}>Due</option><option value="partial" ${filters.due === 'partial' ? 'selected' : ''}>Partial</option><option value="paid" ${filters.due === 'paid' ? 'selected' : ''}>Paid</option></select>
          <select name="status"><option value="">All Account Status</option><option value="active" ${filters.status === 'active' ? 'selected' : ''}>Active</option><option value="inactive" ${filters.status === 'inactive' ? 'selected' : ''}>Inactive</option></select>
        </div>
        <div class="filter-actions">
          <button class="btn secondary small" type="button" data-action="download-report" data-report="students" data-format="csv">CSV</button>
          <button class="btn secondary small" type="button" data-action="download-report" data-report="students" data-format="pdf">PDF</button>
        </div>
      </form>
      <div class="table-toolbar">
        <div>
          <strong>${filteredStudents.length}</strong>
          <span class="muted">shown from ${students.length} students</span>
          ${visibleDue > 0 ? `<span class="toolbar-chip danger">Visible due ${formatMoney(visibleDue)}</span>` : '<span class="toolbar-chip success">No visible due</span>'}
          ${reportFilterSummary(filters, { courseId: 'Course', batchId: 'Batch', due: 'Fee', status: 'Status' })}
        </div>
        <div class="actions">
          <button class="btn ghost small" type="button" data-action="clear-student-filters">Clear Filters</button>
        </div>
      </div>
      <div class="table-wrap">
        <table class="smart-table student-table" data-student-table>
          <thead><tr><th>Student</th><th>Course / Batch</th><th>Fee</th><th>Status</th><th>Actions</th></tr></thead>
          <tbody>
            ${filteredStudents.map((student) => {
              const totalDue = Number(student.finance?.totalDue || 0);
              const totalPaid = Number(student.finance?.totalPaid || 0);
              return html`
              <tr data-student-row data-search="${escapeHtml(`${student.name} ${student.rollNumber} ${student.studentMobile} ${student.email}`.toLowerCase())}">
                <td>
                  <div class="student-cell">
                    <strong>${escapeHtml(student.name)}</strong>
                    <span>${escapeHtml(student.rollNumber || '-')} Â· ${escapeHtml(student.studentMobile || '-')}</span>
                    <small>${escapeHtml(student.email || 'No email')}</small>
                  </div>
                </td>
                <td>
                  <div class="student-cell">
                    <strong>${escapeHtml(courseNames(student.courseIds) || '-')}</strong>
                    <span>${escapeHtml(studentBatchNames(student) || 'No batch')}</span>
                    <small>${escapeHtml(student.college || 'No college')}</small>
                  </div>
                </td>
                <td>
                  <div class="fee-status-block">
                    ${studentFeeStatus(student)}
                    <span>Paid ${formatMoney(totalPaid)}</span>
                    <span>Due ${formatMoney(totalDue)}</span>
                  </div>
                </td>
                <td><span class="badge ${student.status === 'active' ? 'success' : 'danger'}">${student.status}</span></td>
                <td>
                  <div class="actions">
                    <button class="btn secondary small" data-action="view-student" data-id="${student.id}">Details</button>
                    <button class="btn secondary small" data-action="edit-student" data-id="${student.id}">Edit</button>
                    <button class="btn ghost small" data-action="print-student" data-id="${student.id}">Print</button>
                  </div>
                </td>
              </tr>
            `}).join('') || '<tr><td colspan="5"><div class="empty-state"><strong>No students match this filter.</strong><span>Try clearing filters or changing the search text.</span></div></td></tr>'}
          </tbody>
        </table>
      </div>
    </section>
  `;
}

function studentFinanceStatus(student) {
  const totalDue = Number(student.finance?.totalDue || 0);
  const totalPaid = Number(student.finance?.totalPaid || 0);
  const totalPayable = Number(student.finance?.totalPayable || student.finance?.totalFee || 0);
  if (totalDue > 0 && totalPaid > 0) return 'partial';
  if (totalDue > 0) return 'due';
  if (totalPayable > 0) return 'paid';
  return '';
}

function studentEditDialog() {
  const student = (state.data.students || []).find((item) => item.id === state.editingStudentId);
  const courses = (state.data.courses || []).filter((course) => course.status === 'active');
  if (!student) return '';
  return html`
    <div class="modal-backdrop">
      <section class="modal-card modal-wide">
        <div class="panel-header student-profile-header">
          <div><h2>Edit Student</h2><p class="muted">${escapeHtml(student.rollNumber)}</p></div>
          <button class="btn secondary small" type="button" data-action="close-student-edit">Close</button>
        </div>
        <form class="form-grid" data-action="edit-student" data-id="${student.id}" data-student-form>
          <div class="grid-3">
            <label class="field"><span>Name *</span><input name="name" value="${escapeHtml(student.name)}" required></label>
            <label class="field"><span>Roll / Reg. *</span><input name="rollNumber" value="${escapeHtml(student.rollNumber)}" required></label>
            <label class="field"><span>Student Mobile *</span><input name="studentMobile" value="${escapeHtml(student.studentMobile)}" required></label>
          </div>
          <div class="grid-3">
            <label class="field"><span>Guardian Mobile</span><input name="guardianMobile" value="${escapeHtml(student.guardianMobile)}"></label>
            <label class="field"><span>College</span><input name="college" value="${escapeHtml(student.college)}"></label>
            ${courseMultiSelect({ courses, selectedCourseIds: student.courseIds || [], inputName: 'courseIds', label: 'Courses', studentForm: true })}
          </div>
          <div class="grid-2">
            <label class="field"><span>SSC Result</span><input name="sscResult" value="${escapeHtml(student.sscResult || '')}"></label>
            <label class="field"><span>SSC Passing Year</span><input name="sscPassingYear" value="${escapeHtml(student.sscPassingYear || '')}"></label>
            <label class="field"><span>HSC Result</span><input name="hscResult" value="${escapeHtml(student.hscResult || '')}"></label>
            <label class="field"><span>HSC Passing Year</span><input name="hscPassingYear" value="${escapeHtml(student.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(student.photoDataUrl || '')}">
          <div class="student-course-finance" data-student-course-finance>
            ${studentCourseFinanceRows(student.courseIds || [], student)}
          </div>
          <div class="grid-2">
            <label class="field"><span>Admission Date</span><input name="admissionDate" type="date" value="${escapeHtml(student.admissionDate)}"></label>
            <label class="field"><span>Coaching Session</span><input value="${escapeHtml(student.academicYear || state.data?.activeSession?.name || '')}" readonly></label>
          </div>
          <label class="field"><span>Email</span><input name="email" type="email" value="${escapeHtml(student.email)}"></label>
          <button class="btn" type="submit">Save Student</button>
        </form>
      </section>
    </div>
  `;
}

function studentDetailsDialog() {
  const student = (state.data.students || []).find((item) => item.id === state.viewingStudentId);
  if (!student) return '';
  const finance = student.finance || {};
  const dueTone = Number(finance.totalDue || 0) > 0 ? 'danger' : 'success';
  return html`
    <div class="modal-backdrop">
      <section class="modal-card modal-wide">
        <div class="panel-header student-profile-header">
          <div class="student-profile-title">
            <div class="student-photo-preview">${student.photoDataUrl ? `<img src="${escapeHtml(student.photoDataUrl)}" alt="">` : escapeHtml(String(student.name || 'S').slice(0, 1).toUpperCase())}</div>
            <div><h2>Student Details</h2><p class="muted">${escapeHtml(student.name)} · ${escapeHtml(student.rollNumber || '-')} · ${escapeHtml(student.studentMobile || '-')}</p></div>
          </div>
          <div class="actions">
            <button class="btn secondary small" type="button" data-action="print-student" data-id="${student.id}">Print</button>
            <a class="btn secondary small" href="/api/students/${student.id}/profile.pdf" target="_blank">PDF</a>
            <button class="btn secondary small" type="button" data-action="close-student-details">Close</button>
          </div>
        </div>
        <div class="profile-sections">
          <section class="profile-section">
            <h3>Basic Info</h3>
            <div class="detail-grid">
              ${studentDetailItem('Name', student.name)}
              ${studentDetailItem('Roll / Registration', student.rollNumber)}
              ${studentDetailItem('Student Mobile', student.studentMobile)}
              ${studentDetailItem('Guardian Mobile', student.guardianMobile || '-')}
              ${studentDetailItem('Email', student.email || '-')}
              ${studentDetailItem('Status', student.status)}
            </div>
          </section>
          <section class="profile-section">
            <h3>Academic Info</h3>
            <div class="detail-grid">
              ${studentDetailItem('College', student.college || '-')}
              ${studentDetailItem('Courses', courseNames(student.courseIds) || '-')}
              ${studentDetailItem('Batch', studentBatchNames(student) || '-')}
              ${studentDetailItem('Admission Date', student.admissionDate || '-')}
              ${studentDetailItem('Academic Year', student.academicYear || '-')}
              ${studentDetailItem('SSC Result', student.sscResult || '-')}
              ${studentDetailItem('SSC Passing Year', student.sscPassingYear || '-')}
              ${studentDetailItem('HSC Result', student.hscResult || '-')}
              ${studentDetailItem('HSC Passing Year', student.hscPassingYear || '-')}
            </div>
          </section>
        </div>
        <div class="finance-summary">
          ${financeCard('Total Fee', finance.totalFee)}
          ${financeCard('Discount', finance.totalDiscount)}
          ${financeCard('Paid', finance.totalPaid)}
          ${financeCard('Due', finance.totalDue, dueTone)}
        </div>
        <section class="profile-section">
          <h3>Student Timeline</h3>
          ${studentTimeline(student)}
        </section>
        <form class="form-grid" data-action="save-student-fees" data-id="${student.id}">
          <h3>Course Fees & Discount</h3>
          ${(finance.enrollments || []).map((item) => html`
            <div class="fee-row">
              <strong>${escapeHtml(item.courseName)}</strong>
              <input type="hidden" name="courseId" value="${item.courseId}">
              <label class="field"><span>Fee (Course Setting)</span><input type="text" value="${formatMoney(item.fee)}" readonly></label>
              <label class="field"><span>Discount</span><input name="discount_${item.courseId}" type="number" min="0" step="0.01" value="${item.discount}"></label>
              <div><span class="muted">Due</span><strong>${formatMoney(item.due)}</strong></div>
            </div>
          `).join('') || '<p class="muted">No courses enrolled.</p>'}
          <button class="btn" type="submit">Save Fees</button>
        </form>
      </section>
    </div>
  `;
}

function studentDetailItem(label, value) {
  return `<div class="detail-item"><span>${escapeHtml(label)}</span><strong>${escapeHtml(value)}</strong></div>`;
}

function financeCard(label, value, tone = '') {
  return `<div class="finance-card ${tone}"><span>${escapeHtml(label)}</span><strong>${formatMoney(value)}</strong></div>`;
}

function studentTimeline(student) {
  const payments = (state.data.payments || [])
    .filter((payment) => payment.studentId === student.id)
    .map((payment) => ({
      date: payment.paidAt || payment.createdAt,
      title: `Payment ${payment.receiptNumber || ''}`,
      body: `${formatMoney(payment.amount)} · ${payment.courseName || '-'} · ${payment.status || 'completed'}`,
      tone: payment.status === 'cancelled' ? 'danger' : 'success',
    }));
  const attempts = (state.data.attempts || [])
    .filter((attempt) => attempt.studentId === student.id)
    .map((attempt) => ({
      date: attempt.submittedAt || attempt.createdAt,
      title: `Quiz Result: ${attempt.quizTitle || 'Exam'}`,
      body: `${attempt.score ?? attempt.earned ?? attempt.correct ?? 0}/${attempt.total ?? attempt.totalMarks ?? '-'} · ${attempt.passed ? 'Passed' : 'Not passed'}`,
      tone: attempt.passed ? 'success' : 'warning',
    }));
  const manual = (state.data.manualResults || [])
    .filter((item) => item.studentId === student.id || item.rollNumber === student.rollNumber)
    .map((item) => ({
      date: item.examDate || item.createdAt,
      title: `Manual Result: ${item.examName || 'Exam'}`,
      body: `${item.subject || '-'} · Mark ${item.mark || 0} · Position ${item.position || '-'}`,
      tone: 'success',
    }));
  const messages = (state.data.resultSmsLogs || [])
    .filter((item) => item.studentId === student.id || item.rollNumber === student.rollNumber || item.mobile === student.studentMobile)
    .map((item) => ({
      date: item.createdAt,
      title: 'Result SMS',
      body: `${item.examName || 'Exam'} · ${item.status || 'pending'}`,
      tone: item.status === 'sent' ? 'success' : 'warning',
    }));
  const admission = [{
    date: student.admissionDate || student.createdAt,
    title: 'Admission Created',
    body: `${student.rollNumber || '-'} · ${courseNames(student.courseIds) || 'No course'}`,
    tone: 'primary',
  }];
  const items = [...admission, ...payments, ...attempts, ...manual, ...messages]
    .filter((item) => item.date || item.title)
    .sort((a, b) => new Date(b.date || 0) - new Date(a.date || 0))
    .slice(0, 12);
  return `<div class="timeline-list">${items.map((item) => `<article class="timeline-item ${item.tone || ''}"><span>${escapeHtml(formatDate(item.date))}</span><strong>${escapeHtml(item.title)}</strong><small>${escapeHtml(item.body)}</small></article>`).join('') || '<div class="empty-state"><strong>No timeline yet.</strong><span>Payments, quiz attempts and SMS activity will appear here.</span></div>'}</div>`;
}

function metricCard(label, value, suffix = '', tone = '') {
  return `<div class="finance-card ${tone}"><span>${escapeHtml(label)}</span><strong>${escapeHtml(value)}${escapeHtml(suffix)}</strong></div>`;
}

function reportFilterSummary(filters, labels = {}) {
  const entries = Object.entries(filters || {}).filter(([, value]) => value);
  if (!entries.length) return '<span class="toolbar-chip">All records</span>';
  return entries.map(([key, value]) => {
    let displayValue = value;
    if (key === 'courseId') displayValue = courseName(value);
    if (key === 'batchId') displayValue = batchName(value);
    return `<span class="toolbar-chip">${escapeHtml(labels[key] || key)}: ${escapeHtml(displayValue)}</span>`;
  }).join('');
}

const shareholderLedgerLabels = {
  opening_balance: 'Opening Balance',
  capital_investment: 'Capital Investment',
  reference_commission: 'Reference Commission',
  session_profit_share: 'Session Profit Share',
  paid_for_institute: 'Paid for Institute',
  withdrawal: 'Withdrawal / Advance',
  expense_charged: 'Expense Charged',
  adjustment_positive: 'Positive Adjustment',
  adjustment_negative: 'Negative Adjustment',
};

function shareholderName(id) {
  return (state.data?.shareholders || []).find((item) => item.id === id)?.name || '';
}

function signedMoneyClass(value) {
  return Number(value || 0) < 0 ? 'danger' : 'success';
}

function formatMoney(value) {
  return `Tk ${Number(value || 0).toLocaleString('en-BD', { maximumFractionDigits: 2 })}`;
}

function openPrintWindow(title, body) {
  const printWindow = window.open('', '_blank', 'width=900,height=700');
  if (!printWindow) throw new Error('Allow popups to print this document.');
  const institute = state.data?.institute || state.institute || {};
  const printedAt = new Date().toLocaleString('en-GB', { hour12: true });
  const logo = institute.logoDataUrl || institute.faviconDataUrl || '';
  printWindow.document.write(`<!doctype html><html><head><title>${escapeHtml(title)}</title><style>
    *{box-sizing:border-box}body{margin:0;background:#eef4ff;font-family:Arial,sans-serif;color:#172033}
    .page{width:min(100%,900px);margin:0 auto;padding:28px 34px 36px;background:#fff;min-height:100vh}
    .print-header{display:flex;justify-content:space-between;gap:18px;align-items:flex-start;border-bottom:2px solid #2563eb;padding-bottom:16px;margin-bottom:22px}
    .brand{display:flex;gap:12px;align-items:center}.logo{width:52px;height:52px;border-radius:15px;background:#dbeafe;display:grid;place-items:center;color:#1d4ed8;font-weight:800;overflow:hidden}
    .logo img{width:100%;height:100%;object-fit:contain}.brand h2{margin:0;font-size:20px}.brand p,.meta p{margin:4px 0 0;color:#64748b;font-size:12px}.meta{text-align:right}
    h1{margin:0 0 18px;text-align:center;font-size:23px}.grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
    .student-head{display:flex;align-items:center;gap:14px;margin-bottom:18px}.student-photo{width:74px;height:82px;border:1px solid #dbe5f2;border-radius:10px;display:grid;place-items:center;background:#f8fafc;color:#64748b;overflow:hidden}.student-photo img{width:100%;height:100%;object-fit:cover}
    .item{border:1px solid #dbe5f2;border-radius:10px;padding:10px 12px;background:#f8fafc}.item span{display:block;color:#64748b;font-size:10px;margin-bottom:5px;text-transform:uppercase;letter-spacing:.04em}
    .item strong{font-size:12px}.summary{display:flex;gap:10px;margin-top:22px}.summary div{flex:1;border:1px solid #bfdbfe;background:#eff6ff;padding:12px;border-radius:10px;color:#64748b}
    .summary strong{display:block;margin-top:5px;color:#172033;font-size:18px}.print-note{margin-top:18px;padding:11px 12px;border-radius:10px;background:#f8fafc;border:1px solid #dbe5f2;color:#475569}
    table{width:100%;border-collapse:collapse;margin-top:22px;font-size:12px}
    th{background:#eff6ff;color:#1d4ed8;text-transform:uppercase;font-size:10px;letter-spacing:.05em}th,td{border:1px solid #dbe5f2;padding:9px;text-align:left}
    .signature{display:flex;justify-content:space-between;gap:24px;margin-top:62px}.signature div{width:220px;border-top:1px solid #172033;padding-top:8px;text-align:center;color:#64748b}
    .print-footer{margin-top:24px;padding-top:10px;border-top:1px solid #dbe5f2;text-align:center;color:#64748b;font-size:11px}
    @media screen and (max-width:640px){.page{padding:18px}.print-header,.student-head,.summary,.signature{display:grid;grid-template-columns:1fr}.meta{text-align:left}.grid,.grid-3{grid-template-columns:1fr}.signature div{width:100%;margin-top:22px}}
    @media print{body{background:#fff}.page{padding:18mm;box-shadow:none}button{display:none}.print-header{break-inside:avoid}}
  </style></head><body><main class="page">
    <header class="print-header">
      <div class="brand"><div class="logo">${logo ? `<img src="${escapeHtml(logo)}" alt="">` : escapeHtml((institute.name || 'R').slice(0, 1).toUpperCase())}</div><div><h2>${escapeHtml(institute.name || 'Student Management System')}</h2><p>${escapeHtml(institute.tagline || institute.address || '')}</p></div></div>
      <div class="meta"><strong>${escapeHtml(title)}</strong><p>Printed: ${escapeHtml(printedAt)}</p><p>Prepared by: ${escapeHtml(state.user?.name || '-')}</p><p>Session: ${escapeHtml(state.data?.activeSession?.name || '-')}</p></div>
    </header>
    ${body}
    <footer class="print-footer">Generated by ${escapeHtml(institute.name || 'Student Management System')}</footer>
  </main><script>window.onload=()=>window.print()<\/script></body></html>`);
  printWindow.document.close();
}

function printStudentProfile(student) {
  const finance = student.finance || {};
  const photo = student.photoDataUrl ? `<img src="${escapeHtml(student.photoDataUrl)}" alt="">` : escapeHtml(String(student.name || 'S').slice(0, 1).toUpperCase());
  openPrintWindow(`Student ${student.rollNumber}`, `
    <h1>Student Information Form</h1>
    <div class="student-head">
      <div class="student-photo">${photo}</div>
      <div>
        <h2>${escapeHtml(student.name || '-')}</h2>
        <p>Roll / Registration: ${escapeHtml(student.rollNumber || '-')} · Mobile: ${escapeHtml(student.studentMobile || '-')}</p>
      </div>
    </div>
    <div class="grid">
      ${studentDetailItem('Name', student.name)}
      ${studentDetailItem('Roll / Registration', student.rollNumber)}
      ${studentDetailItem('Student Mobile', student.studentMobile)}
      ${studentDetailItem('Guardian Mobile', student.guardianMobile || '-')}
      ${studentDetailItem('College', student.college || '-')}
      ${studentDetailItem('SSC Result', student.sscResult || '-')}
      ${studentDetailItem('SSC Passing Year', student.sscPassingYear || '-')}
      ${studentDetailItem('HSC Result', student.hscResult || '-')}
      ${studentDetailItem('HSC Passing Year', student.hscPassingYear || '-')}
      ${studentDetailItem('Courses', courseNames(student.courseIds) || '-')}
      ${studentDetailItem('Admission Date', student.admissionDate || '-')}
      ${studentDetailItem('Academic Year', student.academicYear || '-')}
      ${studentDetailItem('Email', student.email || '-')}
      ${studentDetailItem('Status', student.status)}
    </div>
    <div class="summary"><div>Total Payable<br><strong>${formatMoney(finance.totalPayable)}</strong></div><div>Discount<br><strong>${formatMoney(finance.totalDiscount)}</strong></div><div>Paid<br><strong>${formatMoney(finance.totalPaid)}</strong></div><div>Due<br><strong>${formatMoney(finance.totalDue)}</strong></div></div>
    <div class="signature"><div>Student / Guardian</div><div>Office Signature</div></div>
  `);
}

function printPaymentReceipt(payment) {
  const student = (state.data.students || []).find((item) => item.id === payment.studentId);
  const enrollment = student?.finance?.enrollments?.find((item) => item.courseId === payment.courseId);
  const institute = state.data?.institute || state.institute || {};
  openPrintWindow(payment.receiptNumber, `
    <h1>Payment Receipt</h1>
    <div class="grid">
      ${studentDetailItem('Receipt No.', payment.receiptNumber)}
      ${studentDetailItem('Payment Date', formatDate(payment.paidAt))}
      ${studentDetailItem('Student', payment.studentName)}
      ${studentDetailItem('Roll / Registration', payment.studentRoll || '-')}
      ${studentDetailItem('Course', payment.courseName)}
      ${studentDetailItem('Payment Method', payment.method.replaceAll('_', ' '))}
      ${studentDetailItem('Reference', payment.reference || '-')}
      ${studentDetailItem('Received By', payment.receivedByName || '-')}
    </div>
    <div class="summary"><div>Course Fee<br><strong>${formatMoney(enrollment?.fee)}</strong></div><div>Discount<br><strong>${formatMoney(enrollment?.discount)}</strong></div><div>Paid Now<br><strong>${formatMoney(payment.amount)}</strong></div><div>Remaining Due<br><strong>${formatMoney(enrollment?.due)}</strong></div></div>
    ${institute.receiptNote ? `<div class="print-note">${escapeHtml(institute.receiptNote)}</div>` : ''}
    <div class="signature"><div>Student / Guardian</div><div>Authorized Signature</div></div>
  `);
}

function printProgressReport(report) {
  const rows = [
    ...(report.attempts || []).map((attempt) => ({
      exam: attempt.quizTitle,
      subject: '-',
      mark: attempt.earned ?? attempt.correct ?? 0,
      position: '-',
      source: 'Quiz',
    })),
    ...(report.manual || []).map((item) => ({
      exam: item.examName,
      subject: item.subject || '-',
      mark: item.mark || 0,
      position: item.position || '-',
      source: 'Manual',
    })),
  ];
  openPrintWindow(`Progress ${report.student.rollNumber || report.student.name}`, `
    <h1>Student Progress Report</h1>
    <div class="grid">
      ${studentDetailItem('Name', report.student.name)}
      ${studentDetailItem('Roll / Registration', report.student.rollNumber || '-')}
      ${studentDetailItem('Mobile', report.student.studentMobile || report.student.mobile || '-')}
      ${studentDetailItem('Average Mark', String(report.summary.average || 0))}
      ${studentDetailItem('Best Mark', String(report.summary.best || 0))}
      ${studentDetailItem('Total Records', String(rows.length))}
    </div>
    <div class="summary"><div>Average<br><strong>${escapeHtml(String(report.summary.average || 0))}</strong></div><div>Best<br><strong>${escapeHtml(String(report.summary.best || 0))}</strong></div><div>Paid<br><strong>${formatMoney(report.finance.totalPaid)}</strong></div><div>Due<br><strong>${formatMoney(report.finance.totalDue)}</strong></div><div>Discount<br><strong>${formatMoney(report.finance.totalDiscount)}</strong></div></div>
    <table><thead><tr><th>Exam</th><th>Subject</th><th>Mark</th><th>Position</th><th>Source</th></tr></thead><tbody>
      ${rows.map((row) => `<tr><td>${escapeHtml(row.exam)}</td><td>${escapeHtml(row.subject)}</td><td>${escapeHtml(String(row.mark))}</td><td>${escapeHtml(row.position)}</td><td>${escapeHtml(row.source)}</td></tr>`).join('') || '<tr><td colspan="5">No result records yet.</td></tr>'}
    </tbody></table>
    <div class="signature"><div>Student / Guardian</div><div>Authorized Signature</div></div>
  `);
}

function courseNames(courseIds) {
  return (courseIds || [])
    .map((id) => (state.data.courses || []).find((course) => course.id === id)?.name)
    .filter(Boolean)
    .join(', ');
}

function studentBatchNames(student) {
  return (student.batchEnrollments || [])
    .map((item) => (state.data.batches || []).find((batch) => batch.id === item.batchId)?.name)
    .filter(Boolean)
    .join(', ');
}

function managerName(managerId) {
  return (state.data.managers || []).find((manager) => manager.id === managerId)?.name || '-';
}

function courseName(courseId) {
  return (state.data.courses || []).find((course) => course.id === courseId)?.name || '-';
}

function batchName(batchId) {
  return (state.data.batches || []).find((batch) => batch.id === batchId)?.name || '-';
}

function teacherPaymentStatus(payment) {
  const payable = Number(payment.payable ?? payment.payableAmount ?? 0);
  const paid = Number(payment.paid ?? payment.paidAmount ?? 0);
  const due = Number(payment.due ?? payment.dueAmount ?? Math.max(0, payable - paid));
  if (due <= 0 && payable > 0) return '<span class="badge success">paid</span>';
  if (paid > 0) return '<span class="badge warning">partial</span>';
  return '<span class="badge danger">due</span>';
}

function teacherClassSummary(payment) {
  const entries = payment.classEntries || [];
  const dates = entries.map((entry) => entry.date).filter(Boolean).join(', ');
  const classes = entries.reduce((sum, entry) => sum + Number(entry.classes || 0), 0);
  return `${classes} class${classes === 1 ? '' : 'es'}${dates ? ` Â· ${dates}` : ''}`;
}

function parseTeacherClassEntries(text, defaultSubject, defaultRate) {
  return String(text || '')
    .split(/\r?\n/)
    .map((line) => line.trim())
    .filter(Boolean)
    .map((line) => {
      const [date, subject, classes, rate, note] = line.split(',').map((part) => part.trim());
      return {
        date,
        subject: subject || defaultSubject || '',
        classes: classes || 1,
        rate: rate || defaultRate || 0,
        note: note || '',
      };
    });
}

function teacherClassEntriesText(payment) {
  return (payment.classEntries || [])
    .map((entry) => [entry.date, entry.subject, entry.classes, entry.rate, entry.note].filter((value) => value !== undefined && value !== null && value !== '').join(','))
    .join('\n');
}

function studentFeeStatus(student) {
  const finance = student.finance || {};
  if (Number(finance.totalDue || 0) <= 0 && Number(finance.totalPayable || 0) > 0) return '<span class="badge success">Paid</span>';
  if (Number(finance.totalPaid || 0) > 0) return '<span class="badge warning">Partial</span>';
  return '<span class="badge danger">Due</span>';
}

function studentCourseFinanceRows(courseIds, student = null) {
  const courses = state.data.courses || [];
  const batches = state.data.batches || [];
  if (!courseIds.length) return '<p class="muted">Select a course to set its fee, discount, batch and initial deposit.</p>';
  return courseIds.map((courseId) => {
    const course = courses.find((item) => item.id === courseId);
    if (!course) return '';
    const configured = (student?.courseFees || []).find((item) => item.courseId === courseId);
    const enrollment = (student?.finance?.enrollments || []).find((item) => item.courseId === courseId);
    const selectedBatchId = (student?.batchEnrollments || []).find((item) => item.courseId === courseId)?.batchId || '';
    const fee = Number(course.defaultFee ?? 0);
    const discount = Number(configured?.discount ?? enrollment?.discount ?? 0);
    const payable = Math.max(0, fee - discount);
    return html`
      <div class="student-finance-row" data-course-finance-row="${course.id}">
        <div class="student-finance-title"><strong>${escapeHtml(course.name)}</strong><span>Default ${formatMoney(course.defaultFee)}</span></div>
        <label class="field"><span>Course Fee</span><input type="text" value="${formatMoney(course.defaultFee)}" readonly data-fixed-fee="${course.defaultFee}"></label>
        <label class="field"><span>Discount</span><input name="discount_${course.id}" type="number" min="0" step="0.01" value="${discount}" data-discount-input></label>
        ${student ? '' : `<label class="field"><span>Initial Deposit</span><input name="deposit_${course.id}" type="number" min="0" max="${payable}" step="0.01" value="0" data-deposit-input></label>`}
        <label class="field"><span>Batch</span>
          <select name="batch_${course.id}">
            <option value="">No batch</option>
            ${batches.filter((batch) => batch.courseId === course.id && batch.status === 'active').map((batch) => `<option value="${batch.id}" ${batch.id === selectedBatchId ? 'selected' : ''}>${escapeHtml(batch.name)} (${batch.studentCount}/${batch.capacity || 'âˆž'})</option>`).join('')}
          </select>
        </label>
        <div class="finance-mini"><span>Payable</span><strong data-payable>${formatMoney(payable)}</strong></div>
        <div class="finance-mini"><span>${student ? 'Current Due' : 'Due After Deposit'}</span><strong data-finance-due>${formatMoney(student ? enrollment?.due : payable)}</strong></div>
      </div>
    `;
  }).join('');
}

