import { useEffect, useMemo, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { fetchHomeworkTracking } from '../../api/grading'
import { AcademicFilterBar } from '../discounts/AcademicFilterBar'
import { GRADING_PATH } from './gradingPaths'

type HomeworkTrackingTeacherRow = {
  class_section_id?: number
  class_id?: number | string | null
  class_section_name?: string | null
  teachers?: string[]
  tas?: string[]
}

type HomeworkTrackingPayload = {
  ok?: boolean
  semester?: string
  school_year?: string
  sundays?: string[]
  event_days?: Record<string, unknown>
  has_homework_by_date?: Record<string, Record<string, unknown>>
  hw_entered_at_by_date?: Record<string, Record<string, string>>
  teachers?: HomeworkTrackingTeacherRow[]
  page?: number
  total_pages?: number
}

function classLabel(classId: number) {
  if (classId === 13) return 'KG'
  if (classId === 12) return 'Youth'
  if (classId >= 1 && classId <= 11) return `Grade ${classId}`
  return `Class ${classId}`
}

function formatHeaderDate(value: string) {
  const match = /^(\d{4})-(\d{2})-(\d{2})/.exec(value)
  if (match) return `${match[2]}-${match[3]}-${match[1]}`
  return value
}

function formatEnteredDate(value?: string) {
  if (!value) return '✓'
  const match = /^(\d{4})-(\d{2})-(\d{2})/.exec(value)
  if (match) return `${match[2]}-${match[3]}-${match[1]}`
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return value
  return `${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}-${date.getFullYear()}`
}

export function HomeworkTrackingPage() {
  const [searchParams] = useSearchParams()
  const [payload, setPayload] = useState<HomeworkTrackingPayload | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    let c = false
    setLoading(true)
    fetchHomeworkTracking(searchParams)
      .then((p) => {
        if (!c) {
          setPayload(p as HomeworkTrackingPayload)
          setError(null)
        }
      })
      .catch((e: unknown) => {
        if (!c) setError(e instanceof ApiHttpError ? e.message : 'Unable to load homework tracking.')
      })
      .finally(() => {
        if (!c) setLoading(false)
      })
    return () => {
      c = true
    }
  }, [searchParams])

  const teachers = Array.isArray(payload?.teachers) ? payload.teachers : []
  const sundays = Array.isArray(payload?.sundays) ? payload.sundays : []
  const eventDays = payload?.event_days ?? {}
  const hasHomeworkByDate = payload?.has_homework_by_date ?? {}
  const enteredAtByDate = payload?.hw_entered_at_by_date ?? {}
  const semester = payload?.semester ?? searchParams.get('semester') ?? ''
  const schoolYear = payload?.school_year ?? searchParams.get('school_year') ?? ''
  const qs = searchParams.toString()
  const todayYmd = useMemo(() => new Date().toISOString().slice(0, 10), [])

  return (
    <div className="container-fluid py-3">
      <h2 className="text-center mt-2 mb-3">Homework tracking</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="small d-flex gap-2 flex-wrap">
          <span className="badge text-bg-success">Entered</span>
          <span className="badge text-bg-danger">Missing</span>
          <span className="badge text-bg-warning">No School</span>
          <span className="badge text-dark border" style={{ backgroundColor: '#e7f1ff' }}>Future</span>
        </div>
      </div>

      <div className="mb-3">
        <Link className="btn btn-outline-secondary btn-sm" to={`${GRADING_PATH}${qs ? `?${qs}` : ''}`}>
          Grading hub
        </Link>
      </div>

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

      {!loading && teachers.length === 0 ? (
        <div className="alert alert-light border">No rows returned for this filter.</div>
      ) : null}

      {!loading && teachers.length > 0 ? (
        <div className="table-responsive">
          <table className="table table-bordered align-middle">
            <thead className="table-light">
              <tr>
                <th>Grade</th>
                <th style={{ minWidth: 300 }}>Teacher &amp; TAs</th>
                <th className="text-center">HW Submitted</th>
                {sundays.map((date) => {
                  const isEventDay = Boolean(eventDays[date])
                  const isFuture = date > todayYmd
                  return (
                    <th
                      key={date}
                      className={`text-center${isEventDay ? ' bg-warning' : ''}`}
                      style={isFuture && !isEventDay ? { backgroundColor: '#e7f1ff' } : undefined}
                      title={date}
                    >
                      {formatHeaderDate(date)}
                    </th>
                  )
                })}
              </tr>
            </thead>
            <tbody>
              {teachers.map((row, index) => {
                const classId = Number(row.class_id ?? 0)
                const sectionId = Number(row.class_section_id ?? 0)
                const sectionName = row.class_section_name ?? ''
                const teacherNames = Array.isArray(row.teachers) ? row.teachers : []
                const taNames = Array.isArray(row.tas) ? row.tas : []
                const submissionCount = Object.values(hasHomeworkByDate[String(sectionId)] ?? {}).filter(Boolean).length

                return (
                  <tr key={`${sectionId || index}`}>
                    <td>
                      {classLabel(classId)}
                      {sectionName ? <div className="text-muted small">Section: {sectionName}</div> : null}
                    </td>
                    <td style={{ minWidth: 300 }}>
                      <div><strong>Teacher{teacherNames.length > 1 ? 's' : ''}:</strong> {teacherNames.length > 0 ? teacherNames.join(', ') : 'N/A'}</div>
                      <div><strong>TA{taNames.length !== 1 ? 's' : ''}:</strong> {taNames.length > 0 ? taNames.join(', ') : '—'}</div>
                    </td>
                    <td className="text-center">{submissionCount}</td>
                    {sundays.map((date) => {
                      const isEventDay = Boolean(eventDays[date])
                      const isFuture = date > todayYmd
                      const ok = Boolean(hasHomeworkByDate[String(sectionId)]?.[date])
                      const rawDate = enteredAtByDate[String(sectionId)]?.[date]

                      if (isEventDay) {
                        return <td key={date} className="bg-warning text-center">—</td>
                      }
                      if (isFuture) {
                        return <td key={date} className="text-center" style={{ backgroundColor: '#e7f1ff' }}>—</td>
                      }
                      if (ok) {
                        return <td key={date} className="text-center text-white" style={{ backgroundColor: '#198754' }}>{formatEnteredDate(rawDate)}</td>
                      }
                      return <td key={date} className="text-center text-white" style={{ backgroundColor: '#dc3545' }}>✖</td>
                    })}
                  </tr>
                )
              })}
            </tbody>
          </table>
        </div>
      ) : null}

      <div className="mt-2 small text-muted">Dates are Sundays within the current school term. Yellow indicates a no-school day; light blue indicates a future Sunday.</div>
    </div>
  )
}
