import { type FormEvent, useEffect, useMemo, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { useSchoolYearOptions } from '../../hooks/useSchoolYearOptions'
import { fetchTeacherStaffAttendance, saveTeacherStaffAttendance } from '../../api/session'
import { TEACHER_ATTENDANCE_MONTH_PATH } from './attendancePaths'
import type { TeacherStaffAttendanceRow } from '../../api/types'

function formatUsDate(ymd: string): string {
  if (!/^\d{4}-\d{2}-\d{2}$/.test(ymd)) return ymd
  const [y, m, d] = ymd.split('-')
  return `${m}-${d}-${y}`
}

/** Port of `Views/attendance/teacher_attendance_form.php` */
export function TeacherAttendanceFormPage() {
  const [searchParams, setSearchParams] = useSearchParams()
  const schoolYear = searchParams.get('school_year') ?? ''
  const semester = searchParams.get('semester') ?? ''
  const date =
    searchParams.get('date') ?? new Date().toISOString().slice(0, 10)
  const classSectionId = Number(searchParams.get('class_section_id') ?? '0')

  const [sections, setSections] = useState<Record<string, string>>({})
  const [grid, setGrid] = useState<TeacherStaffAttendanceRow[]>([])
  const [locked, setLocked] = useState(false)
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [message, setMessage] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const { options, selectedYear } = useSchoolYearOptions({
    preferredYear: schoolYear,
  })

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoading(true)
      setError(null)
      try {
        const data = await fetchTeacherStaffAttendance({
          date,
          semester: semester || null,
          schoolYear: schoolYear || null,
          classSectionId: classSectionId || null,
        })
        if (cancelled) return
        setSections(data.sections ?? {})
        setGrid(data.grid ?? [])
        setLocked(Boolean(data.locked))
      } catch (e) {
        if (!cancelled) setError(e instanceof Error ? e.message : 'Unable to load teacher attendance.')
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [date, semester, schoolYear, classSectionId])

  const dateLabel = useMemo(() => formatUsDate(date), [date])

  function setRow(tid: number, patch: Partial<TeacherStaffAttendanceRow>) {
    setGrid((prev) =>
      prev.map((r) => ((r.teacher_id ?? 0) === tid ? { ...r, ...patch } : r)),
    )
  }

  function markAllPresent() {
    setGrid((prev) => prev.map((r) => ({ ...r, status: 'present' })))
  }

  function clearAll() {
    setGrid((prev) => prev.map((r) => ({ ...r, status: '', reason: '' })))
  }

  async function onSubmit(e: FormEvent) {
    e.preventDefault()
    if (!classSectionId) return
    setSaving(true)
    setMessage(null)
    setError(null)
    try {
      const teachers: Record<string, { status?: string | null; reason?: string | null }> = {}
      for (const r of grid) {
        const tid = r.teacher_id ?? 0
        if (!tid) continue
        teachers[String(tid)] = {
          status: r.status ?? '',
          reason: r.reason ?? '',
        }
      }
      await saveTeacherStaffAttendance({
        date,
        semester,
        school_year: schoolYear,
        class_section_id: classSectionId,
        teachers,
      })
      setMessage('Saved.')
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Save failed.')
    } finally {
      setSaving(false)
    }
  }

  function applyFilters(e: FormEvent<HTMLFormElement>) {
    e.preventDefault()
    const fd = new FormData(e.currentTarget)
    const p = new URLSearchParams()
    const sy = String(fd.get('school_year') ?? '')
    const sem = String(fd.get('semester') ?? '')
    const dt = String(fd.get('date') ?? '')
    const cs = String(fd.get('class_section_id') ?? '0')
    if (sy) p.set('school_year', sy)
    if (sem) p.set('semester', sem)
    if (dt) p.set('date', dt)
    if (cs && cs !== '0') p.set('class_section_id', cs)
    setSearchParams(p)
  }

  const sectionEntries = Object.entries(sections)

  return (
    <div className="container-xxl py-4">
      <div className="d-flex justify-content-between align-items-center mb-3 flex-wrap gap-2">
        <h2 className="mb-0">Teacher Attendance</h2>
        <Link
          className="btn btn-outline-secondary"
          to={`${TEACHER_ATTENDANCE_MONTH_PATH}?${new URLSearchParams({ date, semester, school_year: schoolYear }).toString()}`}
        >
          ← Back to Monthly Attendance
        </Link>
      </div>

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

      <form className="row gy-2 gx-3 align-items-end mb-3" onSubmit={applyFilters}>
        <div className="col-sm-3">
          <label className="form-label">School Year</label>
          <select name="school_year" className="form-select" defaultValue={schoolYear || selectedYear}>
            {(options.length > 0 ? options : [{ value: selectedYear, label: selectedYear }]).map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        </div>
        <div className="col-sm-2">
          <label className="form-label">Semester</label>
          <input
            type="text"
            name="semester"
            className="form-control"
            defaultValue={semester}
            placeholder="Fall"
          />
        </div>
        <div className="col-sm-3">
          <label className="form-label">Date</label>
          <input type="date" name="date" className="form-control" defaultValue={date} />
        </div>
        <div className="col-sm-4">
          <label className="form-label">Class Section</label>
          <select
            name="class_section_id"
            className="form-select"
            defaultValue={classSectionId || 0}
          >
            <option value="0">— Choose Section —</option>
            {sectionEntries.map(([id, label]) => (
              <option key={id} value={id}>
                {label} (ID: {id})
              </option>
            ))}
          </select>
        </div>
        <div className="col-12 d-flex gap-2">
          <button type="submit" className="btn btn-secondary">
            Load
          </button>
          {classSectionId ? (
            <button
              type="button"
              className="btn btn-outline-secondary"
              onClick={() => setSearchParams(new URLSearchParams())}
            >
              Reset
            </button>
          ) : null}
        </div>
      </form>

      {!classSectionId ? null : (
        <>
          {locked ? (
            <div className="alert alert-warning">
              <strong>Note:</strong> Student/section attendance for this day appears to be <em>finalized</em>. Admin edits
              to teacher attendance here are allowed and will not unlock the section.
            </div>
          ) : null}

          <form onSubmit={onSubmit}>
            <div className="card shadow-sm">
              <div className="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
                <strong>Teachers on {dateLabel}</strong>
                <div className="d-flex gap-2">
                  <button type="button" className="btn btn-sm btn-outline-success" onClick={markAllPresent}>
                    Mark All Present
                  </button>
                  <button type="button" className="btn btn-sm btn-outline-secondary" onClick={clearAll}>
                    Clear All
                  </button>
                </div>
              </div>
              <div className="card-body table-responsive">
                {loading ? (
                  <p className="text-muted mb-0">Loading…</p>
                ) : grid.length === 0 ? (
                  <p className="text-muted mb-0 text-center">No teachers found for this section/term.</p>
                ) : (
                  <table className="table table-bordered table-striped align-middle" id="teacherAttTable">
                    <thead className="table-light">
                      <tr>
                        <th className="text-center" style={{ width: 70 }}>
                          #
                        </th>
                        <th>Name</th>
                        <th className="text-center" style={{ width: 160 }}>
                          Role
                        </th>
                        <th className="text-center" style={{ width: 200 }}>
                          Status
                        </th>
                        <th>Reason</th>
                      </tr>
                    </thead>
                    <tbody>
                      {grid.map((row, idx) => {
                        const tid = row.teacher_id ?? 0
                        const name =
                          `${row.firstname ?? ''} ${row.lastname ?? ''}`.trim() || `User#${tid}`
                        const pos = String(row.position ?? '').toLowerCase()
                        const stat = String(row.status ?? '').toLowerCase()
                        return (
                          <tr key={tid || idx}>
                            <td className="text-center">{idx + 1}</td>
                            <td>{name}</td>
                            <td className="text-center">{pos === 'main' ? 'Main Teacher' : 'Assistant'}</td>
                            <td className="text-center">
                              <select
                                className="form-select form-select-sm"
                                value={
                                  stat === 'present' || stat === 'absent' || stat === 'late' ? stat : ''
                                }
                                onChange={(ev) => setRow(tid, { status: ev.target.value || null })}
                              >
                                <option value="">—</option>
                                <option value="present">Present</option>
                                <option value="absent">Absent</option>
                                <option value="late">Late</option>
                              </select>
                            </td>
                            <td>
                              <input
                                type="text"
                                className="form-control form-control-sm"
                                placeholder="Optional reason"
                                value={row.reason ?? ''}
                                onChange={(ev) => setRow(tid, { reason: ev.target.value })}
                              />
                            </td>
                          </tr>
                        )
                      })}
                    </tbody>
                  </table>
                )}
              </div>
              <div className="card-footer d-flex justify-content-end">
                <button type="submit" className="btn btn-primary" disabled={saving || grid.length === 0}>
                  {saving ? 'Saving…' : 'Save Changes'}
                </button>
              </div>
            </div>
          </form>
        </>
      )}
    </div>
  )
}
