import { useEffect, useMemo, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import {
  fetchAdminCompetitionWinnerCreate,
  fetchAdminCompetitionWinnerSettings,
  saveAdminCompetitionWinner,
} from '../../api/session'
import type { CompetitionWinnerAdminClassRow, CompetitionWinnerAdminFormResponse } from '../../api/types'
import { ApiScopeNote, CompetitionPageShell, COMPETITION_WINNERS_BASE } from './competitionWinnersShared'

type CompetitionFormState = {
  title: string
  class_section_id: string
  semester: string
  school_year: string
  start_date: string
  end_date: string
}

function numberOrNull(value: string): number | null {
  const trimmed = value.trim()
  if (trimmed === '') return null
  const parsed = Number(trimmed)
  return Number.isFinite(parsed) ? parsed : null
}

function initialFormState(payload: CompetitionWinnerAdminFormResponse): CompetitionFormState {
  const competition = payload.competition
  return {
    title: String(competition?.title ?? ''),
    class_section_id:
      competition?.class_section_id === null || competition?.class_section_id === undefined
        ? ''
        : String(competition.class_section_id),
    semester: String(competition?.semester ?? payload.defaultSemester ?? ''),
    school_year: String(competition?.school_year ?? payload.defaultSchoolYear ?? ''),
    start_date: String(competition?.start_date ?? ''),
    end_date: String(competition?.end_date ?? ''),
  }
}

function normalizeRowValue(value: number | string | null | undefined): string {
  return value === null || value === undefined ? '' : String(value)
}

/** CI `admin/competition_winners/form.php` */
export function CompetitionWinnerFormPage() {
  const { id } = useParams()
  const navigate = useNavigate()
  const isEdit = Boolean(id)
  const competitionId = Number(id)
  const [form, setForm] = useState<CompetitionFormState>({
    title: '',
    class_section_id: '',
    semester: '',
    school_year: '',
    start_date: '',
    end_date: '',
  })
  const [classRows, setClassRows] = useState<CompetitionWinnerAdminClassRow[]>([])
  const [classSections, setClassSections] = useState<CompetitionWinnerAdminFormResponse['classSections']>([])
  const [saving, setSaving] = useState(false)
  const [message, setMessage] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    ;(async () => {
      try {
        const response =
          isEdit && Number.isFinite(competitionId) && competitionId > 0
            ? await fetchAdminCompetitionWinnerSettings(competitionId)
            : await fetchAdminCompetitionWinnerCreate()

        if (!response.ok) {
          setError(response.message ?? 'Unable to load competition settings.')
          return
        }

        setForm(initialFormState(response))
        setClassRows(response.classRows ?? [])
        setClassSections(response.classSections ?? [])
        setError(null)
      } catch (e) {
        setError(e instanceof Error ? e.message : 'Unable to load competition settings.')
      }
    })()
  }, [competitionId, isEdit])

  const visibleRows = useMemo(() => {
    const selectedClassId = numberOrNull(form.class_section_id)
    if (selectedClassId === null) return classRows
    return classRows.filter((row) => row.class_section_id === selectedClassId)
  }, [classRows, form.class_section_id])

  function updateClassRow(
    classSectionId: number,
    key:
      | 'question_count'
      | 'override_winners'
      | 'prize_1'
      | 'prize_2'
      | 'prize_3'
      | 'prize_4'
      | 'prize_5'
      | 'prize_6',
    value: string,
  ) {
    setClassRows((current) =>
      current.map((row) => {
        if (row.class_section_id !== classSectionId) return row
        return {
          ...row,
          [key]: value.trim() === '' ? null : Number(value),
        }
      }),
    )
  }

  async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault()

    try {
      setSaving(true)
      setMessage(null)
      setError(null)

      const winnerOverrides = Object.fromEntries(
        classRows.map((row) => [String(row.class_section_id), normalizeRowValue(row.override_winners)]),
      )
      const questionCounts = Object.fromEntries(
        classRows.map((row) => [String(row.class_section_id), normalizeRowValue(row.question_count)]),
      )
      const prizes = Object.fromEntries(
        classRows.map((row) => [
          String(row.class_section_id),
          {
            1: normalizeRowValue(row.prize_1),
            2: normalizeRowValue(row.prize_2),
            3: normalizeRowValue(row.prize_3),
            4: normalizeRowValue(row.prize_4),
            5: normalizeRowValue(row.prize_5),
            6: normalizeRowValue(row.prize_6),
          },
        ]),
      )

      const result = await saveAdminCompetitionWinner(
        {
          title: form.title,
          class_section_id: numberOrNull(form.class_section_id),
          semester: form.semester || null,
          school_year: form.school_year || null,
          start_date: form.start_date || null,
          end_date: form.end_date || null,
          winner_overrides: winnerOverrides,
          question_counts: questionCounts,
          prizes,
        },
        isEdit && Number.isFinite(competitionId) && competitionId > 0 ? competitionId : undefined,
      )

      if (!result.ok) {
        setError(result.message ?? 'Unable to save competition.')
        return
      }

      const nextId = result.id ?? competitionId
      setMessage(result.message ?? 'Competition saved.')
      if (Number.isFinite(nextId) && nextId > 0) {
        navigate(`${COMPETITION_WINNERS_BASE}/${nextId}/settings`, { replace: true })
        return
      }

      navigate(COMPETITION_WINNERS_BASE)
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Unable to save competition.')
    } finally {
      setSaving(false)
    }
  }

  return (
    <CompetitionPageShell title={isEdit ? 'Edit Competition' : 'Create Competition'}>
      <ApiScopeNote>
        This screen now saves directly through the Laravel admin competition endpoints, including per-class winner overrides
        and prize grids.
      </ApiScopeNote>
      {error ? <div className="alert alert-danger">{error}</div> : null}
      {message ? <div className="alert alert-success">{message}</div> : null}

      <form className="card shadow-sm" onSubmit={(e) => void onSubmit(e)}>
        <div className="card-body row g-3">
          <div className="col-md-8">
            <label className="form-label">Title *</label>
            <input
              className="form-control"
              value={form.title}
              onChange={(e) => setForm((current) => ({ ...current, title: e.target.value }))}
              required
            />
          </div>
          <div className="col-md-6">
            <label className="form-label">Class Section (optional)</label>
            <select
              className="form-select"
              value={form.class_section_id}
              onChange={(e) => setForm((current) => ({ ...current, class_section_id: e.target.value }))}
            >
              <option value="">All classes</option>
              {(classSections ?? []).map((section) => (
                <option key={String(section?.class_section_id ?? '')} value={String(section?.class_section_id ?? '')}>
                  {section?.class_section_name ?? section?.class_section_id}
                </option>
              ))}
            </select>
            <div className="form-text">Leave empty to manage winners for all classes.</div>
          </div>
          <div className="col-md-3">
            <label className="form-label">Semester</label>
            <input
              className="form-control"
              value={form.semester}
              onChange={(e) => setForm((current) => ({ ...current, semester: e.target.value }))}
            />
          </div>
          <div className="col-md-3">
            <label className="form-label">School Year</label>
            <input
              className="form-control"
              value={form.school_year}
              onChange={(e) => setForm((current) => ({ ...current, school_year: e.target.value }))}
              placeholder="2025-2026"
            />
            <div className="form-text">Counts use the school year above.</div>
          </div>
          <div className="col-md-4">
            <label className="form-label">Start Date</label>
            <input
              className="form-control"
              type="date"
              value={form.start_date}
              onChange={(e) => setForm((current) => ({ ...current, start_date: e.target.value }))}
            />
          </div>
          <div className="col-md-4">
            <label className="form-label">End Date</label>
            <input
              className="form-control"
              type="date"
              value={form.end_date}
              onChange={(e) => setForm((current) => ({ ...current, end_date: e.target.value }))}
            />
          </div>

          <div className="col-12">
            <h5 className="mt-2">Winners per Class</h5>
            <div className="table-responsive">
              <table className="table table-bordered table-sm" data-no-mgmt-sticky>
                <thead className="table-light">
                  <tr>
                    <th>Class</th>
                    <th style={{ width: 140 }}>Students</th>
                    <th style={{ width: 140 }}>Auto Winners</th>
                    <th style={{ width: 150 }}>Questions</th>
                    <th style={{ width: 120 }}>1st</th>
                    <th style={{ width: 120 }}>2nd</th>
                    <th style={{ width: 120 }}>3rd</th>
                    <th style={{ width: 120 }}>4th</th>
                    <th style={{ width: 120 }}>5th</th>
                    <th style={{ width: 120 }}>6th</th>
                    <th style={{ width: 160 }}>Override</th>
                    <th style={{ width: 140 }}>Final Winners</th>
                  </tr>
                </thead>
                <tbody>
                  {visibleRows.length === 0 ? (
                    <tr>
                      <td colSpan={12} className="text-muted small">
                        No class rows found for the selected scope.
                      </td>
                    </tr>
                  ) : (
                    visibleRows.map((row) => {
                      const finalWinners =
                        row.override_winners === null || row.override_winners === undefined
                          ? row.auto_winners
                          : row.override_winners

                      return (
                        <tr key={row.class_section_id}>
                          <td>{row.class_section_name}</td>
                          <td>{row.student_count}</td>
                          <td>{row.auto_winners}</td>
                          <td>
                            <input
                              className="form-control form-control-sm"
                              type="number"
                              min="0"
                              value={normalizeRowValue(row.question_count)}
                              onChange={(e) => updateClassRow(row.class_section_id, 'question_count', e.target.value)}
                            />
                          </td>
                          {[1, 2, 3, 4, 5, 6].map((rank) => (
                            <td key={rank}>
                              <input
                                className="form-control form-control-sm"
                                type="number"
                                min="0"
                                step="0.01"
                                value={normalizeRowValue(row[`prize_${rank}` as keyof CompetitionWinnerAdminClassRow] as number | null | undefined)}
                                onChange={(e) =>
                                  updateClassRow(
                                    row.class_section_id,
                                    `prize_${rank}` as
                                      | 'prize_1'
                                      | 'prize_2'
                                      | 'prize_3'
                                      | 'prize_4'
                                      | 'prize_5'
                                      | 'prize_6',
                                    e.target.value,
                                  )
                                }
                              />
                            </td>
                          ))}
                          <td>
                            <input
                              className="form-control form-control-sm"
                              type="number"
                              min="0"
                              value={normalizeRowValue(row.override_winners)}
                              onChange={(e) => updateClassRow(row.class_section_id, 'override_winners', e.target.value)}
                            />
                          </td>
                          <td>{finalWinners}</td>
                        </tr>
                      )
                    })
                  )}
                </tbody>
              </table>
            </div>
          </div>

          <div className="col-12 d-flex gap-2">
            <button type="submit" className="btn btn-primary" disabled={saving}>
              {saving ? 'Saving...' : 'Save'}
            </button>
            <button
              type="button"
              className="btn btn-outline-secondary"
              onClick={() => navigate(COMPETITION_WINNERS_BASE)}
              disabled={saving}
            >
              Back
            </button>
          </div>
        </div>
      </form>
    </CompetitionPageShell>
  )
}
