import { type FormEvent, useEffect, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { fetchScheduleMeetingForm, postScheduleMeeting } from '../../api/grading'
import { GRADING_BELOW_SIXTY_PATH } from './gradingPaths'

/** CI `grading/schedule_meeting.php` */
export function ScheduleMeetingPage() {
  const [searchParams] = useSearchParams()
  const studentId = searchParams.get('student_id') ?? ''
  const semester = searchParams.get('semester') ?? ''
  const schoolYear = searchParams.get('school_year') ?? ''

  const [studentName, setStudentName] = useState('')
  const [meetingAt, setMeetingAt] = useState('')
  const [notes, setNotes] = useState('')
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [done, setDone] = useState<string | null>(null)

  useEffect(() => {
    if (!studentId) {
      setLoading(false)
      return
    }
    let c = false
    setLoading(true)
    fetchScheduleMeetingForm(searchParams)
      .then((p) => {
        if (c) return
        if (p && typeof p === 'object') {
          const o = p as Record<string, unknown>
          setStudentName(String(o.studentName ?? o.student_name ?? ''))
          setMeetingAt(String(o.meeting_at ?? o.meetingAt ?? ''))
          setNotes(String(o.notes ?? o.note ?? ''))
        }
        setError(null)
      })
      .catch((e: unknown) => {
        if (!c) setError(e instanceof ApiHttpError ? e.message : 'Unable to load form.')
      })
      .finally(() => {
        if (!c) setLoading(false)
      })
    return () => {
      c = true
    }
  }, [searchParams, studentId])

  async function onSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault()
    setSaving(true)
    setError(null)
    setDone(null)
    try {
      await postScheduleMeeting({
        student_id: Number(studentId),
        semester,
        school_year: schoolYear,
        meeting_at: meetingAt || undefined,
        notes,
      })
      setDone('Saved.')
    } catch (err: unknown) {
      setError(err instanceof ApiHttpError ? err.message : 'Save failed.')
    } finally {
      setSaving(false)
    }
  }

  const backQs = searchParams.toString()

  if (!studentId) {
    return (
      <div className="container mt-4">
        <div className="alert alert-info">
          Missing <code>student_id</code>.
        </div>
        <Link className="btn btn-secondary" to={`${GRADING_BELOW_SIXTY_PATH}${backQs ? `?${backQs}` : ''}`}>
          Below 60
        </Link>
      </div>
    )
  }

  return (
    <div className="container py-4 col-lg-8">
      <div className="d-flex justify-content-between align-items-center mb-3 flex-wrap gap-2">
        <h2 className="mb-0">Schedule meeting</h2>
        <Link
          className="btn btn-outline-secondary btn-sm"
          to={`${GRADING_BELOW_SIXTY_PATH}${backQs ? `?${backQs}` : ''}`}
        >
          Back
        </Link>
      </div>

      {studentName ? <p className="text-muted">Student: {studentName}</p> : null}

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

      {!loading ? (
        <form onSubmit={(ev) => void onSubmit(ev)}>
          <div className="mb-3">
            <label className="form-label">Meeting time</label>
            <input
              type="datetime-local"
              className="form-control"
              value={meetingAt}
              onChange={(e) => setMeetingAt(e.target.value)}
            />
          </div>
          <div className="mb-3">
            <label className="form-label">Notes</label>
            <textarea className="form-control" rows={5} value={notes} onChange={(e) => setNotes(e.target.value)} />
          </div>
          <button type="submit" className="btn btn-primary" disabled={saving}>
            {saving ? 'Saving…' : 'Save'}
          </button>
        </form>
      ) : null}
    </div>
  )
}
