import { useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'
import {
  fetchClassProgressGroups,
  fetchParentEnrollments,
  fetchParentMessagesInbox,
  fetchReportCardAcknowledgement,
  fetchReportCardMeta,
  fetchSchoolCalendarEvents,
  fetchStudentScores,
} from '../../api/session'
import type {
  ClassProgressGroupRow,
  ParentEnrollmentStudent,
  ParentMessageRow,
  ReportCardAcknowledgementRow,
  ReportCardStudentMetaRow,
  SchoolCalendarEventRow,
  StudentScoreRow,
} from '../../api/types'
import { ParentParityShell } from './ParentParityShell'

function EmptyRow({ colSpan, children }: { colSpan: number; children: string }) {
  return (
    <tr>
      <td colSpan={colSpan} className="text-muted">
        {children}
      </td>
    </tr>
  )
}

function CiNotice({
  variant = 'info',
  children,
}: {
  variant?: 'info' | 'success' | 'secondary'
  children: string
}) {
  return <div className={`alert alert-${variant} small mb-3`}>{children}</div>
}

function formatDate(value?: string | null) {
  if (!value) return '—'
  const date = new Date(value)
  return Number.isNaN(date.getTime()) ? value : date.toLocaleDateString()
}

function normalizeCalendarDate(value: string | null | undefined): string {
  if (!value) return ''
  const match = /^(\d{4}-\d{2}-\d{2})/.exec(String(value))
  return match ? match[1] : String(value)
}

function formatCalendarLabel(value: string, options: Intl.DateTimeFormatOptions): string {
  if (!value) return ''
  return new Intl.DateTimeFormat('en-US', options).format(new Date(`${value}T12:00:00`))
}

function monthStart(value: Date): Date {
  return new Date(value.getFullYear(), value.getMonth(), 1)
}

function dateKey(value: Date): string {
  const y = value.getFullYear()
  const m = String(value.getMonth() + 1).padStart(2, '0')
  const d = String(value.getDate()).padStart(2, '0')
  return `${y}-${m}-${d}`
}

type ParentCalendarDisplayEvent = SchoolCalendarEventRow & {
  start: string
  backgroundColor: string
}

function scoreValue(row: StudentScoreRow, keys: string[]) {
  for (const key of keys) {
    const value = row[key]
    if (value !== undefined && value !== null && value !== '') return String(value)
  }
  return '—'
}

function EnrollmentTable({
  students,
  loading,
  empty,
}: {
  students: ParentEnrollmentStudent[]
  loading: boolean
  empty: string
}) {
  return (
    <div className="table-responsive">
      <table className="table table-striped table-sm align-middle">
        <thead>
          <tr>
            <th>Select</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>DOB</th>
            <th>Gender</th>
            <th>Grade</th>
            <th>Class</th>
            <th>Status</th>
          </tr>
        </thead>
        <tbody>
          {loading ? (
            <EmptyRow colSpan={8}>Loading students…</EmptyRow>
          ) : students.length === 0 ? (
            <EmptyRow colSpan={8}>{empty}</EmptyRow>
          ) : (
            students.map((student) => (
              <tr key={student.id}>
                <td>
                  <input type="checkbox" className="form-check-input" disabled />
                </td>
                <td>{student.firstname}</td>
                <td>{student.lastname}</td>
                <td>{formatDate(student.dob)}</td>
                <td>{student.gender ?? '—'}</td>
                <td>{student.registration_grade ?? '—'}</td>
                <td>{student.class_section ?? '—'}</td>
                <td>{student.enrollment_status ?? student.admission_status ?? '—'}</td>
              </tr>
            ))
          )}
        </tbody>
      </table>
    </div>
  )
}

export function ParentAddSecondParentPage() {
  return (
    <ParentParityShell
      title="Add second parent"
      ciViewFile="add_second_parent.php"
      legacyCiRoutes={['/parent/add_second_parent']}
    >
      <p className="text-muted small">
        Add a second parent or authorized account user by email.
      </p>
      <Link className="btn btn-success" to="/app/parent/authorized-users">
        Manage authorized users
      </Link>
    </ParentParityShell>
  )
}

export function ParentAssignmentsPage() {
  const [students, setStudents] = useState<ParentEnrollmentStudent[]>([])
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoading(true)
      try {
        const res = await fetchParentEnrollments(null)
        if (cancelled) return
        setStudents(res.students ?? [])
        setError(null)
      } catch (e) {
        if (!cancelled) {
          setStudents([])
          setError(e instanceof Error ? e.message : 'Failed to load assignments.')
        }
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [])

  return (
    <ParentParityShell title="Assignment" ciViewFile="assignments.php" legacyCiRoutes={[]}>
      <div className="pt-2 pb-2 mb-3 border-bottom">
        <h3 className="h4 mb-1">Assignment</h3>
        <p className="text-muted mb-0">
          Review classroom assignments and teacher-provided work for enrolled students.
        </p>
      </div>

      {error ? <div className="alert alert-warning small">{error}</div> : null}
      <EnrollmentTable
        students={students}
        loading={loading}
        empty="No students found. Please register your kids first."
      />

      <div className="mb-3">
        <label className="form-label" htmlFor="assignment_class_section_id">
          Select Class
        </label>
        <select className="form-control" id="assignment_class_section_id" disabled>
          <option>Select Class</option>
        </select>
      </div>
      <button type="button" className="btn btn-primary" disabled>
        Enroll Selected Students
      </button>
    </ParentParityShell>
  )
}

export function ParentCalendarPage() {
  const [events, setEvents] = useState<ParentCalendarDisplayEvent[]>([])
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)
  const [selectedDate, setSelectedDate] = useState<string>('')
  const [visibleMonth, setVisibleMonth] = useState<Date>(() => monthStart(new Date()))

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoading(true)
      try {
        const res = await fetchSchoolCalendarEvents()
        if (cancelled) return
        const rows = (res.data?.events ?? []).map((row) => {
          const start = normalizeCalendarDate(row.start)
          return {
            ...row,
            start,
            backgroundColor:
              row.backgroundColor ??
              row.extendedProps?.backgroundColor ??
              row.extendedProps?.color ??
              '#3788d8',
          }
        })
        const firstDate =
          rows.map((row) => row.start).filter(Boolean).sort()[0] ?? normalizeCalendarDate(new Date().toISOString())
        setEvents(rows)
        setSelectedDate((current) => current || firstDate)
        setVisibleMonth(monthStart(new Date(`${firstDate}T12:00:00`)))
        setError(null)
      } catch (e) {
        if (!cancelled) {
          setEvents([])
          setError(e instanceof Error ? e.message : 'Failed to load calendar events.')
        }
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [])

  const eventsByDate = useMemo(() => {
    const map = new Map<string, ParentCalendarDisplayEvent[]>()
    for (const event of events) {
      if (!event.start) continue
      if (!map.has(event.start)) map.set(event.start, [])
      map.get(event.start)?.push(event)
    }
    for (const rows of map.values()) {
      rows.sort((left, right) => left.title.localeCompare(right.title))
    }
    return map
  }, [events])

  const selectedEvents = eventsByDate.get(selectedDate) ?? []
  const todayKey = normalizeCalendarDate(new Date().toISOString())

  const monthCells = useMemo(() => {
    const firstDay = monthStart(visibleMonth)
    const lastDay = new Date(visibleMonth.getFullYear(), visibleMonth.getMonth() + 1, 0)
    const leading = firstDay.getDay()
    const totalCells = Math.ceil((leading + lastDay.getDate()) / 7) * 7
    const startDate = new Date(visibleMonth.getFullYear(), visibleMonth.getMonth(), 1 - leading)

    return Array.from({ length: totalCells }, (_, index) => {
      const current = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + index)
      const key = dateKey(current)
      return {
        key,
        day: current.getDate(),
        inMonth: current.getMonth() === visibleMonth.getMonth(),
        events: eventsByDate.get(key) ?? [],
      }
    })
  }, [eventsByDate, visibleMonth])

  const monthEventCount = monthCells.reduce((sum, cell) => sum + (cell.inMonth ? cell.events.length : 0), 0)
  const noSchoolCount = events.filter((row) => Boolean(row.extendedProps?.no_school)).length
  const generalCount = events.length - noSchoolCount

  return (
    <ParentParityShell
      title="School calendar"
      ciViewFile="calendar.php"
      legacyCiRoutes={['/parent/calendar']}
      fullWidth
    >
      <div className="teacher-calendar-shell">
        <section className="teacher-calendar-summary">
          <div className="teacher-calendar-stat">
            <span className="teacher-calendar-stat-value">{events.length}</span>
            <span className="teacher-calendar-stat-label">Total events</span>
          </div>
          <div className="teacher-calendar-stat">
            <span className="teacher-calendar-stat-value">{generalCount}</span>
            <span className="teacher-calendar-stat-label">General events</span>
          </div>
          <div className="teacher-calendar-stat">
            <span className="teacher-calendar-stat-value">{noSchoolCount}</span>
            <span className="teacher-calendar-stat-label">No-school days</span>
          </div>
        </section>

        <div className="teacher-calendar-layout">
          <section className="teacher-calendar-panel">
            <div className="teacher-calendar-toolbar">
              <div>
                <h2 className="h5 mb-1">
                  {visibleMonth.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}
                </h2>
                <p className="text-muted mb-0 small">
                  {monthEventCount} event{monthEventCount === 1 ? '' : 's'} this month
                </p>
              </div>
              <div className="teacher-calendar-controls">
                <button
                  type="button"
                  className="btn btn-outline-secondary btn-sm"
                  onClick={() =>
                    setVisibleMonth((current) => monthStart(new Date(current.getFullYear(), current.getMonth() - 1, 1)))
                  }
                >
                  Prev
                </button>
                <button
                  type="button"
                  className="btn btn-success btn-sm"
                  onClick={() => {
                    setSelectedDate(todayKey)
                    setVisibleMonth(monthStart(new Date()))
                  }}
                >
                  Today
                </button>
                <button
                  type="button"
                  className="btn btn-outline-secondary btn-sm"
                  onClick={() =>
                    setVisibleMonth((current) => monthStart(new Date(current.getFullYear(), current.getMonth() + 1, 1)))
                  }
                >
                  Next
                </button>
              </div>
            </div>

            <div className="teacher-calendar-legend small">
              <span><i className="teacher-calendar-dot" style={{ background: '#3788d8' }} /> General</span>
              <span><i className="teacher-calendar-dot" style={{ background: '#ffc107' }} /> No school</span>
            </div>

            <div className="teacher-calendar-grid" aria-label="Parent calendar">
              {['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map((day) => (
                <div key={day} className="teacher-calendar-cell teacher-calendar-head">
                  {day}
                </div>
              ))}
              {monthCells.map((cell) => (
                <button
                  key={cell.key}
                  type="button"
                  className={[
                    'teacher-calendar-cell',
                    'teacher-calendar-day',
                    cell.inMonth ? '' : 'is-muted',
                    cell.key === todayKey ? 'is-today' : '',
                    cell.key === selectedDate ? 'is-selected' : '',
                  ]
                    .filter(Boolean)
                    .join(' ')}
                  onClick={() => {
                    setSelectedDate(cell.key)
                    if (!cell.inMonth) {
                      setVisibleMonth(monthStart(new Date(`${cell.key}T12:00:00`)))
                    }
                  }}
                >
                  <span className="teacher-calendar-day-number">{cell.day}</span>
                  <div className="teacher-calendar-events">
                    {cell.events.slice(0, 3).map((event) => (
                      <span
                        key={`${String(event.id ?? event.title)}-${event.start}`}
                        className="teacher-calendar-event-pill"
                        style={{
                          backgroundColor: `${event.backgroundColor}22`,
                          borderLeftColor: event.backgroundColor,
                        }}
                      >
                        {event.title}
                      </span>
                    ))}
                    {cell.events.length > 3 ? (
                      <span className="teacher-calendar-more">+{cell.events.length - 3} more</span>
                    ) : null}
                  </div>
                </button>
              ))}
            </div>
          </section>

          <aside className="teacher-calendar-panel">
            <div className="teacher-calendar-agenda-head">
              <div>
                <h2 className="h5 mb-1">Day agenda</h2>
                <p className="text-muted mb-0 small">
                  {selectedDate
                    ? formatCalendarLabel(selectedDate, {
                        weekday: 'long',
                        month: 'long',
                        day: 'numeric',
                        year: 'numeric',
                      })
                    : 'Select a date'}
                </p>
              </div>
              <span className="badge text-bg-light">
                {selectedEvents.length} event{selectedEvents.length === 1 ? '' : 's'}
              </span>
            </div>

            {loading ? <p className="text-muted small mb-0">Loading calendar events…</p> : null}
            {!loading && selectedEvents.length === 0 ? (
              <p className="text-muted small mb-0">No parent calendar events are available for this day.</p>
            ) : null}
            {!loading && selectedEvents.length > 0 ? (
              <div className="teacher-calendar-agenda-list">
                {selectedEvents.map((event) => (
                  <article key={`${String(event.id ?? event.title)}-${event.start}`} className="teacher-calendar-agenda-item">
                    <div className="teacher-calendar-agenda-tag">
                      <i className="teacher-calendar-dot" style={{ background: event.backgroundColor }} />
                      <span>{event.extendedProps?.no_school ? 'No School' : 'School Event'}</span>
                    </div>
                    <h3 className="h6 mb-1">{event.title}</h3>
                    <p className="small text-muted mb-0">{event.description || 'No extra details provided.'}</p>
                  </article>
                ))}
              </div>
            ) : null}
          </aside>
        </div>
      </div>
      {!loading && !error && events.length === 0 ? <p className="small text-muted mt-2 mb-0">No parent calendar events are available.</p> : null}
    </ParentParityShell>
  )
}

