import { useEffect, useLayoutEffect, useMemo, useState } from 'react'
import { Link, useParams, useSearchParams } from 'react-router-dom'
import { fetchStudentScoreCard } from '../../api/session'
import type { StudentScoreCardRow, StudentScoreCardStudent } from '../../api/types'
import { reportCardStudentUrl } from '../../api/printables'

function formatScore(val: unknown): string {
  if (val === null || val === undefined || val === '') return 'N/A'
  if (typeof val === 'number' && Number.isFinite(val)) {
    let out = val.toFixed(1)
    if (out.endsWith('.0')) out = out.slice(0, -2)
    return out
  }
  if (typeof val === 'string' && val.trim() !== '' && !Number.isNaN(Number(val))) {
    const n = Number(val)
    let out = n.toFixed(1)
    if (out.endsWith('.0')) out = out.slice(0, -2)
    return out
  }
  return String(val)
}

function labelFromType(type: string): string {
  const map: Record<string, string> = {
    midterm: 'Midterm',
    final: 'Final',
    ptap: 'PTAP',
    attendance: 'Attendance',
    general: 'General',
  }
  const key = type.trim().toLowerCase()
  return map[key] ?? (key ? key.charAt(0).toUpperCase() + key.slice(1) : type)
}

export function StudentScoreCardPage() {
  const { studentId } = useParams()
  const [searchParams] = useSearchParams()
  const id = Number(studentId)
  const [student, setStudent] = useState<StudentScoreCardStudent | null>(null)
  const [rows, setRows] = useState<StudentScoreCardRow[]>([])
  const [error, setError] = useState<string | null>(null)

  const highlightYear = searchParams.get('school_year')?.trim() ?? ''
  const highlightSem = searchParams.get('semester')?.trim().toLowerCase() ?? ''

  useEffect(() => {
    if (!id) return
    let cancelled = false
    ;(async () => {
      try {
        const data = await fetchStudentScoreCard(id)
        if (cancelled) return
        setStudent(data.student)
        setRows(data.rows ?? [])
        setError(null)
      } catch (e) {
        if (!cancelled) setError(e instanceof Error ? e.message : 'Unable to load score card.')
      }
    })()
    return () => {
      cancelled = true
    }
  }, [id])

  useLayoutEffect(() => {
    if (!highlightYear || !highlightSem || rows.length === 0) return
    const idx = rows.findIndex((r) => {
      const y = String(r.school_year ?? '').trim()
      const s = String(r.semester ?? '').trim().toLowerCase()
      return y === highlightYear && s === highlightSem
    })
    if (idx < 0) return
    window.requestAnimationFrame(() => {
      document.getElementById(`score-card-row-${idx}`)?.scrollIntoView({ block: 'center', behavior: 'smooth' })
    })
  }, [highlightYear, highlightSem, rows])

  const yearCounts = useMemo(() => {
    const m: Record<string, number> = {}
    for (const r of rows) {
      const y = String(r.school_year ?? '')
      m[y] = (m[y] ?? 0) + 1
    }
    return m
  }, [rows])

  const firstRowIndexByYear = useMemo(() => {
    const map = new Map<string, number>()
    rows.forEach((row, idx) => {
      const y = String(row.school_year ?? '')
      if (!map.has(y)) map.set(y, idx)
    })
    return map
  }, [rows])

  const yearStripe = useMemo(() => {
    const keyToAlt: Record<string, number> = {}
    let order = 0
    return rows.map((row) => {
      const y = String(row.school_year ?? '')
      if (y === '') return 0
      if (keyToAlt[y] === undefined) {
        keyToAlt[y] = order % 2
        order += 1
      }
      return keyToAlt[y]
    })
  }, [rows])

  const heading = student
    ? `${student.firstname ?? ''} ${student.lastname ?? ''}`.trim()
    : ''

  return (
    <div className="w-100 py-3 px-3">
      <style>{`
        .score-card-table { margin-top: 4px; }
        .score-card-table thead th { position: static; }
        .score-card-table tbody tr.score-year-alt-0 > * { background-color: #fff1e6 !important; }
        .score-card-table tbody tr.score-year-alt-1 > * { background-color: #e8f1ff !important; }
        .score-card-table th, .score-card-table td { white-space: nowrap; }
      `}</style>
      <div className="d-flex align-items-center justify-content-between flex-wrap gap-2 mb-3">
        <div>
          <h2 className="mb-0">Student Score Card</h2>
          <div className="text-muted small">
            {heading}
            {student?.school_id ? ` - ID: ${student.school_id}` : null}
          </div>
        </div>
        <Link className="btn btn-outline-secondary" to="/app/student/score-card/list">
          Back
        </Link>
      </div>

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

      {!error && rows.length === 0 && student ? (
        <div className="alert alert-warning">No semester scores found for this student.</div>
      ) : null}

      {rows.length > 0 && student ? (
        <div className="card shadow-sm">
          <div className="card-header d-flex justify-content-between align-items-center">
            <strong>Scores By Year and Semester</strong>
          </div>
          <div className="card-body table-responsive pt-2">
            <table
              className="table table-striped table-hover align-middle score-card-table no-mgmt-sticky"
              data-no-mgmt-sticky="1"
            >
              <thead className="table-light">
                <tr>
                  <th>School Year</th>
                  <th>Year Score</th>
                  <th>Grade</th>
                  <th>Semester</th>
                  <th>Homework Avg</th>
                  <th>Project Avg</th>
                  <th>Participation</th>
                  <th>Test/Quiz Avg</th>
                  <th>Attendance</th>
                  <th>PTAP</th>
                  <th>Midterm</th>
                  <th>Semester Score</th>
                  <th>Comments</th>
                </tr>
              </thead>
              <tbody>
                {rows.map((row, i) => {
                  const sem = (row.semester ?? '').trim().toLowerCase()
                  const semLabel = sem !== '' ? sem.charAt(0).toUpperCase() + sem.slice(1) : 'N/A'
                  const semParam = semLabel !== 'N/A' ? semLabel : ''
                  const testQuiz = row.quiz_avg ?? row.test_avg ?? null
                  const comments = row.comments ?? {}
                  const yearKey = String(row.school_year ?? '')
                  const showYearCells = firstRowIndexByYear.get(yearKey) === i
                  const rowspan = yearCounts[yearKey] ?? 1
                  const rowAlt = yearStripe[i] ?? 0
                  const pdfUrl =
                    semParam && yearKey && student.id
                      ? reportCardStudentUrl(student.id, {
                          school_year: yearKey,
                          semester: semParam,
                          download: true,
                        })
                      : null

                  const isHighlight =
                    highlightYear !== '' &&
                    highlightSem !== '' &&
                    yearKey === highlightYear &&
                    sem === highlightSem

                  return (
                    <tr
                      key={`${yearKey}-${sem}-${i}`}
                      id={`score-card-row-${i}`}
                      className={`score-year-alt-${rowAlt}${isHighlight ? ' table-warning' : ''}`}
                    >
                      {showYearCells ? (
                        <>
                          <td rowSpan={rowspan}>{row.school_year ?? 'N/A'}</td>
                          <td rowSpan={rowspan}>{formatScore(row.year_score ?? null)}</td>
                          <td rowSpan={rowspan}>{row.class_section_name ?? '—'}</td>
                        </>
                      ) : null}
                      <td>
                        {pdfUrl ? (
                          <a
                            href={pdfUrl}
                            target="_blank"
                            rel="noopener noreferrer"
                            className="d-inline-flex align-items-center gap-1"
                          >
                            <i className="bi bi-file-earmark-pdf" aria-hidden />
                            <span>{semLabel}</span>
                          </a>
                        ) : (
                          semLabel
                        )}
                      </td>
                      <td>{formatScore(row.homework_avg ?? null)}</td>
                      <td>{formatScore(row.project_avg ?? null)}</td>
                      <td>{formatScore(row.participation_score ?? null)}</td>
                      <td>{formatScore(testQuiz)}</td>
                      <td>{formatScore(row.attendance_score ?? null)}</td>
                      <td>{formatScore(row.ptap_score ?? null)}</td>
                      <td>{formatScore(row.midterm_exam_score ?? null)}</td>
                      <td>{formatScore(row.semester_score ?? null)}</td>
                      <td style={{ minWidth: 240 }}>
                        {comments && typeof comments === 'object' && Object.keys(comments).length > 0 ? (
                          Object.entries(comments).map(([type, comment]) => (
                            <details key={type} className="mb-1">
                              <summary className="small fw-semibold">{labelFromType(type)}</summary>
                              <div className="small text-muted mt-1">{String(comment)}</div>
                            </details>
                          ))
                        ) : (
                          <span className="text-muted">N/A</span>
                        )}
                      </td>
                    </tr>
                  )
                })}
              </tbody>
            </table>
          </div>
        </div>
      ) : null}
    </div>
  )
}
