// ~/store/player.ts
import { defineStore } from 'pinia'
import type { Track, Box } from '~/../types/types'
import { useDataStore } from '~/store/data'
import { useCardStore } from '~/store/card'
import { usePlatineStore } from '~/store/platine'

export const usePlayerStore = defineStore('player', {
  state: () => ({
    currentTrack: null as Track | null,
    position: 0,
    progressionLast: 0,
    isLoading: false,
    history: [] as string[]
  }),

  actions: {
    attachAudio() {
      const platineStore = usePlatineStore()

      // Écouter les changements de piste dans le platineStore
      watch(
        () => platineStore.currentTrack,
        (newTrack) => {
          if (newTrack) {
            this.currentTrack = newTrack
            // Révéler la carte quand la lecture commence
            const cardStore = useCardStore()
            if (!cardStore.isCardRevealed(newTrack.id)) {
              requestAnimationFrame(() => {
                cardStore.revealCard(newTrack.id)
              })
            }
          } else {
            this.currentTrack = null
          }
        }
      )

      // Écouter les changements d'état de lecture
      watch(
        () => platineStore.isPlaying,
        (isPlaying) => {
          if (isPlaying) {
            // Gérer la logique de lecture suivante quand la lecture se termine
            if (platineStore.currentTrack?.type === 'playlist') {
              const dataStore = useDataStore()
              const nextTrack = dataStore.getNextPlaylistTrack(platineStore.currentTrack)
              if (nextTrack) {
                platineStore.loadTrack(nextTrack)
                platineStore.play()
              }
            }
          }
        }
      )
    },

    async playBox(box: Box) {
      const platineStore = usePlatineStore()

      // Si c'est la même box, on toggle simplement la lecture
      if (this.currentTrack?.boxId === box.id && this.currentTrack?.side === box.activeSide) {
        platineStore.togglePlay()
        return
      }

      // Sinon, on charge la première piste de la box
      try {
        const dataStore = useDataStore()
        const firstTrack = dataStore.getFirstTrackOfBox(box)
        if (firstTrack) {
          this.currentTrack = firstTrack
          await platineStore.loadTrack(firstTrack)
          await platineStore.play()
        }
      } catch (error) {
        console.error('Error playing box:', error)
      }
    },

    async playTrack(track: Track) {
      const platineStore = usePlatineStore()
      // Si c'est la même piste, on toggle simplement la lecture
      if (this.currentTrack?.id === track.id) {
        platineStore.togglePlay()
        return
      }

      // Sinon, on charge et on lit la piste
      this.currentTrack = track
      await platineStore.loadTrack(track)
      platineStore.play()
    },

    async playCompilationTrack(track: Track) {
      const platineStore = usePlatineStore()

      // Si c'est la même piste, on toggle simplement la lecture
      if (this.currentTrack?.id === track.id) {
        platineStore.togglePlay()
        return
      }

      // Pour les compilations, on charge la piste avec le point de départ
      this.currentTrack = track
      await platineStore.loadTrack(track)

      // Si c'est une compilation, on définit la position de départ
      if (track.type === 'compilation' && track.start !== undefined) {
        platineStore.seek(track.start)
      }

      platineStore.play()
    },

    async playPlaylistTrack(track: Track) {
      const platineStore = usePlatineStore()

      // Toggle simple si c'est la même piste
      if (this.currentTrack?.id === track.id) {
        platineStore.togglePlay()
        return
      }

      // Sinon, on charge et on lit la piste
      this.currentTrack = track
      await platineStore.loadTrack(track)
      platineStore.play()
    },

    async loadTrack(track: Track) {
      const platineStore = usePlatineStore()
      await platineStore.loadTrack(track)
    },

    async loadAndPlayTrack(track: Track) {
      const platineStore = usePlatineStore()

      try {
        this.isLoading = true

        // Charger la piste
        await platineStore.loadTrack(track)

        // Pour les compilations, on définit la position de départ
        if (track.type === 'compilation' && track.start !== undefined) {
          platineStore.seek(track.start)
        }

        // Lancer la lecture
        await platineStore.play()
        this.history.push(track.id.toString()) // S'assurer que l'ID est une chaîne
        this.isLoading = false
      } catch (error) {
        console.error('Error loading/playing track:', error)
        this.isLoading = false
      }
    },

    togglePlay() {
      const platineStore = usePlatineStore()
      platineStore.togglePlay()
    },

    updateTime() {
      const platineStore = usePlatineStore()

      // Mettre à jour la position actuelle
      if (platineStore.currentTrack) {
        this.position = platineStore.currentTurns / 0.75 // Convertir les tours en secondes

        // Calculer et mettre en cache la progression
        const duration = platineStore.totalTurns / 0.75 // Durée totale en secondes
        const progression = (this.position / duration) * 100
        if (!isNaN(progression) && isFinite(progression)) {
          this.progressionLast = progression
        }
      }
    },

    // update current track when changing time in compilation
    async updateCurrentTrack() {
      const platineStore = usePlatineStore()
      const currentTrack = this.currentTrack
      if (currentTrack && currentTrack.type === 'compilation') {
        const dataStore = useDataStore()
        const tracks = dataStore
          .getTracksByboxId(currentTrack.boxId, currentTrack.side)
          .slice()
          .filter((t) => t.type === 'compilation')
          .sort((a, b) => (a.start ?? 0) - (b.start ?? 0))

        if (tracks.length > 0) {
          const now = platineStore.currentTurns / 0.75
          // find the last track whose start <= now (fallback to first track)
          let nextTrack = tracks[0]
          for (const t of tracks) {
            const s = t.start ?? 0
            if (s <= now) {
              nextTrack = t
            } else {
              break
            }
          }
          if (nextTrack && nextTrack.id !== currentTrack.id) {
            // only update metadata reference; do not reload audio
            this.currentTrack = nextTrack

            // Révéler la carte avec une animation fluide
            const cardStore = useCardStore()
            if (nextTrack.id && !cardStore.isCardRevealed(nextTrack.id)) {
              // Utiliser requestAnimationFrame pour une meilleure synchronisation avec le rendu
              requestAnimationFrame(() => {
                cardStore.revealCard(nextTrack.id)
              })
            }
          }
        }
      }
    }
  },

  getters: {
    isCurrentBox: (state) => {
      return (box: Box) => {
        if (box.type === 'compilation') {
          return box.id === state.currentTrack?.boxId && box.activeSide === state.currentTrack?.side
        } else {
          return box.id === state.currentTrack?.boxId
        }
      }
    },

    isCurrentSide: (state) => {
      return (side: string) => side === state.currentTrack?.side
    },

    isPlaylistTrack: () => {
      return (track: Track) => {
        return track.type === 'playlist'
      }
    },

    isCompilationTrack: () => {
      return (track: Track) => {
        return track.type === 'compilation'
      }
    },

    isPaused() {
      const platineStore = usePlatineStore()
      return !platineStore.isPlaying
    },

    getCurrentTrack: (state) => state.currentTrack,

    getCurrentBox: (state) => {
      return state.currentTrack ? state.currentTrack.boxId : null
    },

    getCurrentProgression() {
      const platineStore = usePlatineStore()
      if (!platineStore.currentTrack) return 0

      // Calculer la progression en fonction des tours actuels et totaux
      if (platineStore.totalTurns > 0) {
        return (platineStore.currentTurns / platineStore.totalTurns) * 100
      }
      return 0
    },

    getCurrentCoverUrl(state) {
      const id = state.currentTrack?.coverId
      if (!id) return null
      return id.startsWith('http') ? id : `https://f4.bcbits.com/img/${id}_4.jpg`
    }
  }
})
