import type { Deity, Recitation, Chalisa, Katha, Scripture, Mantra, Ashtottara, Sahasranama, Stotra, Prayer, PrayerOccasion, Sukta } from './types.js'

import aartisByDeity from './aartis/index.js'
import chalisasByDeity from './chalisas/index.js'
import kathasBySlug, { type KathaSlug } from './kathas/index.js'
import scripturesBySlug, { type ScriptureSlug } from './scriptures/index.js'
import mantrasBySlug, { type MantraSlug } from './mantras/index.js'
import ashtottarasByDeity from './ashtottara/index.js'
import sahasranamasByDeity from './sahasranama/index.js'
import stotrasBySlug, { type StotraSlug } from './stotras/index.js'
import prayersBySlug, { type PrayerSlug } from './prayers/index.js'
import suktasBySlug, { type SuktaSlug } from './suktas/index.js'
import pujasBySlug, { type PujaSlug } from './puja/index.js'
import type { Puja } from './puja/types.js'
import { navadurgaForms } from './navratri/index.js'
import type { NavadurgaForm, NavratriDay } from './navratri/types.js'

const values = <T>(record: Partial<Record<Deity, T>> | Record<string, T>): T[] =>
  Object.values(record).filter((x): x is T => x !== undefined)

export function getAarti(deity: Deity): Recitation | undefined {
  return aartisByDeity[deity]
}
export function getAllAartis(): Recitation[] {
  return values(aartisByDeity)
}

export function getChalisa(deity: Deity): Chalisa | undefined {
  return chalisasByDeity[deity]
}
export function getAllChalisas(): Chalisa[] {
  return values(chalisasByDeity)
}

export function getKatha(slug: KathaSlug): Katha {
  return kathasBySlug[slug]
}
export function getAllKathas(): Katha[] {
  return values(kathasBySlug)
}
export function getKathasForDeity(deity: Deity): Katha[] {
  return values(kathasBySlug).filter((k) => k.deity === deity)
}

export function getScripture(slug: ScriptureSlug): Scripture {
  return scripturesBySlug[slug]
}
export function getAllScriptures(): Scripture[] {
  return values(scripturesBySlug)
}

export function getMantra(slug: MantraSlug): Mantra {
  return mantrasBySlug[slug]
}
export function getAllMantras(): Mantra[] {
  return values(mantrasBySlug)
}
export function getMantrasForDeity(deity: Deity): Mantra[] {
  return values(mantrasBySlug).filter((m) => m.deity === deity)
}

export function getAshtottara(deity: Deity): Ashtottara | undefined {
  return ashtottarasByDeity[deity]
}
export function getAllAshtottaras(): Ashtottara[] {
  return values(ashtottarasByDeity)
}

export function getSahasranama(deity: Deity): Sahasranama | undefined {
  return sahasranamasByDeity[deity]
}
export function getAllSahasranamas(): Sahasranama[] {
  return values(sahasranamasByDeity)
}

export function getStotra(slug: StotraSlug): Stotra {
  return stotrasBySlug[slug]
}
export function getAllStotras(): Stotra[] {
  return values(stotrasBySlug)
}
// Reverse lookup by deity: matches the primary `deity` OR any deity in the
// optional `deities` association set (so e.g. the Achyutashtakam surfaces under
// both 'vishnu' and 'krishna').
export function getStotrasForDeity(deity: Deity): Stotra[] {
  return values(stotrasBySlug).filter(
    (s) => s.deity === deity || s.deities?.includes(deity),
  )
}

export function getPrayer(slug: PrayerSlug): Prayer {
  return prayersBySlug[slug]
}
export function getAllPrayers(): Prayer[] {
  return values(prayersBySlug)
}
export function getPrayersForOccasion(occasion: PrayerOccasion): Prayer[] {
  return values(prayersBySlug).filter((p) => p.occasion === occasion)
}
export function getPrayersForDeity(deity: Deity): Prayer[] {
  return values(prayersBySlug).filter((p) => p.deity === deity)
}

export function getSukta(slug: SuktaSlug): Sukta {
  return suktasBySlug[slug]
}
export function getAllSuktas(): Sukta[] {
  return values(suktasBySlug)
}
// Reverse lookup by deity: matches the primary `deity` OR any deity in the
// optional `deities` association set.
export function getSuktasForDeity(deity: Deity): Sukta[] {
  return values(suktasBySlug).filter(
    (s) => s.deity === deity || s.deities?.includes(deity),
  )
}

export function getPuja(slug: PujaSlug): Puja {
  return pujasBySlug[slug]
}
export function getAllPujas(): Puja[] {
  return values(pujasBySlug)
}
export function getPujasForDeity(deity: Deity): Puja[] {
  return values(pujasBySlug).filter((p) => p.rosterDeity === deity)
}

