import { useEffect, useMemo, useState, type FormEvent } from 'react'
import { Link, useParams, useSearchParams } from 'react-router-dom'
import {
  fetchCompetitionScoresDetail,
  fetchCompetitionScoresIndex,
  fetchPublishedCompetition,
  fetchPublishedCompetitions,
  saveCompetitionScores,
} from '../api/session'
import type {
  CompetitionScoreStudentRow,
  CompetitionScoresEditResponse,
  CompetitionScoresIndexCompetitionRow,
  PublicCompetitionRow,
  PublicCompetitionWinnerRow,
} from '../api/types'

function PageShell({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <div className="container-fluid py-3">
      <div className="mb-4">
        <h2 className="h4 mb-1">{title}</h2>
      </div>
      {children}
    </div>
  )
}

function formatDate(value?: string | null) {
  if (!value) return '—'
  const date = new Date(value)
  return Number.isNaN(date.getTime()) ? value : date.toLocaleDateString()
}

function competitionLabel(row?: PublicCompetitionRow | null) {
  return row?.title ?? `Competition #${row?.id ?? ''}`
}

function noteCard(children: React.ReactNode) {
  return <div className="alert alert-warning">{children}</div>
}

export function CompetitionWinnersIndexPage() {
  const [rows, setRows] = useState<PublicCompetitionRow[]>([])
  const [teacherRows, setTeacherRows] = useState<CompetitionScoresIndexCompetitionRow[]>([])
  const [activeClassName, setActiveClassName] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    ;(async () => {
      try {
        const [published, teacher] = await Promise.allSettled([
          fetchPublishedCompetitions(),
          fetchCompetitionScoresIndex(),
        ])

        if (published.status === 'fulfilled') {
          setRows(published.value.data?.competitions ?? [])
        }

        if (teacher.status === 'fulfilled') {
          setTeacherRows(teacher.value.competitions ?? [])
          setActiveClassName(teacher.value.activeClassName ?? null)
        }

        if (published.status === 'rejected' && teacher.status === 'rejected') {
          setError('Unable to load competition winners data.')
        }
      } catch (e) {
        setError(e instanceof Error ? e.message : 'Unable to load competition winners data.')
      }
    })()
  }, [])

  return (
    <PageShell title="Competition Winners">
      {noteCard(
        <>
          The current API exposes published winners data and teacher score entry. I could not find routed admin APIs for
          create, settings, publish, lock, unlock, export quiz, or recognition PDF.
        </>,
      )}
      {error ? <div className="alert alert-danger">{error}</div> : null}

      <div className="card shadow-sm mb-4">
        <div className="card-header">Published Competitions</div>
        <div className="table-responsive">
          <table className="table table-bordered table-sm align-middle mb-0">
            <thead className="table-light">
              <tr>
                <th>ID</th>
                <th>Title</th>
                <th>Semester</th>
                <th>School Year</th>
                <th>Published</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              {rows.length === 0 ? (
                <tr><td colSpan={6} className="text-muted">No published competitions found.</td></tr>
              ) : rows.map((row) => (
                <tr key={row.id}>
                  <td>{row.id}</td>
                  <td>{competitionLabel(row)}</td>
                  <td>{row.semester ?? '—'}</td>
                  <td>{row.school_year ?? '—'}</td>
                  <td>{formatDate(row.published_at)}</td>
                  <td className="d-flex gap-2 flex-wrap">
                    <Link className="btn btn-sm btn-outline-secondary" to={`/app/admin/competition-winners/${row.id}/preview`}>Preview</Link>
                    <Link className="btn btn-sm btn-outline-secondary" to={`/app/admin/competition-winners/${row.id}/winners`}>Winners</Link>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      <div className="card shadow-sm">
        <div className="card-header">Teacher Score Entry Competitions{activeClassName ? ` - ${activeClassName}` : ''}</div>
        <div className="table-responsive">
          <table className="table table-bordered table-sm align-middle mb-0">
            <thead className="table-light">
              <tr>
                <th>ID</th>
                <th>Title</th>
                <th>Published</th>
                <th>Locked</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              {teacherRows.length === 0 ? (
                <tr><td colSpan={5} className="text-muted">No teacher competition score entries available for this account.</td></tr>
              ) : teacherRows.map((row) => (
                <tr key={row.id}>
                  <td>{row.id}</td>
                  <td>{row.title ?? `Competition #${row.id}`}</td>
                  <td>{row.is_published ? 'Yes' : 'No'}</td>
                  <td>{row.is_locked ? 'Yes' : 'No'}</td>
                  <td>
                    <Link className="btn btn-sm btn-outline-primary" to={`/app/admin/competition-winners/${row.id}`}>Enter Scores</Link>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </PageShell>
  )
}

export function CompetitionWinnerFormPage() {
  const { id } = useParams()

  return (
    <PageShell title={id ? 'Edit Competition' : 'Create Competition'}>
      {noteCard(
        <>
          This screen depends on admin competition management endpoints that are not currently routed in the Laravel API.
          The SPA can show published winners and teacher score entry, but it cannot safely create or update competition settings
          without those endpoints.
        </>,
      )}
      <div className="card shadow-sm">
        <div className="card-body">
          <div className="row g-3">
            <div className="col-md-8"><label className="form-label">Title</label><input className="form-control" disabled value="" /></div>
            <div className="col-md-4"><label className="form-label">Class Section</label><input className="form-control" disabled value="" /></div>
            <div className="col-md-3"><label className="form-label">Semester</label><input className="form-control" disabled value="" /></div>
            <div className="col-md-3"><label className="form-label">School Year</label><input className="form-control" disabled value="" /></div>
            <div className="col-md-3"><label className="form-label">Start Date</label><input className="form-control" disabled value="" /></div>
            <div className="col-md-3"><label className="form-label">End Date</label><input className="form-control" disabled value="" /></div>
          </div>
        </div>
      </div>
    </PageShell>
  )
}

export function CompetitionWinnerScoresPage() {
  const { id } = useParams()
  const competitionId = Number(id)
  const [searchParams, setSearchParams] = useSearchParams()
  const selectedClassId = Number(searchParams.get('class_section_id') ?? 0) || null
  const [data, setData] = useState<CompetitionScoresEditResponse | null>(null)
  const [scores, setScores] = useState<Record<string, number | string>>({})
  const [message, setMessage] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)

  async function load(classSectionId = selectedClassId) {
    try {
      const response = await fetchCompetitionScoresDetail(competitionId, classSectionId)
      setData(response)
      setScores(response.scoreMap ?? {})
      setError(response.ok ? null : response.message ?? 'Unable to load competition scores.')
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Unable to load competition scores.')
    }
  }

  useEffect(() => {
    if (!Number.isFinite(competitionId) || competitionId <= 0) return
    void load()
  }, [competitionId, selectedClassId])

  async function onSubmit(e: FormEvent) {
    e.preventDefault()
    if (!competitionId) return
    try {
      const result = await saveCompetitionScores(competitionId, {
        class_section_id: data?.classSectionId ?? selectedClassId,
        scores,
      })
      setMessage(result.message ?? 'Scores saved.')
      if (result.ok) {
        await load()
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Unable to save scores.')
    }
  }

  return (
    <PageShell title="Enter Scores">
      {noteCard(
        <>
          This page uses the teacher-facing `competition-scores` API. It works only when the logged-in account is assigned to the
          target class section.
        </>,
      )}
      {error ? <div className="alert alert-danger">{error}</div> : null}
      {message ? <div className="alert alert-success">{message}</div> : null}
      {data?.competition ? (
        <>
          <div className="mb-3">
            <div><strong>Competition:</strong> {competitionLabel(data.competition)}</div>
            <div><strong>Class Section:</strong> {data.classSectionName ?? '—'}</div>
            <div>
              <strong>Students:</strong> {data.classStudentCount ?? 0} | <strong>Questions:</strong> {data.questionCount ?? '—'}
            </div>
          </div>
          <form onSubmit={(e) => void onSubmit(e)}>
            {data.classSelectionLocked === false ? (
              <div className="mb-3" style={{ maxWidth: 360 }}>
                <label className="form-label">Class Section ID</label>
                <input
                  className="form-control"
                  value={String(selectedClassId ?? data.classSectionId ?? '')}
                  onChange={(e) => setSearchParams(e.target.value ? { class_section_id: e.target.value } : {})}
                />
              </div>
            ) : null}
            <div className="table-responsive">
              <table className="table table-bordered table-sm align-middle">
                <thead className="table-light">
                  <tr>
                    <th>School ID</th>
                    <th>Student</th>
                    <th>Score{data.questionCount ? ` (max ${data.questionCount})` : ''}</th>
                  </tr>
                </thead>
                <tbody>
                  {(data.students ?? []).length === 0 ? (
                    <tr><td colSpan={3} className="text-muted">No students loaded for this competition.</td></tr>
                  ) : (data.students ?? []).map((student: CompetitionScoreStudentRow) => {
                    const studentId = Number(student.id ?? student.student_id ?? 0)
                    const name = `${student.firstname ?? ''} ${student.lastname ?? ''}`.trim() || `Student #${studentId}`
                    return (
                      <tr key={studentId}>
                        <td>{student.school_id ?? studentId}</td>
                        <td>{name}</td>
                        <td>
                          <input
                            className="form-control form-control-sm"
                            type="number"
                            step="1"
                            min="0"
                            max={data.questionCount ?? undefined}
                            disabled={Boolean(data.isLocked)}
                            value={String(scores[String(studentId)] ?? '')}
                            onChange={(e) => setScores((current) => ({ ...current, [String(studentId)]: e.target.value }))}
                          />
                        </td>
                      </tr>
                    )
                  })}
                </tbody>
              </table>
            </div>
            <div className="d-flex gap-2">
              <button className="btn btn-primary" disabled={Boolean(data.isLocked)}>Save Scores</button>
              <Link className="btn btn-outline-secondary" to={`/app/admin/competition-winners/${competitionId}/preview`}>Preview</Link>
            </div>
          </form>
        </>
      ) : (
        <p className="text-muted mb-0">No competition data loaded.</p>
      )}
    </PageShell>
  )
}

function usePublishedCompetition(id: number) {
  const [competition, setCompetition] = useState<PublicCompetitionRow | null>(null)
  const [winnersByClass, setWinnersByClass] = useState<Record<string, PublicCompetitionWinnerRow[]>>({})
  const [sectionMap, setSectionMap] = useState<Record<string, string>>({})
  const [questionCounts, setQuestionCounts] = useState<Record<string, number>>({})
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    if (!Number.isFinite(id) || id <= 0) return
    ;(async () => {
      try {
        const response = await fetchPublishedCompetition(id)
        if (!response.status || !response.data) {
          setError(response.message ?? 'Competition not found.')
          return
        }
        setCompetition(response.data.competition)
        setWinnersByClass(response.data.winners_by_class ?? {})
        setSectionMap(response.data.section_map ?? {})
        setQuestionCounts(response.data.question_counts ?? {})
        setError(null)
      } catch (e) {
        setError(e instanceof Error ? e.message : 'Unable to load winners.')
      }
    })()
  }, [id])

  return { competition, winnersByClass, sectionMap, questionCounts, error }
}

export function CompetitionWinnerPreviewPage() {
  const { id } = useParams()
  const competitionId = Number(id)
  const { competition, winnersByClass, sectionMap, error } = usePublishedCompetition(competitionId)

  return (
    <PageShell title="Preview Winners">
      {noteCard('This preview is backed by the public published-winners API. Unpublished preview data is not exposed by the current backend.')}
      {error ? <div className="alert alert-danger">{error}</div> : null}
      {competition ? (
        <>
          <div className="mb-3">
            <div><strong>Competition:</strong> {competitionLabel(competition)}</div>
            <div><strong>School Year:</strong> {competition.school_year ?? '—'}</div>
          </div>
          {Object.keys(winnersByClass).length === 0 ? (
            <div className="alert alert-warning">No published winners found for this competition.</div>
          ) : Object.entries(winnersByClass).map(([classId, rows]) => (
            <div key={classId} className="mb-4">
              <h5 className="mt-4">Top Winners - {sectionMap[classId] ?? `Class ${classId}`}</h5>
              <table className="table table-bordered table-sm">
                <thead className="table-light">
                  <tr><th>Rank</th><th>Student</th><th>Score</th><th>Prize</th></tr>
                </thead>
                <tbody>
                  {rows.map((row, index) => (
                    <tr key={`${classId}-${index}`}>
                      <td>{row.rank ?? index + 1}</td>
                      <td>{row.name ?? (`${row.firstname ?? ''} ${row.lastname ?? ''}`.trim() || `Student #${row.student_id ?? ''}`)}</td>
                      <td>{row.score ?? '—'}</td>
                      <td>{row.prize_amount ?? '—'}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          ))}
        </>
      ) : null}
    </PageShell>
  )
}

export function CompetitionWinnerWinnersPage() {
  const { id } = useParams()
  const competitionId = Number(id)
  const { competition, winnersByClass, sectionMap, questionCounts, error } = usePublishedCompetition(competitionId)

  const flatRows = useMemo(
    () =>
      Object.entries(winnersByClass).flatMap(([classId, rows]) =>
        rows.map((row) => ({ ...row, _classId: classId })),
      ),
    [winnersByClass],
  )

  const totalPrize = flatRows.reduce((sum, row) => sum + Number(row.prize_amount ?? 0), 0)

  return (
    <PageShell title="School Winners">
      {noteCard('This page uses the public published-winners API. The admin-only recognition PDF endpoint is not currently exposed in the Laravel API.')}
      {error ? <div className="alert alert-danger">{error}</div> : null}
      {competition ? (
        <>
          <div className="mb-3">
            <div><strong>Competition:</strong> {competitionLabel(competition)}</div>
            <div><strong>School Year:</strong> {competition.school_year ?? '—'}</div>
            <div><strong>Published:</strong> {competition.is_published ? 'Yes' : 'No'}</div>
          </div>
          {flatRows.length === 0 ? (
            <div className="alert alert-warning">No published winners yet.</div>
          ) : (
            <div className="table-responsive">
              <table className="table table-bordered table-sm">
                <thead className="table-light">
                  <tr>
                    <th>Class</th>
                    <th>Student</th>
                    <th>Rank</th>
                    <th>Score</th>
                    <th>Question Count</th>
                    <th>Prize</th>
                  </tr>
                </thead>
                <tbody>
                  {flatRows.map((row, index) => (
                    <tr key={`${row._classId}-${index}`}>
                      <td>{sectionMap[String(row._classId)] ?? `Class ${row._classId}`}</td>
                      <td>{row.name ?? (`${row.firstname ?? ''} ${row.lastname ?? ''}`.trim() || `Student #${row.student_id ?? ''}`)}</td>
                      <td>{row.rank ?? '—'}</td>
                      <td>{row.score ?? '—'}</td>
                      <td>{questionCounts[String(row._classId)] ?? '—'}</td>
                      <td>{row.prize_amount ?? '—'}</td>
                    </tr>
                  ))}
                </tbody>
                <tfoot>
                  <tr>
                    <th colSpan={5} className="text-end">Total Prizes</th>
                    <th>{totalPrize.toFixed(2)}</th>
                  </tr>
                </tfoot>
              </table>
            </div>
          )}
        </>
      ) : null}
    </PageShell>
  )
}