export function ParentClassesPage() {
  const [students, setStudents] = useState<ParentEnrollmentStudent[]>([])
  const [selectedYear, setSelectedYear] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoading(true)
      try {
        const res = await fetchParentEnrollments(null)
        if (cancelled) return
        setStudents(res.students ?? [])
        setSelectedYear(res.selectedYear ?? null)
        setError(null)
      } catch (e) {
        if (!cancelled) {
          setStudents([])
          setSelectedYear(null)
          setError(e instanceof Error ? e.message : 'Failed to load classes.')
        }
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [])

  return (
    <ParentParityShell title="Enroll in Classes" ciViewFile="classes.php" legacyCiRoutes={[]}>
      <div className="pt-2 pb-2 mb-3 border-bottom">
        <h3 className="h4 mb-1">Enroll in Classes</h3>
        <p className="text-muted mb-0">
          Enroll your kids in the available classes for the upcoming term.
        </p>
      </div>

      {selectedYear ? <p className="small text-muted">School year: {selectedYear}</p> : null}
      {error ? <div className="alert alert-warning small">{error}</div> : null}
      <EnrollmentTable
        students={students}
        loading={loading}
        empty="No students found. Please register your kids first."
      />

      <div className="mb-3">
        <label className="form-label" htmlFor="classes_class_section_id">
          Select Class
        </label>
        <select className="form-control" id="classes_class_section_id" disabled>
          <option>Select Class</option>
        </select>
      </div>
      <button type="button" className="btn btn-primary" disabled>
        Enroll Selected Students
      </button>
    </ParentParityShell>
  )
}

