import { type FormEvent, useEffect, useMemo, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { useSchoolYearOptions } from '../../hooks/useSchoolYearOptions'
import { fetchScorePrediction, type ScorePredictionStudent } from '../../api/scoreAnalysis'
import { FailRiskLabel, StatusBadge, TrophyChanceLabel } from './scorePredictionUi'

function str(v: unknown): string {
  return v == null ? '' : String(v)
}

export function ScorePredictionPage() {
  const [searchParams, setSearchParams] = useSearchParams()
  const schoolYearParam = searchParams.get('school_year') ?? ''
  const classSectionParam = searchParams.get('class_section_id') ?? ''

  const [data, setData] = useState<Awaited<ReturnType<typeof fetchScorePrediction>> | null>(null)
  const [error, setError] = useState<string | null>(null)
  const { options, selectedYear } = useSchoolYearOptions({
    preferredYear: schoolYearParam,
  })

  useEffect(() => {
    setError(null)
    fetchScorePrediction({
      school_year: schoolYearParam || undefined,
      class_section_id: classSectionParam || undefined,
    })
      .then(setData)
      .catch((e: unknown) =>
        setError(e instanceof ApiHttpError ? e.message : 'Failed to load report.'),
      )
  }, [schoolYearParam, classSectionParam])

  const sectionMap = useMemo(() => {
    const m: Record<string, string> = {}
    for (const sec of data?.classSections ?? []) {
      const id = String(sec.class_section_id ?? '')
      m[id] = String(sec.class_section_name ?? `Section ${id}`)
    }
    return m
  }, [data?.classSections])

  const students = (data?.students ?? []) as ScorePredictionStudent[]

  const {
    statusCounts,
    riskBuckets,
    trophyCounts,
    totalTrophies,
    totalStudents,
    passRate,
    failRate,
    pendingCount,
    undeterminedRate,
  } = useMemo(() => {
    const statusCounts = {
      Passed: 0,
      Failed: 0,
      'Can pass': 0,
      'May fail': 0,
      Undetermined: 0,
    }
    const riskBuckets: Record<string, number> = {
      Low: 0,
      Medium: 0,
      High: 0,
      'Unlikely to pass': 0,
      'New student': 0,
    }
    const trophyCounts: Record<string, number> = {}
    let totalTrophies = 0

    for (const s of students) {
      const status = str(s.status) || 'Undetermined'
      if (status in statusCounts) statusCounts[status as keyof typeof statusCounts]++
      else statusCounts.Undetermined++

      const risk = str(s.failure_risk) || 'New student'
      if (risk in riskBuckets) riskBuckets[risk]++
      else riskBuckets['New student']++

      if (s.trophy_awarded) {
        const cid = String(s.class_section_id ?? '')
        trophyCounts[cid] = (trophyCounts[cid] ?? 0) + 1
        totalTrophies++
      }
    }

    const totalStudents = Object.values(statusCounts).reduce((a, b) => a + b, 0)
    const passRate = totalStudents > 0 ? Math.round((statusCounts.Passed / totalStudents) * 1000) / 10 : 0
    const failRate = totalStudents > 0 ? Math.round((statusCounts.Failed / totalStudents) * 1000) / 10 : 0
    const pendingCount = statusCounts.Undetermined + statusCounts['Can pass'] + statusCounts['May fail']
    const undeterminedRate =
      totalStudents > 0 ? Math.round((pendingCount / totalStudents) * 1000) / 10 : 0

    return {
      statusCounts,
      riskBuckets,
      trophyCounts,
      totalTrophies,
      totalStudents,
      passRate,
      failRate,
      pendingCount,
      undeterminedRate,
    }
  }, [students])

  const trophyOrderCids = useMemo(() => {
    const keys = Object.keys(trophyCounts)
    keys.sort((a, b) => {
      const na = sectionMap[a] ?? a
      const nb = sectionMap[b] ?? b
      return na.localeCompare(nb, undefined, { sensitivity: 'base' })
    })
    return keys
  }, [trophyCounts, sectionMap])

  function applyFilter(e: FormEvent<HTMLFormElement>) {
    e.preventDefault()
    const fd = new FormData(e.currentTarget)
    const next = new URLSearchParams()
    const sy = String(fd.get('school_year') ?? '')
    const cs = String(fd.get('class_section_id') ?? '')
    if (sy) next.set('school_year', sy)
    if (cs) next.set('class_section_id', cs)
    setSearchParams(next)
  }

  const syDefault = data?.school_year ?? schoolYearParam
  const schoolYearOptions = options.length > 0 ? options : [{ value: selectedYear, label: selectedYear }]

  const statusColors = ['#198754', '#dc3545', '#0d6efd', '#ffc107', '#6c757d']
  const riskColors = ['#198754', '#ffc107', '#dc3545', '#6610f2', '#adb5bd']

  return (
    <div className="container-fluid">
      <h2 className="text-center mt-4 mb-3">Student Success & Risk Report</h2>

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

      <div className="mb-4 text-center">
        <p className="text-muted small mb-1">Active Students</p>
        <div className="display-4 fw-semibold">{totalStudents}</div>
        <p className="text-muted small mb-0">
          Reflects only currently active students, so removals update the count instantly.
        </p>
      </div>

      <form method="get" className="row g-3 mb-4 align-items-end" onSubmit={applyFilter}>
        <div className="col-md-6 col-lg-4">
          <label htmlFor="school_year" className="form-label">
            School Year
          </label>
          <select className="form-select" id="school_year" name="school_year" defaultValue={syDefault || selectedYear}>
            {schoolYearOptions.map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        </div>
        <div className="col-md-6 col-lg-4">
          <label htmlFor="class_section_id" className="form-label">
            Class Section
          </label>
          <div className="input-group">
            <select
              className="form-select"
              name="class_section_id"
              id="class_section_id"
              defaultValue={String(data?.selectedClassSectionId ?? classSectionParam)}
            >
              <option value="">-- All Sections --</option>
              {(data?.classSections ?? []).map((section) => (
                <option key={String(section.class_section_id)} value={String(section.class_section_id)}>
                  {String(section.class_section_name)}
                </option>
              ))}
            </select>
            <button type="submit" className="btn btn-primary">
              Filter
            </button>
          </div>
        </div>
      </form>

      <div className="row g-3 mb-4">
        <div className="col-lg-4">
          <div className="card shadow-sm h-100">
            <div className="card-header py-2 d-flex justify-content-between align-items-center">
              <strong>Active Student Snapshot</strong>
              <span className="badge bg-primary">{totalStudents} active</span>
            </div>
            <div className="card-body">
              <div className="d-flex flex-wrap gap-3">
                <div className="flex-fill">
                  <div className="small text-muted">Pass rate</div>
                  <div className="fs-3 text-success fw-semibold">{passRate}%</div>
                  <div className="text-muted small">{statusCounts.Passed} students</div>
                </div>
                <div className="flex-fill">
                  <div className="small text-muted">Failing</div>
                  <div className="fs-4 text-danger fw-semibold">{statusCounts.Failed}</div>
                  <div className="text-muted small">{failRate}% of roster</div>
                </div>
                <div className="flex-fill">
                  <div className="small text-muted">Pending / no data</div>
                  <div className="fs-4 text-secondary fw-semibold">{pendingCount}</div>
                  <div className="text-muted small">{undeterminedRate}% of roster</div>
                </div>
              </div>
              <hr />
              <p className="mb-1 small text-muted">Analyst notes</p>
              <ul className="mb-0 small">
                <li>
                  Focus on {riskBuckets.High} high-risk students; prioritize their action plans.
                </li>
                <li>
                  {statusCounts.Failed} students are currently failing—pair them with tutoring or parental
                  outreach.
                </li>
                <li>{totalTrophies} trophy-eligible students; celebrate them to boost morale.</li>
              </ul>
            </div>
          </div>
        </div>
        <div className="col-lg-4">
          <div className="card shadow-sm h-100">
            <div className="card-header py-2">
              <strong>Pass vs Fail</strong>
            </div>
            <div className="card-body">
              <div className="small text-muted mb-2">Distribution</div>
              <div className="d-flex rounded overflow-hidden" style={{ height: 28 }}>
                {(['Passed', 'Failed', 'Can pass', 'May fail', 'Undetermined'] as const).map((k, i) => {
                  const v = statusCounts[k]
                  const pct = totalStudents > 0 ? (v / totalStudents) * 100 : 0
                  return (
                    <div
                      key={k}
                      title={`${k}: ${v}`}
                      style={{
                        width: `${pct}%`,
                        backgroundColor: statusColors[i],
                        minWidth: v > 0 ? 4 : 0,
                      }}
                    />
                  )
                })}
              </div>
              <div className="d-flex flex-wrap gap-2 mt-2 small">
                {(['Passed', 'Failed', 'Can pass', 'May fail', 'Undetermined'] as const).map((k, i) => (
                  <span key={k}>
                    <span
                      className="d-inline-block rounded-circle me-1 align-middle"
                      style={{
                        width: 10,
                        height: 10,
                        backgroundColor: statusColors[i],
                      }}
                    />
                    {k}: {statusCounts[k]}
                  </span>
                ))}
              </div>
            </div>
          </div>
        </div>
        <div className="col-lg-4">
          <div className="card shadow-sm h-100">
            <div className="card-header py-2">
              <strong>Fail Risk Mix</strong>
            </div>
            <div className="card-body">
              <div className="d-flex flex-column gap-2">
                {(['Low', 'Medium', 'High', 'Unlikely to pass', 'New student'] as const).map((k, i) => (
                  <div key={k} className="d-flex align-items-center gap-2">
                    <span className="small" style={{ width: 120 }}>
                      {k}
                    </span>
                    <div className="flex-grow-1 rounded bg-light" style={{ height: 18 }}>
                      <div
                        className="h-100 rounded"
                        style={{
                          width: `${
                            totalStudents > 0 ? Math.min(100, (riskBuckets[k] / totalStudents) * 100) : 0
                          }%`,
                          backgroundColor: riskColors[i],
                          minWidth: riskBuckets[k] > 0 ? 4 : 0,
                        }}
                      />
                    </div>
                    <span className="small text-muted" style={{ width: 36 }}>
                      {riskBuckets[k]}
                    </span>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="row mb-3">
        <div className="col-12">
          <div className="card shadow-sm">
            <div className="card-header py-2">
              <strong>Trophies Summary</strong>
            </div>
            <div className="card-body p-2">
              <div className="small text-muted mb-2">
                If a class section has no students meeting the trophy threshold, the top 3 ranked students in
                that section receive trophies.
              </div>
              <div className="table-responsive">
                <table className="table table-sm table-bordered table-striped mb-2 text-center align-middle">
                  <thead className="table-light">
                    <tr>
                      <th className="text-start">Class Section</th>
                      {trophyOrderCids.length === 0 ? (
                        <th className="text-muted fst-italic">No trophies yet.</th>
                      ) : (
                        trophyOrderCids.map((cid) => (
                          <th key={cid}>{sectionMap[cid] ?? `Section ${cid}`}</th>
                        ))
                      )}
                    </tr>
                  </thead>
                  <tbody>
                    {trophyOrderCids.length > 0 ? (
                      <>
                        <tr>
                          <th className="text-start">Trophy Counts</th>
                          {trophyOrderCids.map((cid) => (
                            <td key={cid}>{trophyCounts[cid]}</td>
                          ))}
                        </tr>
                        <tr className="fw-bold table-light">
                          <th className="text-start">Total Trophies</th>
                          <td colSpan={trophyOrderCids.length} className="text-center">
                            {totalTrophies}
                          </td>
                        </tr>
                      </>
                    ) : (
                      <tr>
                        <td colSpan={2} className="text-muted fst-italic">
                          No data available
                        </td>
                      </tr>
                    )}
                  </tbody>
                </table>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="table-responsive mb-4">
        <table className="table table-bordered table-striped align-middle w-100 score-prediction-table">
          <thead className="table-dark">
            <tr>
              <th style={{ width: 60 }}>#</th>
              <th>School ID</th>
              <th>First Name</th>
              <th>Last Name</th>
              <th>Class</th>
              <th>Fall Score</th>
              <th>Spring Score</th>
              <th>Final Average</th>
              <th>Needed for Trophy</th>
              <th>Chance to Win Trophy</th>
              <th>Needed to Pass (60+)</th>
              <th>Risk of Failing</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            {students.map((student, idx) => {
              const sid = Number(student.student_id ?? 0)
              const cid = String(student.class_section_id ?? '')
              const className = sectionMap[cid] ?? (cid ? `Section ${cid}` : '—')
              return (
                <tr key={`${str(student.school_id)}-${sid}-${idx}`}>
                  <td>{idx + 1}</td>
                  <td>{str(student.school_id)}</td>
                  <td>
                    {sid ? (
                      <Link to="/app/administrator/student_profiles" className="text-decoration-none">
                        {str(student.firstname)}
                      </Link>
                    ) : (
                      str(student.firstname)
                    )}
                  </td>
                  <td>
                    {sid ? (
                      <Link to="/app/administrator/student_profiles" className="text-decoration-none">
                        {str(student.lastname)}
                      </Link>
                    ) : (
                      str(student.lastname)
                    )}
                  </td>
                  <td>{className}</td>
                  <td>{str(student.fall_score)}</td>
                  <td>{str(student.spring_score)}</td>
                  <td>{str(student.final_average)}</td>
                  <td>{str(student.required_spring_score)}</td>
                  <td>
                    <TrophyChanceLabel risk={str(student.winning_risk)} />
                  </td>
                  <td>{str(student.required_spring_to_pass)}</td>
                  <td>
                    <FailRiskLabel risk={str(student.failure_risk)} />
                  </td>
                  <td>
                    <StatusBadge status={str(student.status)} />
                  </td>
                </tr>
              )
            })}
          </tbody>
        </table>
      </div>

      <style>{`
        .table-dark th { background-color: #343a40; color: #fff; }
        .score-prediction-table thead th,
        .score-prediction-table tbody td {
          white-space: normal;
          vertical-align: middle;
          line-height: 1.35;
          padding-top: 0.5rem;
          padding-bottom: 0.5rem;
        }
      `}</style>
    </div>
  )
}
