import { defineStore } from 'pinia'
import type { Track } from '~~/types'
import Disc from '~/platine-tools/disc'
import Sampler from '~/platine-tools/sampler'
import { useCardStore } from '~/store/card'

export const usePlatineStore = defineStore('platine', () => {
  // State
  const currentTrack = ref<Track | null>(null)
  const isPlaying = ref(false)
  const isLoadingTrack = ref(false)
  const isFirstDrag = ref(true)
  const progressPercentage = ref(0)
  const currentTurns = ref(0)
  const totalTurns = ref(0)
  const isMuted = ref(false)

  // Refs pour les instances
  const disc = ref<Disc | null>(null)
  const sampler = ref<Sampler | null>(null)
  const discRef = ref<HTMLElement>()

  // Actions
  const initPlatine = (element: HTMLElement) => {
    discRef.value = element
    disc.value = new Disc(element)
    sampler.value = new Sampler()

    // Configurer les callbacks du disque
    if (disc.value) {
      disc.value.callbacks.onStop = () => {
        sampler.value?.pause()
      }

      disc.value.callbacks.onDragStart = () => {
        if (isFirstDrag.value) {
          isFirstDrag.value = false
          togglePlay()
          if (sampler.value && disc.value) {
            sampler.value.play(disc.value.secondsPlayed)
            disc.value.powerOn()
          }
        }
      }

      disc.value.callbacks.onDragEnded = () => {
        if (!isPlaying.value) return
        sampler.value?.play(disc.value?.secondsPlayed || 0)
      }

      disc.value.callbacks.onLoop = ({ playbackSpeed, isReversed, secondsPlayed }) => {
        sampler.value?.updateSpeed(playbackSpeed, isReversed, secondsPlayed)
        updateTurns()
      }
    }
  }

  const updateTurns = () => {
    if (!disc.value) return

    currentTurns.value = disc.value.secondsPlayed * 0.75
    totalTurns.value = (disc.value as any)._duration * 0.75
    progressPercentage.value = Math.min(
      100,
      (disc.value.secondsPlayed / (disc.value as any)._duration) * 100
    )
  }

  const loadTrack = async (track: Track) => {
    const cardStore = useCardStore()
    if (!sampler.value || !track) return

    currentTrack.value = track
    isLoadingTrack.value = true

    try {
      await sampler.value.loadTrack(track.filePath)
      if (disc.value) {
        disc.value.setDuration(sampler.value.duration)
        updateTurns()
        play()
      }
    } finally {
      isLoadingTrack.value = false
      cardStore.revealCard(track.id)
    }
  }

  const play = (position = 0) => {
    if (!disc.value || !sampler.value || !currentTrack.value) return

    isPlaying.value = true
    sampler.value.play(position)
    disc.value.powerOn()
  }

  const pause = () => {
    if (!disc.value || !sampler.value) return

    isPlaying.value = false
    sampler.value.pause()
    disc.value.powerOff()
  }

  const togglePlay = () => {
    if (isPlaying.value) {
      pause()
    } else {
      play()
    }
  }

  const toggleMute = () => {
    if (!sampler.value) return

    isMuted.value = !isMuted.value
    if (isMuted.value) {
      sampler.value.mute()
    } else {
      sampler.value.unmute()
    }
  }

  const seek = (position: number) => {
    if (!disc.value) return

    disc.value.secondsPlayed = position
    if (sampler.value) {
      sampler.value.play(position)
    }
  }

  // Nettoyage
  const cleanup = () => {
    if (disc.value) {
      disc.value.stop()
      disc.value.powerOff()
    }
    if (sampler.value) {
      sampler.value.pause()
    }
  }

  return {
    // State
    currentTrack,
    isPlaying,
    isLoadingTrack,
    progressPercentage,
    currentTurns,
    totalTurns,
    isMuted,

    // Getters
    coverUrl: computed(() => currentTrack.value?.coverId || '/card-dock.svg'),

    // Actions
    initPlatine,
    loadTrack,
    play,
    pause,
    togglePlay,
    toggleMute,
    seek,
    cleanup
  }
})

export default usePlatineStore
