import type { Song } from '~/types/song'
import type { ChapterSongLink, ChapterPageLink, BookConfig } from '~/types/book'

let _configCache: BookConfig | null = null

async function loadConfig(): Promise<BookConfig> {
  if (_configCache) return _configCache

  const parsed = await $fetch<any>('/api/content/config')

  _configCache = {
    title: parsed.book.title,
    author: parsed.book.author,
    description: parsed.book.description,
    coverImage: parsed.book.coverImage,
    pdfFile: parsed.book.pdfFile,
    chapters: [],
    songs: parsed.songs as Song[],
    chapterSongs: parsed.chapterSongs as ChapterSongLink[],
    chapterPages: (parsed.chapterPages ?? []) as ChapterPageLink[],
    defaultPlaylistOrder: parsed.defaultPlaylistOrder as string[],
  }

  return _configCache
}

export function useBookData() {
  const config = ref<BookConfig | null>(null)
  const isLoaded = ref(false)

  async function init() {
    if (isLoaded.value) return
    config.value = await loadConfig()
    isLoaded.value = true
  }

  function getSongs(): Song[] {
    return config.value?.songs ?? []
  }

  function getSongById(id: string): Song | undefined {
    return config.value?.songs.find(s => s.id === id)
  }

  function getChapterSongs(chapterSlug: string): Song[] {
    if (!config.value) return []
    const links = config.value.chapterSongs.filter(cs => cs.chapterSlug === chapterSlug)
    return links
      .map(link => config.value!.songs.find(s => s.id === link.songId))
      .filter((s): s is Song => !!s)
  }

  function getPrimarySong(chapterSlug: string): Song | undefined {
    if (!config.value) return undefined
    const link = config.value.chapterSongs.find(
      cs => cs.chapterSlug === chapterSlug && cs.primary,
    )
    if (!link) return undefined
    return config.value.songs.find(s => s.id === link.songId)
  }

  function getChapterSongLinks(chapterSlug: string): ChapterSongLink[] {
    return config.value?.chapterSongs.filter(cs => cs.chapterSlug === chapterSlug) ?? []
  }

  function getPlaylistOrder(): Song[] {
    if (!config.value) return []
    return config.value.defaultPlaylistOrder
      .map(id => config.value!.songs.find(s => s.id === id))
      .filter((s): s is Song => !!s)
  }

  function getChapterForSong(songId: string): string | undefined {
    if (!config.value) return undefined
    const link = config.value.chapterSongs.find(
      cs => cs.songId === songId && cs.primary,
    )
    return link?.chapterSlug
  }

  function getChapterPage(chapterSlug: string): number | undefined {
    return config.value?.chapterPages.find(cp => cp.chapterSlug === chapterSlug)?.page
  }

  function getPdfUrl(): string {
    return config.value?.pdfFile || '/pdf/une-economie-du-don.pdf'
  }

  function getBookMeta() {
    if (!config.value) return null
    return {
      title: config.value.title,
      author: config.value.author,
      description: config.value.description,
      coverImage: config.value.coverImage,
    }
  }

  return {
    config,
    isLoaded,
    init,
    getSongs,
    getSongById,
    getChapterSongs,
    getPrimarySong,
    getChapterSongLinks,
    getChapterForSong,
    getPlaylistOrder,
    getBookMeta,
    getChapterPage,
    getPdfUrl,
  }
}
