import { type FormEvent, type ReactNode, useEffect, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { useSchoolYearOptions } from '../../hooks/useSchoolYearOptions'
import {
  fetchTrophyFinal,
  fetchTrophyProjection,
  fetchTrophyWinners,
  type TrophyFinalPayload,
  type TrophyProjectionPayload,
  type TrophyStudent,
  type TrophyWinnersClassResult,
  type TrophyWinnersPayload,
} from '../../api/trophy'

function formatScore(value?: number | null) {
  return value == null || Number.isNaN(value) ? '—' : value.toFixed(1)
}

function isMale(gender?: string | null) {
  const normalized = String(gender ?? '').trim().toLowerCase()
  return ['male', 'm', 'boy', 'boys'].includes(normalized)
}

function buildSearch(params: { school_year?: string; percentile?: string | number }) {
  const qs = new URLSearchParams()
  if (params.school_year) qs.set('school_year', String(params.school_year))
  if (params.percentile !== undefined && String(params.percentile).trim() !== '') {
    qs.set('percentile', String(params.percentile))
  }
  const value = qs.toString()
  return value ? `?${value}` : ''
}

function TrophyHeader({
  title,
  subtitle,
  actions,
}: {
  title: string
  subtitle: string
  actions?: ReactNode
}) {
  return (
    <div className="d-flex flex-wrap align-items-start justify-content-between gap-3 mb-4">
      <div>
        <h2 className="mb-1">{title}</h2>
        <p className="text-muted mb-0">{subtitle}</p>
      </div>
      {actions ? <div className="d-flex gap-2 flex-wrap">{actions}</div> : null}
    </div>
  )
}

function TrophyFilters({
  years,
  selectedYear,
  selectedPercentile,
  onSubmit,
}: {
  years: string[]
  selectedYear: string
  selectedPercentile: number
  onSubmit: (event: FormEvent<HTMLFormElement>) => void
}) {
  const { options } = useSchoolYearOptions({
    legacyYears: years,
    preferredYear: selectedYear,
  })

  return (
    <form className="row g-3 align-items-end mb-4" onSubmit={onSubmit}>
      <div className="col-md-4 col-lg-3">
        <label className="form-label">School Year</label>
        <select className="form-select" name="school_year" defaultValue={selectedYear}>
          {(options.length > 0 ? options : [{ value: selectedYear, label: selectedYear }]).map((year) => (
            <option key={year.value} value={year.value}>
              {year.label}
            </option>
          ))}
        </select>
      </div>
      <div className="col-md-4 col-lg-3">
        <label className="form-label">Percentile</label>
        <div className="input-group">
          <input
            className="form-control"
            type="number"
            min="1"
            max="99"
            step="1"
            name="percentile"
            defaultValue={Math.round(selectedPercentile)}
          />
          <span className="input-group-text">%</span>
        </div>
      </div>
      <div className="col-md-4 col-lg-2">
        <button className="btn btn-primary w-100" type="submit">
          Apply
        </button>
      </div>
    </form>
  )
}

function useTrophySearchParams() {
  const [searchParams, setSearchParams] = useSearchParams()
  const schoolYear = searchParams.get('school_year') ?? ''
  const percentile = searchParams.get('percentile') ?? ''

  function applyFilters(event: FormEvent<HTMLFormElement>) {
    event.preventDefault()
    const formData = new FormData(event.currentTarget)
    const next = new URLSearchParams()
    const year = String(formData.get('school_year') ?? '').trim()
    const pct = String(formData.get('percentile') ?? '').trim()
    if (year) next.set('school_year', year)
    if (pct) next.set('percentile', pct)
    setSearchParams(next)
  }

  return {
    schoolYear,
    percentile,
    applyFilters,
  }
}

function SummaryCard({
  label,
  value,
  detail,
  tone = 'primary',
}: {
  label: string
  value: string | number
  detail?: string
  tone?: 'primary' | 'success' | 'warning' | 'secondary' | 'info' | 'dark'
}) {
  return (
    <div className="col-6 col-lg-2">
      <div className={`card border-${tone} shadow-sm h-100`}>
        <div className="card-body py-3">
          <div className={`small text-${tone} text-uppercase fw-semibold mb-1`}>{label}</div>
          <div className="fs-3 fw-semibold">{value}</div>
          {detail ? <div className="small text-muted mt-1">{detail}</div> : null}
        </div>
      </div>
    </div>
  )
}

function StudentGenderBadge({ gender }: { gender?: string | null }) {
  const male = isMale(gender)
  return (
    <span
      className="badge"
      style={{ backgroundColor: male ? '#4A90E2' : '#E47AB0' }}
    >
      {male ? 'M' : 'F'}
    </span>
  )
}

export function TrophyProjectionPage() {
  const { schoolYear, percentile, applyFilters } = useTrophySearchParams()
  const [data, setData] = useState<TrophyProjectionPayload | null>(null)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    let cancelled = false
    setError(null)
    fetchTrophyProjection({
      school_year: schoolYear || undefined,
      percentile: percentile || undefined,
    })
      .then((payload) => {
        if (!cancelled) setData(payload)
      })
      .catch((e: unknown) => {
        if (!cancelled) {
          setError(e instanceof ApiHttpError ? e.message : 'Failed to load trophy projection.')
        }
      })
    return () => {
      cancelled = true
    }
  }, [schoolYear, percentile])

  const selectedYear = data?.selected_year ?? schoolYear
  const selectedPercentile = data?.selected_percentile ?? Number(percentile || 75)
  const search = buildSearch({ school_year: selectedYear, percentile: selectedPercentile })
  const summary = data?.summary ?? {}

  return (
    <div className="container-fluid">
      <TrophyHeader
        title="Trophy Projections"
        subtitle="Fall scores determine the projected year-end trophy threshold for each class."
        actions={
          <>
            <Link className="btn btn-warning" to={`/app/administrator/trophy_winners${search}`}>
              Reveal Winners
            </Link>
            <Link className="btn btn-success" to={`/app/administrator/trophy_final${search}`}>
              Final vs Predicted
            </Link>
          </>
        }
      />

      {error ? <div className="alert alert-danger">{error}</div> : null}

      <TrophyFilters
        years={data?.years ?? []}
        selectedYear={selectedYear}
        selectedPercentile={selectedPercentile}
        onSubmit={applyFilters}
      />

      <div className="row g-3 mb-4">
        <SummaryCard label="Classes" value={summary.classes ?? 0} tone="secondary" />
        <SummaryCard label="Students" value={summary.students ?? 0} tone="primary" />
        <SummaryCard label="Scored" value={summary.scored ?? 0} detail={`${summary.pct_scored ?? 0}% roster`} tone="success" />
        <SummaryCard label="Trophies" value={summary.trophies ?? 0} detail={`${summary.pct_trophies ?? 0}% roster`} tone="warning" />
        <SummaryCard label="Boys" value={summary.boys ?? 0} detail={`${summary.pct_boys ?? 0}%`} tone="info" />
        <SummaryCard label="Girls" value={summary.girls ?? 0} detail={`${summary.pct_girls ?? 0}%`} tone="dark" />
      </div>

      {data && data.class_results.length === 0 ? (
        <div className="alert alert-info">No class or fall-score data found for the selected school year.</div>
      ) : null}

      {data?.class_results?.length ? (
        <div className="card shadow-sm">
          <div className="card-header bg-white fw-semibold">Class Breakdown</div>
          <div className="table-responsive">
            <table className="table table-sm table-hover mb-0" data-no-mgmt-sticky>
              <thead className="table-light">
                <tr>
                  <th>Class</th>
                  <th className="text-center">Students</th>
                  <th className="text-center">Scored</th>
                  <th className="text-center">Trophies</th>
                  <th className="text-center">Boys</th>
                  <th className="text-center">Girls</th>
                  <th className="text-center">Trophy Boys</th>
                  <th className="text-center">Trophy Girls</th>
                  <th className="text-end">Threshold</th>
                </tr>
              </thead>
              <tbody>
                {data.class_results.map((row) => (
                  <tr key={row.section_id}>
                    <td className="fw-semibold">{row.section_name}</td>
                    <td className="text-center">{row.student_count}</td>
                    <td className="text-center">{row.scored_count}</td>
                    <td className="text-center">
                      <span className="badge text-bg-warning">{row.trophy_count}</span>
                    </td>
                    <td className="text-center">
                      {row.boys} <span className="text-muted small">({row.pct_boys}%)</span>
                    </td>
                    <td className="text-center">
                      {row.girls} <span className="text-muted small">({row.pct_girls}%)</span>
                    </td>
                    <td className="text-center">
                      {row.trophy_boys} <span className="text-muted small">({row.pct_trophy_boys}%)</span>
                    </td>
                    <td className="text-center">
                      {row.trophy_girls} <span className="text-muted small">({row.pct_trophy_girls}%)</span>
                    </td>
                    <td className="text-end text-muted">{formatScore(row.threshold)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      ) : null}
    </div>
  )
}

function WinnersTable({
  rows,
}: {
  rows: TrophyWinnersClassResult[]
}) {
  return (
    <>
      {rows.map((section) => (
        <section key={section.section_id} className="card shadow-sm mb-4">
          <div className="card-header d-flex flex-wrap justify-content-between gap-2">
            <div className="fw-semibold">{section.section_name}</div>
            <div className="small text-muted">
              Threshold {formatScore(section.threshold)} | {section.winners.length}/{section.student_count} winners
            </div>
          </div>
          <div className="table-responsive">
            <table className="table table-sm table-hover mb-0" data-no-mgmt-sticky>
              <thead className="table-light">
                <tr>
                  <th style={{ width: 70 }}>#</th>
                  <th>Name</th>
                  <th style={{ width: 90 }}>Gender</th>
                  <th style={{ width: 140 }}>School ID</th>
                  <th className="text-end" style={{ width: 120 }}>Fall</th>
                  <th className="text-end" style={{ width: 120 }}>Spring</th>
                  <th className="text-end" style={{ width: 120 }}>Year</th>
                </tr>
              </thead>
              <tbody>
                {section.winners.map((student, index) => (
                  <tr key={`${section.section_id}-${student.student_id ?? index}`}>
                    <td>{index + 1}</td>
                    <td className="fw-semibold">{student.name}</td>
                    <td><StudentGenderBadge gender={student.gender} /></td>
                    <td>{student.school_id ?? '—'}</td>
                    <td className="text-end">{formatScore(student.fall_score)}</td>
                    <td className="text-end">{formatScore(student.spring_score)}</td>
                    <td className="text-end">{formatScore(student.year_score)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </section>
      ))}
    </>
  )
}

export function TrophyWinnersPage() {
  const { schoolYear, percentile, applyFilters } = useTrophySearchParams()
  const [data, setData] = useState<TrophyWinnersPayload | null>(null)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    let cancelled = false
    setError(null)
    fetchTrophyWinners({
      school_year: schoolYear || undefined,
      percentile: percentile || undefined,
    })
      .then((payload) => {
        if (!cancelled) setData(payload)
      })
      .catch((e: unknown) => {
        if (!cancelled) {
          setError(e instanceof ApiHttpError ? e.message : 'Failed to load trophy winners.')
        }
      })
    return () => {
      cancelled = true
    }
  }, [schoolYear, percentile])

  const selectedYear = data?.selected_year ?? schoolYear
  const selectedPercentile = data?.selected_percentile ?? Number(percentile || 75)
  const search = buildSearch({ school_year: selectedYear, percentile: selectedPercentile })
  const summary = data?.summary ?? {}

  return (
    <div className="container-fluid">
      <TrophyHeader
        title="Trophy Winners"
        subtitle={`${selectedYear || 'Current year'} projected trophy winners at the ${Math.round(selectedPercentile)}th percentile.`}
        actions={
          <>
            <Link className="btn btn-outline-secondary" to={`/app/administrator/trophy${search}`}>
              Back to Projection
            </Link>
            <Link className="btn btn-success" to={`/app/administrator/trophy_final${search}`}>
              Final vs Predicted
            </Link>
          </>
        }
      />

      {error ? <div className="alert alert-danger">{error}</div> : null}

      <TrophyFilters
        years={data?.years ?? []}
        selectedYear={selectedYear}
        selectedPercentile={selectedPercentile}
        onSubmit={applyFilters}
      />

      <div className="row g-3 mb-4">
        <SummaryCard label="Classes" value={summary.classes ?? 0} tone="secondary" />
        <SummaryCard label="Students" value={summary.students ?? 0} tone="primary" />
        <SummaryCard label="Winners" value={summary.winners ?? 0} detail={`${summary.pct_winners ?? 0}% roster`} tone="warning" />
        <SummaryCard label="Trophy Boys" value={summary.trophy_boys ?? 0} detail={`${summary.pct_trophy_boys ?? 0}% boys`} tone="info" />
        <SummaryCard label="Trophy Girls" value={summary.trophy_girls ?? 0} detail={`${summary.pct_trophy_girls ?? 0}% girls`} tone="dark" />
      </div>

      {data && data.class_results.length === 0 ? (
        <div className="alert alert-info">No projected trophy winners found.</div>
      ) : null}

      {data?.class_results?.length ? <WinnersTable rows={data.class_results} /> : null}
    </div>
  )
}

function StatusBadge({ status }: { status?: string }) {
  if (status === 'confirmed') return <span className="badge bg-success">Confirmed</span>
  if (status === 'surprise') return <span className="badge bg-info text-dark">Surprise</span>
  if (status === 'missed') return <span className="badge text-bg-warning">Missed</span>
  return <span className="badge bg-light text-dark border">None</span>
}

function FinalStatusRows({ students }: { students: TrophyStudent[] }) {
  return students.filter((student) => student.status && student.status !== 'none')
}

export function TrophyFinalPage() {
  const { schoolYear, percentile, applyFilters } = useTrophySearchParams()
  const [data, setData] = useState<TrophyFinalPayload | null>(null)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    let cancelled = false
    setError(null)
    fetchTrophyFinal({
      school_year: schoolYear || undefined,
      percentile: percentile || undefined,
    })
      .then((payload) => {
        if (!cancelled) setData(payload)
      })
      .catch((e: unknown) => {
        if (!cancelled) {
          setError(e instanceof ApiHttpError ? e.message : 'Failed to load final trophy report.')
        }
      })
    return () => {
      cancelled = true
    }
  }, [schoolYear, percentile])

  const selectedYear = data?.selected_year ?? schoolYear
  const selectedPercentile = data?.selected_percentile ?? Number(percentile || 75)
  const search = buildSearch({ school_year: selectedYear, percentile: selectedPercentile })
  const summary = data?.summary ?? {}
  const winnerGender = data?.winner_gender_summary

  return (
    <div className="container-fluid">
      <TrophyHeader
        title="Final vs Predicted"
        subtitle="Compares fall-score trophy projections with year-end trophy outcomes."
        actions={
          <>
            <Link className="btn btn-outline-secondary" to={`/app/administrator/trophy${search}`}>
              Projection
            </Link>
            <Link className="btn btn-warning" to={`/app/administrator/trophy_winners${search}`}>
              Winners
            </Link>
          </>
        }
      />

      {error ? <div className="alert alert-danger">{error}</div> : null}

      <TrophyFilters
        years={data?.years ?? []}
        selectedYear={selectedYear}
        selectedPercentile={selectedPercentile}
        onSubmit={applyFilters}
      />

      <div className="row g-3 mb-4">
        <SummaryCard label="Predicted" value={summary.predicted ?? 0} detail={`${summary.pct_predicted ?? 0}% roster`} tone="primary" />
        <SummaryCard label="Actual" value={summary.actual ?? 0} detail={`${summary.pct_actual ?? 0}% roster`} tone="warning" />
        <SummaryCard label="Confirmed" value={summary.confirmed ?? 0} detail={`${summary.pct_confirmed_of_predicted ?? 0}% of predicted`} tone="success" />
        <SummaryCard label="Surprises" value={summary.surprises ?? 0} tone="info" />
        <SummaryCard label="Missed" value={summary.missed ?? 0} tone="dark" />
        <SummaryCard label="Accuracy" value={`${summary.accuracy ?? 0}%`} tone="secondary" />
      </div>

      {winnerGender ? (
        <div className="card shadow-sm mb-4">
          <div className="card-header bg-white fw-semibold">Winner Gender Breakdown</div>
          <div className="card-body">
            <div className="row g-3">
              <SummaryCard label="Total Winners" value={winnerGender.total} tone="secondary" />
              <SummaryCard label="Boys" value={winnerGender.boys} detail={`${winnerGender.pct_boys}%`} tone="info" />
              <SummaryCard label="Girls" value={winnerGender.girls} detail={`${winnerGender.pct_girls}%`} tone="dark" />
            </div>
          </div>
        </div>
      ) : null}

      {data && data.class_results.length === 0 ? (
        <div className="alert alert-info">No data found for the selected school year.</div>
      ) : null}

      {data?.class_results?.map((section) => {
        const rows = FinalStatusRows({ students: section.students })
        return (
          <section key={section.section_id} className="card shadow-sm mb-4">
            <div className="card-header d-flex flex-wrap justify-content-between gap-2">
              <div className="fw-semibold">{section.section_name}</div>
              <div className="small text-muted">
                Fall ≥ {formatScore(section.fall_threshold)} | Year ≥ {formatScore(section.year_threshold)} | Accuracy {section.accuracy}%
              </div>
            </div>
            <div className="table-responsive">
              <table className="table table-sm table-hover mb-0" data-no-mgmt-sticky>
                <thead className="table-light">
                  <tr>
                    <th>Name</th>
                    <th style={{ width: 90 }}>Gender</th>
                    <th className="text-end" style={{ width: 110 }}>Fall</th>
                    <th className="text-end" style={{ width: 110 }}>Spring</th>
                    <th className="text-end" style={{ width: 110 }}>Year</th>
                    <th className="text-center" style={{ width: 110 }}>Predicted</th>
                    <th className="text-center" style={{ width: 110 }}>Actual</th>
                    <th className="text-center" style={{ width: 120 }}>Status</th>
                  </tr>
                </thead>
                <tbody>
                  {rows.length === 0 ? (
                    <tr>
                      <td colSpan={8} className="text-center text-muted py-4">
                        No trophy changes in this class.
                      </td>
                    </tr>
                  ) : (
                    rows.map((student) => (
                      <tr key={`${section.section_id}-${student.student_id}`}>
                        <td className="fw-semibold">{student.name}</td>
                        <td><StudentGenderBadge gender={student.gender} /></td>
                        <td className="text-end">{formatScore(student.fall_score)}</td>
                        <td className="text-end">{formatScore(student.spring_score)}</td>
                        <td className="text-end">{formatScore(student.year_score)}</td>
                        <td className="text-center">{student.predicted ? 'Yes' : 'No'}</td>
                        <td className="text-center">{student.actual ? 'Yes' : 'No'}</td>
                        <td className="text-center"><StatusBadge status={student.status} /></td>
                      </tr>
                    ))
                  )}
                </tbody>
              </table>
            </div>
          </section>
        )
      })}
    </div>
  )
}
