import type { Box, Artist, Track } from '~/../types/types'
import { FAVORITES_BOX_ID, useFavoritesStore } from '~/store/favorites'

// stores/data.ts
import { defineStore } from 'pinia'
import { useUiStore } from '~/store/ui'

export const useDataStore = defineStore('data', {
  state: () => ({
    boxes: [] as Box[], // Store your box data here
    artists: [] as Artist[], // Store artist data here
    tracks: [] as Track[], // Store track data here
    isLoaded: false, // Remember if data is already loaded
    isLoading: true
  }),

  actions: {
    async loadData() {
      if (this.isLoaded) return
      this.isLoading = true
      try {
        this.boxes = await $fetch<Box[]>('/api/boxes')
        this.artists = await $fetch<Artist[]>('/api/artists')
        const compilationTracks = await $fetch<Track[]>('/api/tracks/compilation')
        const playlistTracks = await $fetch<Track[]>('/api/tracks/playlist')

        // Mapper les tracks pour remplacer l'artist avec un objet Artist cohérent
        const artistMap = new Map(this.artists.map((a) => [a.id, a]))
        const allTracks = [...(compilationTracks ?? []), ...(playlistTracks ?? [])]

        this.tracks = allTracks.map((track) => {
          const a = track.artist as unknown
          let artistObj: Artist
          if (typeof a === 'number') {
            artistObj = artistMap.get(a) ?? { id: a, name: String(a), url: '', coverId: '' }
          } else if (typeof a === 'string') {
            artistObj = { id: 0, name: a, url: '', coverId: '' }
          } else if (a && typeof a === 'object' && 'id' in (a as any)) {
            const idVal = (a as any).id as number | undefined
            artistObj = idVal != null ? artistMap.get(idVal) ?? (a as Artist) : (a as Artist)
          } else {
            artistObj = { id: 0, name: '', url: '', coverId: '' }
          }

          return {
            ...track,
            artist: artistObj
          }
        })
        const favBox: Box = {
          id: FAVORITES_BOX_ID,
          type: 'playlist',
          name: 'Favoris',
          duration: 0,
          tracks: [],
          description: '',
          color1: '#0f172a',
          color2: '#1e293b',
          color3: '#334155',
          state: 'box-list'
        }
        if (!this.boxes.find((b) => b.id === FAVORITES_BOX_ID)) {
          this.boxes = [favBox, ...this.boxes]
        }
        this.isLoaded = true
      } finally {
        this.isLoading = false
      }
    }
  },

  getters: {
    // Obtenir toutes les boxes
    getBoxById: (state) => {
      return (id: string) => {
        return state.boxes.find((box) => box.id === id)
      }
    },
    // Obtenir toutes les pistes d'une box donnée
    getTracksByboxId: (state) => (id: string) => {
      if (id === FAVORITES_BOX_ID) {
        const fav = useFavoritesStore()
        return fav.trackIds
          .map((tid) => state.tracks.find((t) => t.id === tid))
          .filter((t): t is Track => !!t)
      }
      return state.tracks.filter((track) => track.boxId === id)
    },
    // Filtrer les artistes selon certains critères
    getArtistById: (state) => (id: number) => state.artists.find((artist) => artist.id === id),

    // Obtenir toutes les pistes d'un artiste donné
    getTracksByArtistId: (state) => (artistId: number) => {
      return state.tracks.filter(
        (track) =>
          typeof track.artist === 'object' &&
          !!track.artist &&
          'id' in track.artist &&
          (track.artist as Artist).id === artistId
      )
    },
    getFirstTrackOfBox() {
      return (box: Box) => {
        const tracks = this.getTracksByboxId(box.id)
          .slice()
          .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
        return tracks.length > 0 ? tracks[0] : null
      }
    },
    getNextPlaylistTrack: (state) => {
      return (track: Track) => {
        const tracksInPlaylist = state.tracks
          .filter((t) => t.boxId === track.boxId)
          .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))

        const index = tracksInPlaylist.findIndex((t) => t.id === track.id)
        return index >= 0 && index < tracksInPlaylist.length - 1
          ? tracksInPlaylist[index + 1]
          : null
      }
    },
    getNextTrack: (state) => {
      return (track: Track) => {
        // Récupérer toutes les tracks de la même box et les trier par ordre
        const tracksInBox = state.tracks
          .filter((t) => t.boxId === track.boxId)
          .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))

        // Trouver l’index de la track courante
        const index = tracksInBox.findIndex((t) => t.id === track.id)
        // Retourner la track suivante ou null si c’est la dernière
        return index >= 0 && index < tracksInBox.length - 1 ? tracksInBox[index + 1] : null
      }
    },
    getPrevTrack: (state) => {
      return (track: Track) => {
        const tracksInBox = state.tracks
          .filter((t) => t.boxId === track.boxId)
          .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))

        const index = tracksInBox.findIndex((t) => t.id === track.id)
        return index > 0 ? tracksInBox[index - 1] : null
      }
    }
  }
})