export function ParentProgressListPage() {
  const [groups, setGroups] = useState<ClassProgressGroupRow[]>([])
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoading(true)
      try {
        const res = await fetchClassProgressGroups()
        if (cancelled) return
        setGroups(res.data?.items ?? [])
        setError(null)
      } catch (e) {
        if (!cancelled) {
          setGroups([])
          setError(e instanceof Error ? e.message : 'Failed to load class progress.')
        }
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [])

  return (
    <ParentParityShell
      title="Class Progress"
      ciViewFile="class_progress_list.php"
      legacyCiRoutes={['/parent/progress']}
    >
      <div className="d-flex align-items-center justify-content-between mb-3 flex-wrap gap-2">
        <div>
          <h3 className="mb-0">Class Progress</h3>
          <div className="text-muted">Review the weekly reports your child’s teachers submit.</div>
        </div>
        <div className="text-end text-muted small">
          Reports are grouped by student; click a name to expand weekly details.
        </div>
      </div>

      {error ? <div className="alert alert-warning small">{error}</div> : null}

      <div className="accordion" id="parentProgressAccordion">
        {loading ? (
          <CiNotice>Loading progress reports…</CiNotice>
        ) : groups.length === 0 ? (
          <CiNotice>
            We couldn’t find any current progress reports for your account. Once your child is
            assigned to a Sunday class, their teacher’s progress reports will appear here.
          </CiNotice>
        ) : (
          groups.map((group, index) => {
            const reports = Object.values(group.reports ?? {})
            const collapseId = `progress-week-${index}`
            return (
              <div className="accordion-item" key={`${group.week_start}-${group.class_section_id}-${index}`}>
                <h2 className="accordion-header">
                  <button
                    className={`accordion-button ${index === 0 ? '' : 'collapsed'}`}
                    type="button"
                    data-bs-toggle="collapse"
                    data-bs-target={`#${collapseId}`}
                  >
                    <div className="d-flex flex-column flex-md-row align-items-md-center gap-1 gap-md-3">
                      <span className="fw-semibold">
                        {formatDate(group.week_start)} - {formatDate(group.week_end)}
                      </span>
                      <span className="text-muted small">
                        Class: {group.class_section_name || 'N/A'}
                      </span>
                    </div>
                  </button>
                </h2>
                <div
                  id={collapseId}
                  className={`accordion-collapse collapse ${index === 0 ? 'show' : ''}`}
                  data-bs-parent="#parentProgressAccordion"
                >
                  <div className="accordion-body">
                    {reports.length === 0 ? (
                      <div className="alert alert-secondary mb-0">No reports submitted yet.</div>
                    ) : (
                      <div className="table-responsive">
                        <table className="table table-hover align-middle mb-0">
                          <thead className="table-light">
                            <tr>
                              <th>Subject</th>
                              <th>Unit</th>
                              <th>Status</th>
                              <th>Teacher</th>
                            </tr>
                          </thead>
                          <tbody>
                            {reports.map((report) => (
                              <tr key={report.id}>
                                <td>{report.subject ?? '—'}</td>
                                <td>{report.unit_title ?? '—'}</td>
                                <td>
                                  <span className="badge bg-secondary">
                                    {report.status_label ?? report.status ?? '—'}
                                  </span>
                                </td>
                                <td>{report.teacher_name ?? '—'}</td>
                              </tr>
                            ))}
                          </tbody>
                        </table>
                      </div>
                    )}
                  </div>
                </div>
              </div>
            )
          })
        )}
      </div>
    </ParentParityShell>
  )
}

