import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import {
  exportAdminCompetitionWinnerQuiz,
  fetchAdminCompetitionWinnersIndex,
  lockAdminCompetitionWinner,
  unlockAdminCompetitionWinner,
} from '../../api/session'
import type { CompetitionWinnerAdminCompetitionRow } from '../../api/types'
import { ApiScopeNote, CompetitionPageShell, COMPETITION_WINNERS_BASE } from './competitionWinnersShared'

function toFiniteNumber(value: unknown): number | null {
  const n = typeof value === 'number' ? value : Number(value)
  return Number.isFinite(n) ? n : null
}

function competitionId(row: CompetitionWinnerAdminCompetitionRow): number | null {
  return toFiniteNumber(row.id ?? row.competition_id)
}

export function CompetitionWinnersIndexPage() {
  const [rows, setRows] = useState<CompetitionWinnerAdminCompetitionRow[]>([])
  const [sectionMap, setSectionMap] = useState<Record<string, string>>({})
  const [message, setMessage] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [busyAction, setBusyAction] = useState<string | null>(null)

  async function load() {
    try {
      const response = await fetchAdminCompetitionWinnersIndex()
      if (!response.ok) {
        setError(response.message ?? 'Unable to load competition winners data.')
        return
      }

      setRows(response.competitions ?? [])
      setSectionMap(response.sectionMap ?? {})
      setError(null)
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Unable to load competition winners data.')
    }
  }

  useEffect(() => {
    void load()
  }, [])

  async function handleExport(row: CompetitionWinnerAdminCompetitionRow) {
    const id = competitionId(row)
    if (id === null) {
      setError('This competition does not have a valid id yet.')
      return
    }

    try {
      setBusyAction(`export:${id}`)
      setMessage(null)
      const result = await exportAdminCompetitionWinnerQuiz(id, {
        class_section_id: toFiniteNumber(row.class_section_id),
      })
      if (!result.ok) {
        setError(result.message ?? 'Unable to export competition scores to quiz.')
        return
      }
      setMessage(result.message ?? 'Competition scores exported to quiz.')
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Unable to export competition scores to quiz.')
    } finally {
      setBusyAction(null)
    }
  }

  async function handleLockToggle(row: CompetitionWinnerAdminCompetitionRow) {
    const id = competitionId(row)
    if (id === null) {
      setError('This competition does not have a valid id yet.')
      return
    }

    try {
      setBusyAction(`lock:${id}`)
      setMessage(null)
      const result = row.is_locked
        ? await unlockAdminCompetitionWinner(id)
        : await lockAdminCompetitionWinner(id)
      if (!result.ok) {
        setError(result.message ?? 'Unable to update competition lock state.')
        return
      }
      setMessage(result.message ?? (row.is_locked ? 'Competition unlocked.' : 'Competition locked.'))
      await load()
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Unable to update competition lock state.')
    } finally {
      setBusyAction(null)
    }
  }

  return (
    <CompetitionPageShell title="Competition Winners">
      <ApiScopeNote>
        Admin competition management now uses dedicated Laravel endpoints. Draft competitions keep working here, and preview
        is no longer limited to published rows.
      </ApiScopeNote>
      {error ? <div className="alert alert-danger">{error}</div> : null}
      {message ? <div className="alert alert-success">{message}</div> : null}

      <div className="d-flex justify-content-between align-items-center mb-3 flex-wrap gap-2">
        <div />
        <Link className="btn btn-primary" to={`${COMPETITION_WINNERS_BASE}/create`}>
          + New Competition
        </Link>
      </div>

      <div className="table-responsive">
        <table className="table table-bordered table-sm align-middle mb-0" data-no-mgmt-sticky>
          <thead className="table-light">
            <tr>
              <th>ID</th>
              <th>Title</th>
              <th>Class Section</th>
              <th>Winners Rule</th>
              <th>Published</th>
              <th>Locked</th>
              <th>Actions</th>
            </tr>
          </thead>
          <tbody>
            {rows.length === 0 ? (
              <tr>
                <td colSpan={7} className="text-muted">
                  No competitions found.
                </td>
              </tr>
            ) : (
              rows.map((row) => {
                const id = competitionId(row)
                const sectionId = toFiniteNumber(row.class_section_id) ?? 0
                const sectionName =
                  sectionId > 0 ? (sectionMap[String(sectionId)] ?? String(sectionId)) : 'All'
                const title = String(row.title ?? (id !== null ? `Competition #${id}` : 'Competition'))
                const exportBusy = busyAction === `export:${id}`
                const lockBusy = busyAction === `lock:${id}`

                return (
                  <tr key={id !== null ? String(id) : `${title}-${sectionId}`}>
                    <td>{id ?? '—'}</td>
                    <td>{title}</td>
                    <td>{sectionName}</td>
                    <td>Tiered per class</td>
                    <td>{row.is_published ? 'Yes' : 'No'}</td>
                    <td>{row.is_locked ? 'Yes' : 'No'}</td>
                    <td>
                      <div className="d-flex flex-wrap gap-1">
                        {id !== null ? (
                          <>
                            <Link
                              className="btn btn-sm btn-outline-secondary"
                              to={`${COMPETITION_WINNERS_BASE}/${id}/settings`}
                            >
                              Settings
                            </Link>
                            <Link className="btn btn-sm btn-outline-primary" to={`${COMPETITION_WINNERS_BASE}/${id}`}>
                              Enter Scores
                            </Link>
                            <Link
                              className="btn btn-sm btn-outline-secondary"
                              to={`${COMPETITION_WINNERS_BASE}/${id}/preview`}
                            >
                              Preview
                            </Link>
                            <Link
                              className="btn btn-sm btn-outline-secondary"
                              to={`${COMPETITION_WINNERS_BASE}/${id}/winners`}
                            >
                              Winners
                            </Link>
                          </>
                        ) : (
                          <span className="text-muted small me-2">Invalid competition id</span>
                        )}
                        <button
                          type="button"
                          className="btn btn-sm btn-outline-success"
                          disabled={id === null || exportBusy || lockBusy}
                          onClick={() => void handleExport(row)}
                        >
                          {exportBusy ? 'Exporting...' : 'Export Scores to Quiz'}
                        </button>
                        <button
                          type="button"
                          className={`btn btn-sm ${row.is_locked ? 'btn-outline-warning' : 'btn-outline-danger'}`}
                          disabled={id === null || exportBusy || lockBusy}
                          onClick={() => void handleLockToggle(row)}
                        >
                          {lockBusy ? 'Saving...' : row.is_locked ? 'Unlock' : 'Lock'}
                        </button>
                      </div>
                    </td>
                  </tr>
                )
              })
            )}
          </tbody>
        </table>
      </div>
    </CompetitionPageShell>
  )
}
