import { type FormEvent, useEffect, useMemo, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { useSchoolYearOptions } from '../../hooks/useSchoolYearOptions'
import {
  fetchAttendanceViolationsNotified,
  fetchAttendanceViolationsPending,
  saveAttendanceViolationNote,
} from '../../api/session'
import type { AttendanceViolationStudentRow } from '../../api/types'
import {
  ATTENDANCE_VIOLATIONS_NOTIFIED_PATH,
  ATTENDANCE_VIOLATIONS_PENDING_PATH,
} from './attendancePaths'

function studentIdOf(st: AttendanceViolationStudentRow): number {
  return Number(st.student_id ?? st.id ?? 0)
}

function studentNameOf(st: AttendanceViolationStudentRow): string {
  const n =
    (st.name as string | undefined) ||
    (st.student_name as string | undefined) ||
    `${String(st.firstname ?? st.first_name ?? '')} ${String(st.lastname ?? st.last_name ?? '')}`.trim()
  const sid = studentIdOf(st)
  return n || (sid ? `Student #${sid}` : '—')
}

/** Port of `Views/attendance/violations_pending.php` */
export function ViolationsPendingPage() {
  const [searchParams, setSearchParams] = useSearchParams()
  const schoolYear = searchParams.get('school_year') ?? ''
  const semester = searchParams.get('semester') ?? ''
  const { options, selectedYear } = useSchoolYearOptions({
    preferredYear: schoolYear,
  })

  const filterQuery = useMemo(() => {
    const s = searchParams.toString()
    return s ? `?${s}` : ''
  }, [searchParams])

  const [rows, setRows] = useState<AttendanceViolationStudentRow[]>([])
  const [debug, setDebug] = useState<Record<string, unknown> | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [q, setQ] = useState('')

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoading(true)
      try {
        const data = await fetchAttendanceViolationsPending({
          schoolYear: schoolYear || null,
          semester: semester || null,
        })
        if (!cancelled) {
          setRows(data.students ?? [])
          setDebug((data.debug as Record<string, unknown>) ?? null)
          if (!schoolYear && data.school_year) {
            const p = new URLSearchParams(searchParams)
            p.set('school_year', data.school_year)
            setSearchParams(p, { replace: true })
          }
        }
      } catch (e) {
        if (!cancelled) setError(e instanceof Error ? e.message : 'Unable to load violations.')
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [schoolYear, semester])

  const filtered = useMemo(() => {
    const s = q.trim().toLowerCase()
    if (!s) return rows
    return rows.filter((r) => studentNameOf(r).toLowerCase().includes(s))
  }, [rows, q])

  function applyFilter(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') ?? '')
    if (sy) p.set('school_year', sy)
    if (sem) p.set('semester', sem)
    setSearchParams(p)
  }

  return (
    <div className="container-fluid px-0">
      <h2 className="text-center mt-4 mb-3">Pending Attendance Violations</h2>
      <div className="d-flex justify-content-center mb-2">
        <form className="row g-2 align-items-end" onSubmit={applyFilter}>
          <div className="col-auto">
            <label htmlFor="pending-school-year" className="form-label small mb-0">School Year</label>
            <select
              id="pending-school-year"
              name="school_year"
              className="form-select form-select-sm"
              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-auto">
            <label htmlFor="pending-semester" className="form-label small mb-0">Semester</label>
            <select id="pending-semester" name="semester" className="form-select form-select-sm" defaultValue={semester}>
              <option value="">— All —</option>
              <option value="Fall">Fall</option>
              <option value="Spring">Spring</option>
            </select>
          </div>
          <div className="col-auto">
            <button type="submit" className="btn btn-sm btn-secondary">
              Apply
            </button>
          </div>
        </form>
      </div>

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

      <div className="row g-0">
        <div className="col-12">
          <div className="card border-0 rounded-3 shadow-sm mx-2">
            <div className="card-header d-flex flex-wrap gap-2 justify-content-between align-items-center">
              <h5 className="mt-2 mb-0">Pending Attendance Violations</h5>
              <div className="d-flex flex-wrap gap-2 align-items-center">
                <span className="badge bg-primary">School Year: {schoolYear || '—'}</span>
                <Link
                  to={`${ATTENDANCE_VIOLATIONS_NOTIFIED_PATH}${filterQuery}`}
                  className="btn btn-outline-dark btn-sm"
                >
                  View Notified
                </Link>
              </div>
            </div>
            <div className="card-body">
              <div className="row mb-3">
                <div className="col-md-4">
                  <input
                    id="pending-quick-filter"
                    type="search"
                    name="q"
                    className="form-control form-control-sm"
                    placeholder="Quick filter…"
                    value={q}
                    onChange={(ev) => setQ(ev.target.value)}
                  />
                </div>
              </div>

              <div className="d-flex flex-wrap gap-3 mb-3 small">
                <Legend dot="#e6f7ff" label="1 Absence — Auto Email" dark />
                <Legend dot="#fadb14" label="2 Absences — Team Notify" dark />
                <Legend dot="#fa8c16" label="3 Absences — Team Notify" />
                <Legend dot="#ff4d4f" label="4 Absences / Expel / 4 Lates" />
                <Legend dot="#bae7ff" label="2 Lates — Auto Email" dark />
                <Legend dot="#002766" label="3 Lates / mixed — Team Notify" />
              </div>

              {loading ? (
                <p className="text-muted">Loading…</p>
              ) : filtered.length === 0 ? (
                <>
                  <div className="alert alert-info mb-2">No attendance violations found.</div>
                  {debug ? (
                    <div className="alert alert-secondary small">
                      <strong>Debug</strong>
                      <pre className="mb-0 small">{JSON.stringify(debug, null, 2)}</pre>
                    </div>
                  ) : null}
                </>
              ) : (
                <div className="table-responsive">
                  <table className="table table-striped table-hover align-middle w-100 small">
                    <thead className="table-dark">
                      <tr>
                        <th>Student</th>
                        <th>Grade</th>
                        <th>Violation</th>
                        <th>Type</th>
                        <th className="text-center">Abs</th>
                        <th className="text-center">Late</th>
                        <th>Last Incident</th>
                        <th>Action</th>
                        <th>Notified?</th>
                        <th>#</th>
                        <th>Parent</th>
                        <th>Actions</th>
                      </tr>
                    </thead>
                    <tbody>
                      {filtered.map((st, idx) => (
                        <PendingRow key={`${studentIdOf(st)}-${idx}`} st={st} />
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

function Legend({ dot, label, dark }: { dot: string; label: string; dark?: boolean }) {
  return (
    <span>
      <span
        className="badge rounded-pill"
        style={{ backgroundColor: dot, color: dark ? '#000' : '#fff' }}
      >
        &nbsp;&nbsp;
      </span>{' '}
      {label}
    </span>
  )
}

function PendingRow({ st }: { st: AttendanceViolationStudentRow }) {
  const sid = studentIdOf(st)
  const name = studentNameOf(st)
  const grade = String(st.class_name ?? st.class_section_name ?? '')
  const viTitle = String(st.violation ?? '')
  const viCode = String(st.violation_code ?? '')
  const viType = String(st.type ?? '')
  const viColor = String(st.color ?? '#6c757d')
  const action = String(st.action ?? '')
  const absences = (st.absences as unknown[]) ?? []
  const lates = (st.lates as unknown[]) ?? []
  const lastDate = st.last_date as string | undefined
  const incidentYmd = lastDate ? String(lastDate).slice(0, 10) : ''
  const notified = Boolean(st.is_notified)
  const notifCnt = Number(st.notif_counter ?? 0)
  const parentEmail = String(st.parent_email ?? '')
  const parentName = String(st.parent_name ?? '')
  const parentLabel = parentName || parentEmail || 'View'

  const isLight = ['#bae7ff', '#e6f7ff', '#fadb14'].includes(viColor.toLowerCase())
  const badgeCls = `badge rounded-pill ${isLight ? 'text-dark' : 'text-light'}`

  const composeBase = `/app/administrator/attendance/compose-email?student_id=${sid}&code=${encodeURIComponent(viCode)}`
  const incidentParam = incidentYmd ? `&incident_date=${encodeURIComponent(incidentYmd)}` : ''

  return (
    <tr style={{ borderLeft: `6px solid ${viColor}` }}>
      <td>
        <Link to={`/app/administrator/family?student_id=${sid}`} className="text-decoration-none">
          {name}
        </Link>
      </td>
      <td>{grade}</td>
      <td>
        <span className={badgeCls} style={{ backgroundColor: viColor }}>
          {viTitle}
        </span>
      </td>
      <td className="text-capitalize">{viType || '—'}</td>
      <td className="text-center">{absences.length}</td>
      <td className="text-center">{lates.length}</td>
      <td>{incidentYmd ? formatMdY(incidentYmd) : '—'}</td>
      <td>
        {action === 'auto_email' ? (
          <span className="badge bg-primary">Auto Email</span>
        ) : action === 'expel_notify' ? (
          <span className="badge bg-danger">Expel Notify</span>
        ) : (
          <span className="badge bg-warning text-dark">Team Notify</span>
        )}
      </td>
      <td>
        <span className={`badge ${notified ? 'bg-success' : 'bg-warning text-dark'}`}>
          {notified ? 'Yes' : 'No'}
        </span>
      </td>
      <td>{notifCnt}</td>
      <td>
        <Link to={`/app/administrator/family?student_id=${sid}`} className="text-decoration-none">
          {parentLabel}
        </Link>
        {parentEmail ? (
          <a className="ms-2" href={`mailto:${parentEmail}`} title="Email parent">
            <i className="bi bi-envelope" aria-hidden />
          </a>
        ) : null}
      </td>
      <td className="text-nowrap">
        <Link
          className="btn btn-sm btn-info"
          to={`/app/administrator/attendance/view/${sid}?code=${encodeURIComponent(viCode)}${incidentParam}`}
        >
          Details
        </Link>
        {action === 'auto_email' ? (
          <Link
            className="btn btn-sm btn-primary ms-1"
            to={`${composeBase}&variant=default${incidentParam}`}
          >
            Compose Auto Email
          </Link>
        ) : (
          <span className="btn-group ms-1">
            <Link className="btn btn-sm btn-success" to={`${composeBase}&variant=answered${incidentParam}`}>
              Answered
            </Link>
            <Link className="btn btn-sm btn-warning" to={`${composeBase}&variant=no_answer${incidentParam}`}>
              No Answer
            </Link>
          </span>
        )}
      </td>
    </tr>
  )
}

/** Port of `Views/attendance/violations_notified.php` */
export function ViolationsNotifiedPage() {
  const [searchParams, setSearchParams] = useSearchParams()
  const schoolYear = searchParams.get('school_year') ?? ''
  const semester = searchParams.get('semester') ?? ''
  const { options, selectedYear } = useSchoolYearOptions({
    preferredYear: schoolYear,
  })

  const filterQuery = useMemo(() => {
    const s = searchParams.toString()
    return s ? `?${s}` : ''
  }, [searchParams])

  const [rows, setRows] = useState<AttendanceViolationStudentRow[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [noteModal, setNoteModal] = useState<AttendanceViolationStudentRow | null>(null)
  const [noteText, setNoteText] = useState('')
  const [savingNote, setSavingNote] = useState(false)

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      setLoading(true)
      try {
        const data = await fetchAttendanceViolationsNotified({
          schoolYear: schoolYear || null,
          semester: semester || null,
        })
        if (!cancelled) {
          setRows(data.students ?? [])
          if (!schoolYear && data.school_year) {
            const p = new URLSearchParams(searchParams)
            p.set('school_year', data.school_year)
            setSearchParams(p, { replace: true })
          }
        }
      } catch (e) {
        if (!cancelled) setError(e instanceof Error ? e.message : 'Unable to load.')
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [schoolYear, semester])

  function applyFilter(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') ?? '')
    if (sy) p.set('school_year', sy)
    if (sem) p.set('semester', sem)
    setSearchParams(p)
  }

  async function submitNote(e: FormEvent) {
    e.preventDefault()
    if (!noteModal) return
    setSavingNote(true)
    try {
      const sid = studentIdOf(noteModal)
      const code = String(noteModal.reason ?? noteModal.violation_code ?? '')
      const lastDate = noteModal.last_date as string | undefined
      const incidentYmd = lastDate ? String(lastDate).slice(0, 10) : ''
      await saveAttendanceViolationNote({
        student_id: String(sid),
        code,
        incident_date: incidentYmd,
        note: noteText,
        return_url: typeof window !== 'undefined' ? window.location.href : '',
      })
      setNoteModal(null)
      setNoteText('')
    } catch {
      setError('Unable to save note.')
    } finally {
      setSavingNote(false)
    }
  }

  return (
    <div className="container-fluid px-0">
      <h2 className="text-center mt-4 mb-3">Notified Attendance Violations</h2>
      <div className="d-flex justify-content-center mb-2">
        <form className="row g-2 align-items-end" onSubmit={applyFilter}>
          <div className="col-auto">
            <label htmlFor="notified-school-year" className="form-label small mb-0">School Year</label>
            <select
              id="notified-school-year"
              name="school_year"
              className="form-select form-select-sm"
              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-auto">
            <label htmlFor="notified-semester" className="form-label small mb-0">Semester</label>
            <select id="notified-semester" name="semester" className="form-select form-select-sm" defaultValue={semester}>
              <option value="">— All —</option>
              <option value="Fall">Fall</option>
              <option value="Spring">Spring</option>
            </select>
          </div>
          <div className="col-auto">
            <button type="submit" className="btn btn-sm btn-secondary">
              Apply
            </button>
          </div>
        </form>
      </div>

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

      <div className="card border-0 rounded-3 shadow-sm mx-2">
        <div className="card-header d-flex flex-wrap gap-2 justify-content-between align-items-center">
          <h5 className="mt-2 mb-0">Notified Attendance Violations</h5>
          <div className="d-flex flex-wrap gap-2 align-items-center">
            <span className="badge bg-primary">School Year: {schoolYear || '—'}</span>
            <Link to={`${ATTENDANCE_VIOLATIONS_PENDING_PATH}${filterQuery}`} className="btn btn-outline-dark btn-sm">
              View Pending
            </Link>
          </div>
        </div>
        <div className="card-body">
          {loading ? (
            <p className="text-muted">Loading…</p>
          ) : rows.length === 0 ? (
            <div className="alert alert-info mb-0">No notified violations found.</div>
          ) : (
            <div className="table-responsive">
              <table className="table table-striped table-hover align-middle w-100 small">
                <thead className="table-dark">
                  <tr>
                    <th>Student</th>
                    <th>Grade</th>
                    <th>Last Incident</th>
                    <th>Reason</th>
                    <th>Note</th>
                    <th>Parent</th>
                    <th>Notified On</th>
                    <th>Details</th>
                  </tr>
                </thead>
                <tbody>
                  {rows.map((st, idx) => (
                    <NotifiedRow
                      key={`${studentIdOf(st)}-${idx}`}
                      st={st}
                      onEditNote={() => {
                        setNoteModal(st)
                        setNoteText(String(st.note ?? ''))
                      }}
                    />
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </div>

      {noteModal ? (
        <div className="modal show d-block" tabIndex={-1} style={{ background: 'rgba(0,0,0,0.4)' }}>
          <div className="modal-dialog">
            <form className="modal-content" onSubmit={submitNote}>
              <div className="modal-header">
                <h5 className="modal-title">Comment / Note</h5>
                <button type="button" className="btn-close" aria-label="Close" onClick={() => setNoteModal(null)} />
              </div>
              <div className="modal-body">
                <textarea
                  id="note-text"
                  name="note"
                  className="form-control"
                  rows={5}
                  required
                  value={noteText}
                  onChange={(ev) => setNoteText(ev.target.value)}
                />
              </div>
              <div className="modal-footer">
                <button type="submit" className="btn btn-primary" disabled={savingNote}>
                  Save Note
                </button>
                <button type="button" className="btn btn-outline-secondary" onClick={() => setNoteModal(null)}>
                  Cancel
                </button>
              </div>
            </form>
          </div>
        </div>
      ) : null}
    </div>
  )
}

function NotifiedRow({
  st,
  onEditNote,
}: {
  st: AttendanceViolationStudentRow
  onEditNote: () => void
}) {
  const sid = studentIdOf(st)
  const name = studentNameOf(st)
  const grade = String(st.class_section_name ?? st.class_name ?? '')
  const lastDate = st.last_date ?? st.date
  const incidentYmd = lastDate ? String(lastDate).slice(0, 10) : ''
  const reason = String(st.reason ?? '')
  const note = String(st.note ?? '')
  const parentName = String(st.parent_name ?? '')
  const notifiedAt = st.updated_at ?? st.date
  const code = String(st.reason ?? st.violation_code ?? '')
  const viColor = String(st.color ?? '#0d6efd')

  return (
    <tr style={{ borderLeft: `6px solid ${viColor}` }}>
      <td>
        <Link to={`/app/administrator/family?student_id=${sid}`} className="text-decoration-none">
          {name}
        </Link>
      </td>
      <td>{grade}</td>
      <td>{incidentYmd ? formatMdY(incidentYmd) : '—'}</td>
      <td>{reason || '—'}</td>
      <td style={{ maxWidth: 280 }}>
        {note ? (
          <span className="small">{note.length > 120 ? `${note.slice(0, 120)}…` : note}</span>
        ) : null}
        <button type="button" className="btn btn-sm btn-outline-primary ms-1" onClick={onEditNote}>
          {note ? 'Edit note' : 'Add note'}
        </button>
      </td>
      <td>
        {parentName ? (
          <Link to={`/app/administrator/family?student_id=${sid}`} className="text-decoration-none">
            {parentName}
          </Link>
        ) : (
          <span className="text-muted">—</span>
        )}
      </td>
      <td>{notifiedAt ? formatMdY(String(notifiedAt).slice(0, 10)) : '—'}</td>
      <td>
        <Link
          className="btn btn-sm btn-info"
          to={`/app/administrator/attendance/view/${sid}?code=${encodeURIComponent(code)}&incident_date=${encodeURIComponent(incidentYmd)}&include_notified=1`}
        >
          Details
        </Link>
      </td>
    </tr>
  )
}

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