import { useCallback, useEffect, useMemo, useState } from 'react'
import { ApiHttpError } from '../../api/http'
import {
  fetchReportCardAck,
  fetchReportCardClassHtml,
  fetchReportCardCompleteness,
  fetchReportCardMeta,
  fetchReportCardStudentHtml,
  openReportCardDownload,
  reportCardClassUrl,
  reportCardStudentUrl,
  type ReportCardMeta,
} from '../../api/printables'

function todayIsoDate() {
  const t = new Date()
  const p = (n: number) => String(n).padStart(2, '0')
  return `${t.getFullYear()}-${p(t.getMonth() + 1)}-${p(t.getDate())}`
}

export function ReportCardManagementPage() {
  const [meta, setMeta] = useState<ReportCardMeta | null>(null)
  const [schoolYear, setSchoolYear] = useState('')
  const [semester, setSemester] = useState('')
  const [reportDate, setReportDate] = useState(todayIsoDate)
  const [classId, setClassId] = useState('')
  const [studentId, setStudentId] = useState('')
  const [ackText, setAckText] = useState('')
  const [studentHtml, setStudentHtml] = useState('')
  const [classHtml, setClassHtml] = useState('')
  const [showStudentFrame, setShowStudentFrame] = useState(false)
  const [showClassFrame, setShowClassFrame] = useState(false)
  const [completenessStatus, setCompletenessStatus] = useState('')
  const [completenessError, setCompletenessError] = useState(false)
  const [completenessSummary, setCompletenessSummary] = useState('')
  const [completenessRows, setCompletenessRows] = useState<Array<Record<string, unknown>>>([])
  const [completenessWrapOpen, setCompletenessWrapOpen] = useState(false)

  const loadMeta = useCallback(async (year?: string | null, sem?: string | null) => {
    const data = await fetchReportCardMeta({
      school_year: year ?? undefined,
      semester: sem ?? undefined,
    })
    setMeta(data)
    if (data.selectedYear) setSchoolYear(data.selectedYear)
    if (data.selectedSemester != null) setSemester(data.selectedSemester ?? '')
    const students = data.students ?? []
    setStudentId(students.length ? String(students[0].id) : '')
    const classes = data.classSections ?? []
    const firstC = classes[0]
    setClassId(firstC ? String(firstC.class_section_id ?? firstC.id ?? '') : '')
  }, [])

  useEffect(() => {
    loadMeta(null, null).catch(() => {})
  }, [loadMeta])

  const studentOptions = meta?.students ?? []
  const classOptions = meta?.classSections ?? []

  const opts = useMemo(
    () => ({
      school_year: schoolYear,
      semester: semester || undefined,
      report_date: reportDate || undefined,
    }),
    [schoolYear, semester, reportDate],
  )

  async function refreshAck(sid: string) {
    if (!sid) {
      setAckText('')
      return
    }
    try {
      const data = await fetchReportCardAck({
        student_id: sid,
        school_year: schoolYear,
        semester,
      })
      const viewed = data.viewed_at ? `Viewed: ${data.viewed_at}` : 'Viewed: not yet'
      const signed = data.signed_at
        ? `Signed: ${data.signed_at} (${data.signed_name || 'name missing'})`
        : 'Signed: not yet'
      setAckText(`Parent acknowledgement — ${viewed} · ${signed}`)
    } catch {
      setAckText('Parent acknowledgement: unavailable')
    }
  }

  useEffect(() => {
    refreshAck(studentId).catch(() => {})
  }, [studentId, schoolYear, semester])

  async function onViewStudent() {
    if (!studentId || !schoolYear) return
    try {
      const html = await fetchReportCardStudentHtml(studentId, opts)
      setStudentHtml(html)
      setShowStudentFrame(true)
      setShowClassFrame(false)
    } catch (e: unknown) {
      alert(e instanceof ApiHttpError ? e.message : 'Failed to load report.')
    }
  }

  async function onViewClass() {
    if (!classId || !schoolYear) return
    try {
      const html = await fetchReportCardClassHtml(classId, opts)
      setClassHtml(html)
      setShowClassFrame(true)
      setShowStudentFrame(false)
    } catch (e: unknown) {
      alert(e instanceof ApiHttpError ? e.message : 'Failed to load report.')
    }
  }

  async function downloadStudent() {
    if (!studentId || !schoolYear) return
    const url = reportCardStudentUrl(studentId, {
      school_year: schoolYear,
      semester,
      download: true,
      report_date: reportDate || undefined,
    })
    try {
      await openReportCardDownload(url)
    } catch (e: unknown) {
      alert(e instanceof ApiHttpError ? e.message : 'Download failed.')
    }
  }

  async function downloadClass() {
    if (!classId || !schoolYear) return
    const url = reportCardClassUrl(classId, {
      school_year: schoolYear,
      semester,
      download: true,
      report_date: reportDate || undefined,
    })
    try {
      await openReportCardDownload(url)
    } catch (e: unknown) {
      alert(e instanceof ApiHttpError ? e.message : 'Download failed.')
    }
  }

  function printStudent() {
    if (!studentId || !schoolYear) return
    const url = reportCardStudentUrl(studentId, {
      school_year: schoolYear,
      semester,
      report_date: reportDate || undefined,
    })
    window.open(url, '_blank', 'noopener')
  }

  function printClass() {
    if (!classId || !schoolYear) return
    const url = reportCardClassUrl(classId, {
      school_year: schoolYear,
      semester,
      report_date: reportDate || undefined,
    })
    window.open(url, '_blank', 'noopener')
  }

  async function checkCompleteness() {
    if (!classId || !schoolYear) {
      setCompletenessStatus('Select a class and school year first.')
      setCompletenessError(true)
      return
    }
    setCompletenessStatus('Checking completeness...')
    setCompletenessError(false)
    setCompletenessSummary('')
    setCompletenessWrapOpen(false)
    setCompletenessRows([])
    try {
      const data = await fetchReportCardCompleteness({
        class_section_id: classId,
        school_year: schoolYear,
        semester,
      })
      setCompletenessStatus('')
      const students = Array.isArray(data.students) ? data.students : []
      if (students.length === 0) {
        setCompletenessSummary('No students found for the selected class.')
        setCompletenessWrapOpen(false)
        return
      }
      const summary = (data.summary ?? {}) as Record<string, number>
      const total = summary.total ?? students.length
      const complete = summary.complete ?? 0
      const incomplete = summary.incomplete ?? total - complete
      const warnings = summary.warnings ?? 0
      const note = data.used_fallback ? ' (roster uses year-only assignments)' : ''
      setCompletenessSummary(
        `Complete: ${complete}/${total} | Incomplete: ${incomplete} | With warnings: ${warnings}${note}`,
      )
      setCompletenessRows(students as Array<Record<string, unknown>>)
      setCompletenessWrapOpen(true)
    } catch (e: unknown) {
      setCompletenessStatus(e instanceof Error ? e.message : 'Failed to load completeness report.')
      setCompletenessError(true)
    }
  }

  const years = meta?.schoolYears ?? []
  const semesters = meta?.semesters ?? []

  return (
    <div className="container-fluid py-3">
      <div className="text-center mx-auto mb-4" style={{ maxWidth: 700 }}>
        <h2 className="text-dark">Report Card Management</h2>
      </div>

      <div className="row g-2 align-items-center justify-content-center mb-3">
        <div className="col-auto">
          <label htmlFor="schoolYearSelect" className="col-form-label">
            School year
          </label>
        </div>
        <div className="col-auto">
          <select
            id="schoolYearSelect"
            className="form-select form-select-sm"
            style={{ minWidth: 200 }}
            value={schoolYear}
            onChange={(e) => {
              const y = e.target.value
              setSchoolYear(y)
              loadMeta(y, semester).catch(() => {})
            }}
          >
            {years.map((y) => (
              <option key={y} value={y}>
                {y}
              </option>
            ))}
          </select>
        </div>
        <div className="col-auto">
          <label htmlFor="semesterSelect" className="col-form-label">
            Semester
          </label>
        </div>
        <div className="col-auto">
          <select
            id="semesterSelect"
            className="form-select form-select-sm"
            style={{ minWidth: 160 }}
            value={semester}
            onChange={(e) => {
              const s = e.target.value
              setSemester(s)
              loadMeta(schoolYear, s).catch(() => {})
            }}
          >
            {semesters.map((s) => (
              <option key={s} value={s}>
                {s}
              </option>
            ))}
          </select>
        </div>
        <div className="col-auto">
          <label htmlFor="reportDate" className="col-form-label">
            Report Date
          </label>
        </div>
        <div className="col-auto">
          <input
            type="date"
            id="reportDate"
            className="form-control form-control-sm"
            style={{ minWidth: 170 }}
            value={reportDate}
            onChange={(e) => setReportDate(e.target.value)}
          />
        </div>
      </div>

      <div className="mb-3">
        <div className="row align-items-end justify-content-center g-2">
          <div className="col-md-4 mb-2">
            <label htmlFor="class_section_id">Select Class Section</label>
            <select
              className="form-control"
              id="class_section_id"
              value={classId}
              onChange={(e) => setClassId(e.target.value)}
            >
              {classOptions.map((c) => {
                const id = String(c.class_section_id ?? c.id ?? '')
                return (
                  <option key={id} value={id}>
                    {c.class_section_name ?? id}
                  </option>
                )
              })}
            </select>
          </div>
          <div className="col-md-4 d-flex gap-2 mb-2 justify-content-center flex-wrap">
            <button type="button" className="btn btn-primary" onClick={onViewClass}>
              View All Reports
            </button>
            <button type="button" className="btn btn-secondary" onClick={printClass}>
              Print
            </button>
            <button type="button" className="btn btn-success" onClick={downloadClass}>
              Download
            </button>
          </div>
        </div>
      </div>

      <div className="mb-3">
        <div className="row align-items-end justify-content-center g-2">
          <div className="col-md-4 mb-2">
            <label htmlFor="student_id">Select Student</label>
            <select
              className="form-control"
              id="student_id"
              value={studentId}
              onChange={(e) => setStudentId(e.target.value)}
            >
              {studentOptions.length === 0 ? (
                <option value="">No students found</option>
              ) : (
                studentOptions.map((s) => {
                  const label = `${s.firstname ?? ''} ${s.lastname ?? ''}${s.class_section_name ? ` — ${s.class_section_name}` : ''}`
                  return (
                    <option key={String(s.id)} value={String(s.id)}>
                      {label.trim() || String(s.id)}
                    </option>
                  )
                })
              )}
            </select>
          </div>
          <div className="col-md-4 d-flex gap-2 mb-2 justify-content-center flex-wrap">
            <button type="button" className="btn btn-primary" onClick={onViewStudent}>
              View Report
            </button>
            <button type="button" className="btn btn-secondary" onClick={printStudent}>
              Print
            </button>
            <button type="button" className="btn btn-success" onClick={downloadStudent}>
              Download
            </button>
          </div>
        </div>
        <div className="text-muted small text-center" id="ackStatus">
          {ackText}
        </div>
      </div>

      <div className="card shadow-sm mb-3">
        <div className="card-body">
          <div className="d-flex flex-wrap gap-2 align-items-center justify-content-between">
            <div>
              <h5 className="mb-1">Report Card Completeness</h5>
              <div className="text-muted small">
                Check grades, comments, and final scores for the selected class.
              </div>
            </div>
            <button type="button" className="btn btn-outline-primary btn-sm" onClick={checkCompleteness}>
              Check Completeness
            </button>
          </div>
          <div className={`small mt-2 ${completenessError ? 'text-danger' : 'text-muted'}`}>
            {completenessStatus}
          </div>
          <div className="mt-2">{completenessSummary}</div>
          {completenessWrapOpen ? (
            <div className="table-responsive mt-3">
              <table className="table table-sm table-bordered align-middle mb-0">
                <thead className="table-light">
                  <tr>
                    <th style={{ width: '28%' }}>Student</th>
                    <th style={{ width: '15%' }}>Status</th>
                    <th>Missing</th>
                    <th>Warnings</th>
                    <th style={{ width: '16%' }}>Viewed</th>
                    <th style={{ width: '16%' }}>Signed</th>
                  </tr>
                </thead>
                <tbody>
                  {completenessRows.map((row, idx) => {
                    const missing = Array.isArray(row.missing) ? (row.missing as string[]) : []
                    const warningsList = Array.isArray(row.warnings) ? (row.warnings as string[]) : []
                    const isComplete = Boolean(row.complete)
                    const status = isComplete
                      ? warningsList.length
                        ? 'Complete (warnings)'
                        : 'Complete'
                      : 'Missing data'
                    return (
                      <tr key={idx} className={!isComplete ? 'table-warning' : undefined}>
                        <td>{String(row.name ?? 'N/A')}</td>
                        <td>{status}</td>
                        <td>{missing.length ? missing.join(', ') : 'None'}</td>
                        <td>{warningsList.length ? warningsList.join(', ') : 'None'}</td>
                        <td>{row.viewed_at ? String(row.viewed_at) : 'Not viewed'}</td>
                        <td>
                          {row.signed_at
                            ? `${String(row.signed_at)}${row.signed_name ? ` (${String(row.signed_name)})` : ''}`
                            : 'Not signed'}
                        </td>
                      </tr>
                    )
                  })}
                </tbody>
              </table>
            </div>
          ) : null}
        </div>
      </div>

      {showStudentFrame ? (
        <iframe
          title="Student report card"
          srcDoc={studentHtml}
          style={{ width: '100%', height: 600, border: '1px solid #ccc' }}
          sandbox="allow-same-origin allow-scripts allow-popups allow-popups-to-escape-sandbox"
        />
      ) : null}
      {showClassFrame ? (
        <iframe
          title="Class report cards"
          srcDoc={classHtml}
          style={{ width: '100%', height: 600, border: '1px solid #ccc' }}
          sandbox="allow-same-origin allow-scripts allow-popups allow-popups-to-escape-sandbox"
        />
      ) : null}
    </div>
  )
}
