import { type FormEvent, useEffect, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { fetchPlacementIndex, postPlacementAll } from '../../api/grading'
import { AcademicFilterBar } from '../discounts/AcademicFilterBar'
import { sectionsFromUnknown } from './gradingPayloadHelpers'
import { GRADING_PATH, GRADING_PLACEMENT_PATH } from './gradingPaths'

function sectionId(row: Record<string, unknown>): string {
  const id = row.class_section_id ?? row.id ?? row.section_id
  return id !== undefined && id !== null ? String(id) : ''
}

function sectionLabel(row: Record<string, unknown>): string {
  return String(
    row.class_section_name ?? row.name ?? row.title ?? row.section_name ?? row.class_section_id ?? 'Section',
  )
}

/** CI `grading/placement_index.php` */
export function PlacementIndexPage() {
  const [searchParams] = useSearchParams()
  const [sections, setSections] = useState<Record<string, unknown>[]>([])
  const [payload, setPayload] = useState<unknown>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [busy, setBusy] = useState(false)

  useEffect(() => {
    let c = false
    setLoading(true)
    fetchPlacementIndex(searchParams)
      .then((p) => {
        if (c) return
        setPayload(p)
        setSections(sectionsFromUnknown(p))
        setError(null)
      })
      .catch((e: unknown) => {
        if (!c) setError(e instanceof ApiHttpError ? e.message : 'Unable to load placement index.')
      })
      .finally(() => {
        if (!c) setLoading(false)
      })
    return () => {
      c = true
    }
  }, [searchParams])

  async function runPlacementAll(e: FormEvent<HTMLFormElement>) {
    e.preventDefault()
    setBusy(true)
    setError(null)
    try {
      await postPlacementAll({
        school_year: searchParams.get('school_year') ?? undefined,
        semester: searchParams.get('semester') ?? undefined,
      })
      const next = await fetchPlacementIndex(searchParams)
      setPayload(next)
      setSections(sectionsFromUnknown(next))
    } catch (err: unknown) {
      setError(err instanceof ApiHttpError ? err.message : 'Action failed.')
    } finally {
      setBusy(false)
    }
  }

  const baseQs = searchParams.toString()

  return (
    <div className="container-fluid py-3">
      <h2 className="text-center mt-2 mb-3">Placement scores — sections</h2>
      <AcademicFilterBar />

      <div className="d-flex flex-wrap gap-2 mb-3">
        <Link
          className="btn btn-outline-secondary btn-sm"
          to={`${GRADING_PATH}${baseQs ? `?${baseQs}` : ''}`}
        >
          Grading hub
        </Link>
        <form onSubmit={(ev) => void runPlacementAll(ev)} className="d-inline">
          <button type="submit" className="btn btn-outline-primary btn-sm" disabled={busy}>
            {busy ? 'Working…' : 'Run placement for all (API)'}
          </button>
        </form>
      </div>

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

      {!loading && sections.length === 0 ? (
        <div className="alert alert-light border">No sections in the response.</div>
      ) : null}

      <ul className="list-group">
        {!loading &&
          sections.map((row, i) => {
            const id = sectionId(row)
            const href = id
              ? `${GRADING_PLACEMENT_PATH}?class_section_id=${encodeURIComponent(id)}${baseQs ? `&${baseQs}` : ''}`
              : '#'
            return (
              <li key={id || i} className="list-group-item d-flex justify-content-between align-items-center">
                <span>{sectionLabel(row)}</span>
                {id ? (
                  <Link className="btn btn-sm btn-primary" to={href}>
                    Open
                  </Link>
                ) : (
                  <span className="text-muted small">Missing section id</span>
                )}
              </li>
            )
          })}
      </ul>

      {payload != null && !loading ? (
        <details className="mt-4">
          <summary className="small text-muted">Raw payload</summary>
          <pre className="small bg-light p-3 rounded mt-2 overflow-auto" style={{ maxHeight: 280 }}>
            {JSON.stringify(payload, null, 2)}
          </pre>
        </details>
      ) : null}
    </div>
  )
}
