import type { SchoolYearRecord } from '../api/schoolYears'

export type LegacySchoolYearValue =
  | string
  | {
      id?: number | null
      name?: string | null
      school_year?: string | null
      status?: string | null
      is_current?: boolean | null
    }

export type SchoolYearOption = {
  id?: number
  value: string
  label: string
  status?: string | null
  isCurrent: boolean
}

export function buildCalendarSchoolYear(date = new Date()): string {
  const year = date.getFullYear()
  return date.getMonth() >= 8 ? `${year}-${year + 1}` : `${year - 1}-${year}`
}

export function normalizeSchoolYearValue(value: unknown): string {
  return typeof value === 'string' ? value.trim() : ''
}

function capitalize(value: string): string {
  return value.charAt(0).toUpperCase() + value.slice(1)
}

function optionLabel(name: string, status?: string | null, isCurrent = false): string {
  const normalizedStatus = String(status ?? '').trim().toLowerCase()

  if (isCurrent) {
    return normalizedStatus && normalizedStatus !== 'active'
      ? `${name} (Current, ${capitalize(normalizedStatus)})`
      : `${name} (Current)`
  }

  if (!normalizedStatus || normalizedStatus === 'active') {
    return name
  }

  return `${name} (${capitalize(normalizedStatus)})`
}

function makeOption(
  name: string,
  status?: string | null,
  isCurrent = false,
  id?: number | null,
): SchoolYearOption | null {
  const value = normalizeSchoolYearValue(name)
  if (!value) return null

  return {
    id: id == null ? undefined : Number(id),
    value,
    label: optionLabel(value, status, isCurrent),
    status: status ?? undefined,
    isCurrent,
  }
}

function optionFromRecord(record: SchoolYearRecord): SchoolYearOption | null {
  return makeOption(record.name, record.status, Boolean(record.is_current), record.id)
}

function optionFromLegacy(value: LegacySchoolYearValue): SchoolYearOption | null {
  if (typeof value === 'string') {
    return makeOption(value)
  }

  return makeOption(
    value.name ?? value.school_year ?? '',
    value.status ?? undefined,
    Boolean(value.is_current),
    value.id,
  )
}

function compareSchoolYears(left: SchoolYearOption, right: SchoolYearOption): number {
  if (left.isCurrent !== right.isCurrent) {
    return Number(right.isCurrent) - Number(left.isCurrent)
  }

  return right.value.localeCompare(left.value, undefined, {
    numeric: true,
    sensitivity: 'base',
  })
}

export function mergeSchoolYearOptions(params: {
  canonicalYears?: SchoolYearRecord[]
  legacyYears?: LegacySchoolYearValue[]
  extraYears?: Array<string | null | undefined>
}): SchoolYearOption[] {
  const map = new Map<string, SchoolYearOption>()

  for (const record of params.canonicalYears ?? []) {
    const option = optionFromRecord(record)
    if (option) map.set(option.value, option)
  }

  for (const value of params.legacyYears ?? []) {
    const option = optionFromLegacy(value)
    if (!option || map.has(option.value)) continue
    map.set(option.value, option)
  }

  for (const extraYear of params.extraYears ?? []) {
    const option = makeOption(String(extraYear ?? ''))
    if (!option || map.has(option.value)) continue
    map.set(option.value, option)
  }

  return [...map.values()].sort(compareSchoolYears)
}

export function defaultSchoolYearOption(
  options: SchoolYearOption[],
  preferredYear?: string | null,
): string {
  const preferred = normalizeSchoolYearValue(preferredYear)
  if (preferred && options.some((option) => option.value === preferred)) {
    return preferred
  }

  const current = options.find((option) => option.isCurrent)
  if (current) return current.value

  return options[0]?.value ?? buildCalendarSchoolYear()
}

export function canonicalSchoolYearName(records: SchoolYearRecord[]): string | null {
  if (records.length === 0) return null
  const current = records.find((record) => record.is_current)
  return current?.name ?? records[0]?.name ?? null
}