export function ParentInvoicePaymentPage() {
  return (
    <ParentParityShell
      title="Invoice payment"
      ciViewFile="invoice_payment.php"
      legacyCiRoutes={['/parent/invoice_payment']}
    >
      <p className="text-muted small">Choose an invoice from your payment list to review balances.</p>
      <Link className="btn btn-success" to="/app/parent/payment">
        Open payments
      </Link>
    </ParentParityShell>
  )
}

export function ParentNoKidsRegisteredPage() {
  return (
    <ParentParityShell
      title="No kids registered"
      ciViewFile="no_kids_registred.php"
      legacyCiRoutes={['/parent/child_register', '/parent/register_student']}
    >
      <div className="alert alert-info small">No students are registered under this account yet.</div>
      <Link className="btn btn-success" to="/app/parent/add-student-form">
        Add student
      </Link>
    </ParentParityShell>
  )
}

export function ParentMessagePage() {
  const [messages, setMessages] = useState<ParentMessageRow[]>([])
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoading(true)
      try {
        const res = await fetchParentMessagesInbox()
        if (cancelled) return
        setMessages(res.data?.messages ?? [])
        setError(null)
      } catch (e) {
        if (!cancelled) {
          setMessages([])
          setError(e instanceof Error ? e.message : 'Failed to load messages.')
        }
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [])

  return (
    <ParentParityShell title="Messages" ciViewFile="parent_message.php" legacyCiRoutes={[]}>
      <div className="pt-2 pb-2 mb-3 border-bottom">
        <h3 className="h4 mb-1">Messages</h3>
        <p className="text-muted mb-0">
          Send and receive messages from teachers and school administrators.
        </p>
      </div>

      <section className="mb-4">
        <h4 className="h5">Received Messages</h4>
        {error ? <div className="alert alert-warning small">{error}</div> : null}
        <div className="table-responsive">
          <table className="table table-striped align-middle">
            <thead>
              <tr>
                <th>Message Number</th>
                <th>From</th>
                <th>Subject</th>
                <th>Message</th>
                <th>Date</th>
              </tr>
            </thead>
            <tbody>
              {loading ? (
                <EmptyRow colSpan={5}>Loading messages…</EmptyRow>
              ) : messages.length === 0 ? (
                <EmptyRow colSpan={5}>No messages found.</EmptyRow>
              ) : (
                messages.map((message) => (
                  <tr key={message.id ?? message.message_number ?? message.subject}>
                    <td>{message.message_number ?? '—'}</td>
                    <td>{message.sender_name ?? '—'}</td>
                    <td>{message.subject ?? '—'}</td>
                    <td>{message.message ?? '—'}</td>
                    <td>{message.sent_datetime ?? '—'}</td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </section>

      <section className="mb-2">
        <h4 className="h5">Send a Message</h4>
        <form className="row g-3">
          <div className="col-12">
            <label className="form-label" htmlFor="recipient">
              Recipient
            </label>
            <select className="form-control" id="recipient" name="recipient">
              <option value="teacher">Teacher</option>
              <option value="administration">Administration</option>
            </select>
          </div>
          <div className="col-12">
            <label className="form-label" htmlFor="subject">
              Subject
            </label>
            <input type="text" className="form-control" id="subject" name="subject" />
          </div>
          <div className="col-12">
            <label className="form-label" htmlFor="message">
              Message
            </label>
            <textarea className="form-control" id="message" name="message" rows={4} />
          </div>
          <div className="col-12">
            <button type="button" className="btn btn-primary" disabled>
              Send Message
            </button>
          </div>
        </form>
      </section>
    </ParentParityShell>
  )
}

export function ParentEnrollFailurePage() {
  return (
    <ParentParityShell title="Enrollment unsuccessful" ciViewFile="enroll_failure.php" legacyCiRoutes={['/parent/enroll_failure']}>
      <div className="alert alert-warning small">Enrollment could not be completed.</div>
      <Link className="btn btn-outline-success" to="/app/parent/enroll-classes">Back to enrollment</Link>
    </ParentParityShell>
  )
}

export function ParentEnrollSuccessPage() {
  return (
    <ParentParityShell title="Enrollment successful" ciViewFile="enroll_success.php" legacyCiRoutes={['/parent/enroll_success']}>
      <div className="alert alert-success small">Enrollment completed successfully.</div>
      <Link className="btn btn-success" to="/app/parent/enroll-classes">View enrollments</Link>
    </ParentParityShell>
  )
}

export function ParentPaymentSuccessPage() {
  return (
    <ParentParityShell title="Payment success" ciViewFile="payment_success.php" legacyCiRoutes={['/parent/payment_success']}>
      <div className="alert alert-success small">Payment completed successfully.</div>
      <Link className="btn btn-success" to="/app/parent/payment">View payments</Link>
    </ParentParityShell>
  )
}

export function ParentReportCardsPage() {
  const [students, setStudents] = useState<ReportCardStudentMetaRow[]>([])
  const [ackMap, setAckMap] = useState<Record<number, ReportCardAcknowledgementRow>>({})
  const [selectedYear, setSelectedYear] = useState<string | null>(null)
  const [selectedSemester, setSelectedSemester] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoading(true)
      try {
        const meta = await fetchReportCardMeta()
        if (cancelled) return
        const metaData = meta.data
        const rows = metaData?.students ?? []
        setStudents(rows)
        setSelectedYear(metaData?.selectedYear ?? null)
        setSelectedSemester(metaData?.selectedSemester ?? null)

        const acknowledgements = await Promise.all(
          rows.map(async (student) => {
            try {
              const ack = await fetchReportCardAcknowledgement(
                student.id,
                metaData?.selectedYear,
                metaData?.selectedSemester,
              )
              return [student.id, ack.data ?? null] as const
            } catch {
              return [student.id, null] as const
            }
          }),
        )
        if (cancelled) return
        setAckMap(
          Object.fromEntries(
            acknowledgements
              .filter((entry): entry is readonly [number, ReportCardAcknowledgementRow] => Boolean(entry[1]))
              .map(([studentId, ack]) => [studentId, ack]),
          ),
        )
        setError(null)
      } catch (e) {
        if (!cancelled) {
          setStudents([])
          setAckMap({})
          setError(e instanceof Error ? e.message : 'Failed to load report cards.')
        }
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [])

  return (
    <ParentParityShell
      title="Report Cards"
      ciViewFile="report_cards.php"
      legacyCiRoutes={['/parent/report-cards']}
    >
      <div className="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-3">
        <div>
          <h3 className="text-success mb-1" style={{ fontFamily: 'Arial, sans-serif' }}>
            Report Cards
          </h3>
          <div className="text-muted small">
            {selectedYear ?? 'N/A'} {selectedSemester ? `• ${selectedSemester} Semester` : ''}
          </div>
        </div>
      </div>

      {error ? <div className="alert alert-warning small">{error}</div> : null}
      <div className="table-responsive">
        <table className="table table-striped table-bordered align-middle">
          <thead className="table-light">
            <tr>
              <th>Student</th>
              <th>Class Section</th>
              <th>Viewed</th>
              <th>Signature</th>
              <th className="text-end">Action</th>
            </tr>
          </thead>
          <tbody>
            {loading ? (
              <EmptyRow colSpan={5}>Loading report cards…</EmptyRow>
            ) : students.length === 0 ? (
              <EmptyRow colSpan={5}>No students available for report cards.</EmptyRow>
            ) : (
              students.map((student) => {
                const ack = ackMap[student.id]
                return (
                  <tr key={student.id}>
                    <td>{`${student.firstname} ${student.lastname}`.trim() || 'Student'}</td>
                    <td>{student.class_section_name || 'N/A'}</td>
                    <td>{ack?.viewed_at ? formatDate(ack.viewed_at) : 'Not viewed'}</td>
                    <td>
                      {ack?.signed_at ? (
                        <>
                          {ack.signed_name || 'Signed'}
                          <br />
                          <small className="text-muted">{formatDate(ack.signed_at)}</small>
                        </>
                      ) : (
                        <span className="text-muted">Not signed</span>
                      )}
                    </td>
                    <td className="text-end">
                      <Link
                        className="btn btn-sm btn-outline-primary"
                        to={`/app/parent/report-cards/view/${student.id}`}
                      >
                        View Report
                      </Link>
                    </td>
                  </tr>
                )
              })
            )}
          </tbody>
        </table>
      </div>
    </ParentParityShell>
  )
}

export function ParentScoresPage() {
  const [students, setStudents] = useState<ParentEnrollmentStudent[]>([])
  const [scores, setScores] = useState<Record<number, StudentScoreRow[]>>({})
  const [selectedYear, setSelectedYear] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoading(true)
      try {
        const enrollment = await fetchParentEnrollments(null)
        if (cancelled) return
        const rows = enrollment.students ?? []
        setStudents(rows)
        setSelectedYear(enrollment.selectedYear ?? null)

        const scorePairs = await Promise.all(
          rows.map(async (student) => {
            try {
              const res = await fetchStudentScores(student.id)
              return [student.id, res.rows ?? []] as const
            } catch {
              return [student.id, []] as const
            }
          }),
        )
        if (cancelled) return
        setScores(Object.fromEntries(scorePairs))
        setError(null)
      } catch (e) {
        if (!cancelled) {
          setStudents([])
          setScores({})
          setSelectedYear(null)
          setError(e instanceof Error ? e.message : 'Failed to load scores.')
        }
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [])

  const semesters = ['Fall', 'Spring']

  return (
    <ParentParityShell title="Scores" ciViewFile="scores.php" legacyCiRoutes={['/parent/scores']}>
      <div className="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-3">
        <h3 className="text-success mb-0" style={{ fontFamily: 'Arial, sans-serif' }}>
          Scores
        </h3>
      </div>

      <form className="form-inline mb-3">
        <div className="d-flex flex-wrap align-items-center gap-2">
          <select name="school_year" id="school_year" className="form-control" disabled>
            <option>{selectedYear ?? 'School year'}</option>
          </select>
          <button type="button" className="btn btn-success" disabled>
            Filter
          </button>
        </div>
      </form>

      {error ? <div className="alert alert-warning small">{error}</div> : null}
      <div className="accordion" id="parentScoresAccordion">
        {semesters.map((semester, index) => (
          <div className="accordion-item" key={semester}>
            <h2 className="accordion-header" id={`heading${semester}`}>
              <button
                className={`accordion-button ${index === 0 ? '' : 'collapsed'}`}
                type="button"
                data-bs-toggle="collapse"
                data-bs-target={`#scores-${semester}`}
              >
                {semester} Semester
              </button>
            </h2>
            <div
              id={`scores-${semester}`}
              className={`accordion-collapse collapse ${index === 0 ? 'show' : ''}`}
              data-bs-parent="#parentScoresAccordion"
            >
                <div className="accordion-body p-0">
                  <div className="table-responsive">
                    <table className="table table-striped table-bordered mb-0">
                      <thead>
                        <tr>
                          <th>School ID</th>
                          <th>Student Name</th>
                          <th>Class Section</th>
                          <th>Homework</th>
                          <th>Project</th>
                          <th>Participation</th>
                          <th>Quiz</th>
                          <th>Attendance</th>
                          <th>PTAP</th>
                          <th>{semester === 'Fall' ? 'Midterm' : 'Final Exam'}</th>
                          <th>Semester Score</th>
                          <th>Report Card</th>
                        </tr>
                      </thead>
                      <tbody>
                        {loading ? (
                          <EmptyRow colSpan={12}>Loading scores…</EmptyRow>
                        ) : students.length === 0 ? (
                          <EmptyRow colSpan={12}>No scores available for the selected year.</EmptyRow>
                        ) : (
                          students.flatMap((student) => {
                            const studentScores = (scores[student.id] ?? []).filter((row) => {
                              const rowSemester = String(row.semester ?? '').toLowerCase()
                              return rowSemester === semester.toLowerCase()
                            })
                            if (studentScores.length === 0) {
                              return [
                                <tr key={`${student.id}-${semester}-empty`}>
                                  <td>—</td>
                                  <td>{`${student.firstname} ${student.lastname}`.trim()}</td>
                                  <td>{student.class_section ?? '—'}</td>
                                  <td colSpan={9} className="text-muted">
                                    No {semester} semester scores recorded yet.
                                  </td>
                                </tr>,
                              ]
                            }
                            return studentScores.map((row, scoreIndex) => (
                              <tr key={`${student.id}-${semester}-${row.id ?? scoreIndex}`}>
                                <td>{scoreValue(row, ['school_id'])}</td>
                                <td>{`${student.firstname} ${student.lastname}`.trim()}</td>
                                <td>{student.class_section ?? '—'}</td>
                                <td>{scoreValue(row, ['homework_score', 'homework'])}</td>
                                <td>{scoreValue(row, ['project_score', 'project'])}</td>
                                <td>{scoreValue(row, ['participation_score', 'participation'])}</td>
                                <td>{scoreValue(row, ['quiz_score', 'quiz'])}</td>
                                <td>{scoreValue(row, ['attendance_score', 'attendance'])}</td>
                                <td>{scoreValue(row, ['ptap_score', 'ptap'])}</td>
                                <td>
                                  {scoreValue(row, [
                                    semester === 'Fall' ? 'midterm_exam_score' : 'final_exam_score',
                                    semester === 'Fall' ? 'midterm_exam' : 'final_exam',
                                  ])}
                                </td>
                                <td>{scoreValue(row, ['semester_score', 'semester'])}</td>
                                <td>
                                  <Link
                                    className="btn btn-sm btn-outline-primary"
                                    to={`/app/parent/report-cards/view/${student.id}`}
                                  >
                                    View
                                  </Link>
                                </td>
                              </tr>
                            ))
                          })
                        )}
                      </tbody>
                    </table>
                  </div>
                </div>
              </div>
          </div>
        ))}
      </div>
    </ParentParityShell>
  )
}

export function ParentSuccessMessagePage() {
  return (
    <ParentParityShell title="Success" ciViewFile="success_message.php" legacyCiRoutes={[]}>
      <CiNotice variant="success">Your request was completed successfully.</CiNotice>
      <Link className="btn btn-success" to="/app/parent/home">
        Back to Parent dashboard
      </Link>
    </ParentParityShell>
  )
}

export function ParentWithdrawSuccessPage() {
  return (
    <ParentParityShell title="Withdrawal successful" ciViewFile="withdraw_success.php" legacyCiRoutes={[]}>
      <div className="alert alert-success small">Withdrawal completed successfully.</div>
      <Link className="btn btn-success" to="/app/parent/enroll-classes">View enrollments</Link>
    </ParentParityShell>
  )
}