export function getNavadurgaForm(day: NavratriDay): NavadurgaForm {
  return navadurgaForms[day - 1]
}
export function getAllNavadurgaForms(): NavadurgaForm[] {
  return [...navadurgaForms]
}

export function getContentForDeity(deity: Deity): {
  aarti?: Recitation
  chalisa?: Chalisa
  ashtottara?: Ashtottara
  sahasranama?: Sahasranama
  kathas: Katha[]
  mantras: Mantra[]
  stotras: Stotra[]
  prayers: Prayer[]
  suktas: Sukta[]
} {
  return {
    aarti: aartisByDeity[deity],
    chalisa: chalisasByDeity[deity],
    ashtottara: ashtottarasByDeity[deity],
    sahasranama: sahasranamasByDeity[deity],
    kathas: getKathasForDeity(deity),
    mantras: getMantrasForDeity(deity),
    stotras: getStotrasForDeity(deity),
    prayers: getPrayersForDeity(deity),
    suktas: getSuktasForDeity(deity),
  }
}

export type {
  Deity,
  Category,
  Bilingual,
  Recitation,
  RecitationVerse,
  Chalisa,
  Katha,
  KathaParagraph,
  KathaChapter,
  SamagriItem,
  Scripture,
  ScriptureVerse,
  Chapter,
  Mantra,
  Ashtottara,
  AshtottaraName,
  NamavaliName,
  Sahasranama,
  SahasranamaSection,
  Stotra,
  StotraForm,
  StotraLanguage,
  Prayer,
  PrayerOccasion,
  Sukta,
  SuktaSection,
} from './types.js'
export type { KathaSlug } from './kathas/index.js'
export type { ScriptureSlug } from './scriptures/index.js'
export type { MantraSlug } from './mantras/index.js'
export type { StotraSlug } from './stotras/index.js'
export type { PrayerSlug } from './prayers/index.js'
export type { SuktaSlug } from './suktas/index.js'
export type {
  Puja,
  PujaMantra,
  UpacharaName,
  UpacharaSlug,
  Upachara,
  ArcStep,
  PujaSamagriItem,
  PostPujaLink,
  StotraKathaRef,
  FestivalMatch,
  VariantNote,
} from './puja/types.js'
export type { PujaSlug } from './puja/index.js'
export { PUJA_DISCLAIMER } from './puja/upacharas.js'
export {
  navratriVratTiers,
  navratriVratFoods,
  kanyaPujan,
  saptashatiOutline,
  navratriColourCycle,
  navratriColourRule,
} from './navratri/index.js'
export {
  VAAR_DEVATA,
  VAAR_SOURCES,
  getVaarDevataForDate,
  getVaarDevataByKey,
  getVaarDevataByGraha,
  vaarRosterIds,
  vaarDeityNames,
} from './vaar/index.js'
export {
  JYOTIRLINGAS,
  SHAKTI_PEETHAS,
  CHAR_DHAM,
  CHOTA_CHAR_DHAM,
  SAPTA_PURI,
  SACRED_RIVERS,
  DVADASHA_JYOTIRLINGA_STOTRA,
  SAPTA_PURI_SLOKA,
  SAPTA_NADI_SLOKA,
  TIRTHA_SOURCES,
  getJyotirlingas,
  getShaktiPeethas,
  getCharDham,
  getChotaCharDham,
  getSaptaPuri,
  getSacredRivers,
  getAllTirthas,
  getTirtha,
  getTirthasForDeity,
} from './tirtha/index.js'
export {
  EKADASHIS,
  FESTIVAL_SOURCES,
  getAllFestivals,
  getEkadashis,
  getFestival,
  getFestivalsByCategory,
  getFestivalsForDeity,
} from './festivals/index.js'
export type {
  NavadurgaForm,
  NavadurgaMantra,
  DhyanaShloka,
  NavadurgaSlug,
  NavratriDay,
  VratTier,
  VratFoodList,
  KanyaAgeName,
  KanyaPujanData,
  SaptashatiChapter,
  SaptashatiCharita,
  SaptashatiDayMapEntry,
  SaptashatiOutline,
  NavratriColour,
} from './navratri/types.js'
export type {
  GrahaKey,
  DayKey,
  VaarDeity,
  VaarMantra,
  VaarVariantNote,
  VaarOffering,
  VaarDevata,
} from './vaar/types.js'
export type {
  TirthaCategory,
  TirthaEntry,
  TirthaSloka,
} from './tirtha/types.js'
export type {
  FestivalCategory,
  FestivalEntry,
  Paksha,
} from './festivals/types.js'
