import { type FormEvent, useEffect, useMemo, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { fetchBelowSixty, postBelowSixtyStatus } from '../../api/grading'
import { fetchGradingOverview } from '../../api/session'
import { AcademicFilterBar } from '../discounts/AcademicFilterBar'
import {
  GRADING_BELOW_SIXTY_DECISIONS_PATH,
  GRADING_BELOW_SIXTY_EMAIL_EDITOR_PATH,
  GRADING_PATH,
  GRADING_SCHEDULE_MEETING_PATH,
} from './gradingPaths'

type BelowRow = Record<string, unknown>

function displayScore(value: unknown): string {
  if (value === null || value === undefined || value === '') return '—'
  if (typeof value === 'number' && Number.isFinite(value)) return value.toFixed(2)
  return String(value)
}

/** CI `grading/below_sixty.php` */
export function BelowSixtyPage() {
  type BelowSixtySortKey =
    | 'student_name'
    | 'class_section_name'
    | 'homework_avg'
    | 'project_avg'
    | 'participation_score'
    | 'test_avg'
    | 'ptap_score'
    | 'attendance_score'
    | 'midterm_exam_score'
    | 'semester_score'
  const [searchParams, setSearchParams] = useSearchParams()
  const semester = searchParams.get('semester') ?? ''
  const schoolYear = searchParams.get('school_year') ?? ''
  const qs = searchParams.toString()

  const [rows, setRows] = useState<BelowRow[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [sortConfig, setSortConfig] = useState<{
    key: BelowSixtySortKey
    direction: 'asc' | 'desc'
  }>({
    key: 'student_name',
    direction: 'asc',
  })

  useEffect(() => {
    if (semester && schoolYear) return
    let cancelled = false
    ;(async () => {
      try {
        const overview = await fetchGradingOverview({
          semester: semester || null,
          schoolYear: schoolYear || null,
        })
        if (cancelled) return
        const next = new URLSearchParams(searchParams)
        if (!semester && (overview.semester ?? '').trim() !== '') {
          next.set('semester', String(overview.semester))
        }
        if (!schoolYear && (overview.school_year ?? '').trim() !== '') {
          next.set('school_year', String(overview.school_year))
        }
        setSearchParams(next, { replace: true })
      } catch (e) {
        if (!cancelled) {
          setError(e instanceof ApiHttpError ? e.message : 'Unable to determine the current grading term.')
          setLoading(false)
        }
      }
    })()
    return () => {
      cancelled = true
    }
  }, [schoolYear, searchParams, semester, setSearchParams])

  const load = () => {
    if (!semester || !schoolYear) {
      setLoading(false)
      return
    }
    setLoading(true)
    fetchBelowSixty(searchParams)
      .then((data) => {
        const raw =
          data && typeof data === 'object' && 'rows' in data && Array.isArray((data as { rows: unknown }).rows)
            ? (data as { rows: BelowRow[] }).rows
            : Array.isArray(data)
              ? (data as BelowRow[])
              : []
        setRows(raw)
        setError(null)
      })
      .catch((e: unknown) => {
        setError(e instanceof ApiHttpError ? e.message : 'Unable to load below-60 summary.')
      })
      .finally(() => setLoading(false))
  }

  useEffect(() => {
    load()
  }, [searchParams])

  const semLabel =
    semester.toLowerCase() === 'fall' ? '1st Semester Score' : 'Semester Score'

  async function onStatusSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault()
    const fd = new FormData(e.currentTarget)
    try {
      await postBelowSixtyStatus({
        student_id: fd.get('student_id'),
        semester: fd.get('semester'),
        school_year: fd.get('school_year'),
        status: fd.get('status'),
        note: fd.get('note'),
      })
      load()
    } catch (err: unknown) {
      setError(err instanceof ApiHttpError ? err.message : 'Status update failed.')
    }
  }

  function requestSort(key: BelowSixtySortKey) {
    setSortConfig((prev) =>
      prev.key === key
        ? { key, direction: prev.direction === 'asc' ? 'desc' : 'asc' }
        : { key, direction: 'asc' },
    )
  }

  function sortArrow(key: BelowSixtySortKey) {
    if (sortConfig.key !== key) return '↕'
    return sortConfig.direction === 'asc' ? '↑' : '↓'
  }

  const displayedRows = useMemo(() => {
    return [...rows].sort((left, right) => {
      const direction = sortConfig.direction === 'asc' ? 1 : -1
      if (sortConfig.key === 'student_name') {
        const leftName = `${String(left.firstname ?? '')} ${String(left.lastname ?? '')}`.trim()
        const rightName = `${String(right.firstname ?? '')} ${String(right.lastname ?? '')}`.trim()
        return leftName.localeCompare(rightName, undefined, { sensitivity: 'base' }) * direction
      }

      const numericKeys = new Set<BelowSixtySortKey>([
        'homework_avg',
        'project_avg',
        'participation_score',
        'test_avg',
        'ptap_score',
        'attendance_score',
        'midterm_exam_score',
        'semester_score',
      ])

      if (numericKeys.has(sortConfig.key)) {
        const a = Number(left[sortConfig.key] ?? Number.NEGATIVE_INFINITY)
        const b = Number(right[sortConfig.key] ?? Number.NEGATIVE_INFINITY)
        return (a - b) * direction
      }

      const a = String(left[sortConfig.key] ?? '')
      const b = String(right[sortConfig.key] ?? '')
      return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }) * direction
    })
  }, [rows, sortConfig])

  return (
    <div className="container-fluid">
      <h2 className="text-center mt-4 mb-4">Below 60 Summary</h2>
      <AcademicFilterBar />

      <div className="d-flex justify-content-between align-items-center mb-3 flex-wrap gap-2">
        <div className="text-muted">
          {semester ? `${semester} • ` : ''}
          {schoolYear}
        </div>
        <div className="d-flex gap-2 flex-wrap">
          <Link className="btn btn-outline-primary btn-sm" to={`${GRADING_BELOW_SIXTY_DECISIONS_PATH}?school_year=${encodeURIComponent(schoolYear)}`}>
            School Year Decisions
          </Link>
          <Link className="btn btn-outline-secondary btn-sm" to={`${GRADING_PATH}${qs ? `?${qs}` : ''}`}>
            Back to Grading
          </Link>
        </div>
      </div>

      {error ? <div className="alert alert-danger">{error}</div> : null}
      {loading ? <p className="text-muted">Loading…</p> : null}

      {!loading && rows.length === 0 ? (
        <div className="alert alert-success text-center d-inline-block">
          No students below 60 for this selection.
        </div>
      ) : null}

      {!loading && rows.length > 0 ? (
        <div className="table-responsive">
          <table className="table table-bordered table-striped align-middle">
            <thead className="table-light">
              <tr>
                <th role="button" style={{ cursor: 'pointer' }} onClick={() => requestSort('student_name')}>Student Name {sortArrow('student_name')}</th>
                <th role="button" style={{ cursor: 'pointer' }} onClick={() => requestSort('class_section_name')}>Section {sortArrow('class_section_name')}</th>
                <th role="button" style={{ cursor: 'pointer' }} onClick={() => requestSort('homework_avg')}>Hwk Avg {sortArrow('homework_avg')}</th>
                <th role="button" style={{ cursor: 'pointer' }} onClick={() => requestSort('project_avg')}>Project Avg {sortArrow('project_avg')}</th>
                <th role="button" style={{ cursor: 'pointer' }} onClick={() => requestSort('participation_score')}>Participation {sortArrow('participation_score')}</th>
                <th role="button" style={{ cursor: 'pointer' }} onClick={() => requestSort('test_avg')}>Test Avg {sortArrow('test_avg')}</th>
                <th role="button" style={{ cursor: 'pointer' }} onClick={() => requestSort('ptap_score')}>PTAP Score {sortArrow('ptap_score')}</th>
                <th role="button" style={{ cursor: 'pointer' }} onClick={() => requestSort('attendance_score')}>Attendance {sortArrow('attendance_score')}</th>
                <th role="button" style={{ cursor: 'pointer' }} onClick={() => requestSort('midterm_exam_score')}>Midterm Score {sortArrow('midterm_exam_score')}</th>
                <th role="button" style={{ cursor: 'pointer' }} onClick={() => requestSort('semester_score')}>{semLabel} {sortArrow('semester_score')}</th>
                <th>Status</th>
                <th>Email Parent</th>
                <th>Schedule Meeting</th>
              </tr>
            </thead>
            <tbody>
              {displayedRows.map((row, i) => {
                const sid = Number(row.student_id ?? 0)
                const first = String(row.firstname ?? '')
                const last = String(row.lastname ?? '')
                const studentName = `${first} ${last}`.trim() || 'N/A'
                const scoreRaw = row.semester_score
                const scoreVal =
                  typeof scoreRaw === 'number'
                    ? scoreRaw
                    : typeof scoreRaw === 'string' && scoreRaw !== ''
                      ? Number(scoreRaw)
                      : null
                let rowClass = ''
                if (scoreVal !== null && Number.isFinite(scoreVal)) {
                  if (scoreVal < 50) rowClass = 'table-danger'
                  else if (scoreVal < 60) rowClass = 'table-warning'
                }
                const isClosed = String(row.status ?? 'Open') === 'Closed'
                const emailTo = `${GRADING_BELOW_SIXTY_EMAIL_EDITOR_PATH}?student_id=${sid}&semester=${encodeURIComponent(semester)}&school_year=${encodeURIComponent(schoolYear)}`
                const schedTo = `${GRADING_SCHEDULE_MEETING_PATH}?student_id=${sid}&semester=${encodeURIComponent(semester)}&school_year=${encodeURIComponent(schoolYear)}`

                return (
                  <tr key={sid || i} className={rowClass}>
                    <td>{studentName}</td>
                    <td>{String(row.class_section_name ?? '—')}</td>
                    <td className="text-center">{displayScore(row.homework_avg)}</td>
                    <td className="text-center">{displayScore(row.project_avg)}</td>
                    <td className="text-center">{displayScore(row.participation_score)}</td>
                    <td className="text-center">{displayScore(row.test_avg)}</td>
                    <td className="text-center">{displayScore(row.ptap_score)}</td>
                    <td className="text-center">{displayScore(row.attendance_score)}</td>
                    <td className="text-center">{displayScore(row.midterm_exam_score)}</td>
                    <td className="text-center">{displayScore(row.semester_score)}</td>
                    <td className="text-center">
                      <form
                        key={`${sid}-${String(row.status ?? 'Open')}-${String(row.note ?? '')}`}
                        className="d-flex align-items-center gap-2 justify-content-center flex-wrap"
                        onSubmit={(ev) => void onStatusSubmit(ev)}
                      >
                        <input type="hidden" name="student_id" value={sid} />
                        <input type="hidden" name="semester" value={semester} />
                        <input type="hidden" name="school_year" value={schoolYear} />
                        <select
                          name="status"
                          className="form-select form-select-sm"
                          style={{ width: 110 }}
                          defaultValue={String(row.status ?? 'Open')}
                        >
                          <option value="Open">Open</option>
                          <option value="Closed">Closed</option>
                        </select>
                        <input
                          type="text"
                          name="note"
                          className="form-control form-control-sm"
                          style={{ width: 140 }}
                          placeholder="Note"
                          defaultValue={String(row.note ?? '')}
                        />
                        <button type="submit" className="btn btn-sm btn-outline-secondary">
                          Update
                        </button>
                      </form>
                    </td>
                    <td className="text-center">
                      {isClosed ? (
                        <button type="button" className="btn btn-sm btn-secondary" disabled>
                          Send Email
                        </button>
                      ) : (
                        <Link className="btn btn-sm btn-outline-primary" to={emailTo}>
                          Send Email
                        </Link>
                      )}
                    </td>
                    <td className="text-center">
                      {isClosed ? (
                        <button type="button" className="btn btn-sm btn-secondary" disabled>
                          Schedule
                        </button>
                      ) : (
                        <Link className="btn btn-sm btn-outline-secondary" to={schedTo}>
                          Schedule
                        </Link>
                      )}
                    </td>
                  </tr>
                )
              })}
            </tbody>
          </table>
        </div>
      ) : null}
    </div>
  )
}
