import { useEffect, useMemo, useState } from 'react'
import { fetchSchoolYears, type SchoolYearRecord } from '../api/schoolYears'
import {
  defaultSchoolYearOption,
  mergeSchoolYearOptions,
  type LegacySchoolYearValue,
} from '../lib/schoolYearOptions'

let cachedSchoolYears: SchoolYearRecord[] | null = null
let cachedSchoolYearsPromise: Promise<SchoolYearRecord[]> | null = null

async function loadCanonicalSchoolYears(): Promise<SchoolYearRecord[]> {
  if (cachedSchoolYears) return cachedSchoolYears

  if (!cachedSchoolYearsPromise) {
    cachedSchoolYearsPromise = fetchSchoolYears()
      .then((years) => {
        cachedSchoolYears = years
        return years
      })
      .finally(() => {
        cachedSchoolYearsPromise = null
      })
  }

  return cachedSchoolYearsPromise
}

export function useSchoolYearOptions({
  legacyYears,
  preferredYear,
  enabled = true,
}: {
  legacyYears?: LegacySchoolYearValue[]
  preferredYear?: string | null
  enabled?: boolean
}) {
  const [canonicalYears, setCanonicalYears] = useState<SchoolYearRecord[]>(cachedSchoolYears ?? [])

  useEffect(() => {
    if (!enabled) return

    if (cachedSchoolYears) {
      setCanonicalYears(cachedSchoolYears)
      return
    }

    let cancelled = false
    loadCanonicalSchoolYears()
      .then((years) => {
        if (!cancelled) setCanonicalYears(years)
      })
      .catch(() => {
        if (!cancelled) setCanonicalYears([])
      })

    return () => {
      cancelled = true
    }
  }, [enabled])

  const options = useMemo(
    () =>
      mergeSchoolYearOptions({
        canonicalYears,
        legacyYears,
        extraYears: [preferredYear],
      }),
    [canonicalYears, legacyYears, preferredYear],
  )

  const selectedYear = useMemo(
    () => defaultSchoolYearOption(options, preferredYear),
    [options, preferredYear],
  )

  const currentYear = useMemo(
    () => options.find((option) => option.isCurrent)?.value ?? selectedYear,
    [options, selectedYear],
  )

  return {
    canonicalYears,
    currentYear,
    options,
    selectedYear,
  }
}
