<template>
  <div class="flex flex-col fixed right-0 top-0 z-50" :class="props.class">
    <button @click="closeDatBox" v-if="uiStore.isBoxSelected"
      class="px-4 py-2 text-black hover:text-black bg-esyellow transition-colors z-50" aria-label="close the box">
      close
    </button>
  </div>
  <div class="controls flex justify-center z-50 relative" v-bind="attrs">
    <SearchInput @search="onSearch" />
    <SelectCardRank @change="onRankChange" />
    <SelectCardSuit @change="onSuitChange" />
  </div>
  <div ref="deck" class="deck flex flex-wrap justify-center gap-4" :class="{ 'pb-36': playerStore.currentTrack }"
    @dragover.prevent @drop.prevent="handleGlobalDrop">
    <card v-for="(track, i) in filteredTracks" :key="track.id" :track="track" :tabindex="i"
      @card-click="playerStore.playPlaylistTrack(track)" :is-face-up="isCardRevealed(track.id)"
      @click-card-symbol="openCardSharer()" />
  </div>
</template>

<script setup lang="ts">
import { computed, ref, onMounted, onUnmounted } from 'vue'
import { useDataStore } from '~/store/data'
import { useCardStore } from '~/store/card'
import { usePlayerStore } from '~/store/player'
import { useUiStore } from '~/store/ui'
import type { Box, Track } from '~~/types'
import SelectCardSuit from '~/components/ui/SelectCardSuit.vue'
import SelectCardRank from '~/components/ui/SelectCardRank.vue'
import SearchInput from '~/components/ui/SearchInput.vue'

// Define the events this component emits
const emit = defineEmits<{
  (e: 'click', event: MouseEvent): void;
}>()

const props = defineProps<{
  box: Box;
  class?: string;
}>()

// Use useAttrs to get all other attributes
const attrs = useAttrs()

const cardStore = useCardStore()
const dataStore = useDataStore()
const playerStore = usePlayerStore()
const uiStore = useUiStore()

const deck = ref()
const tracks = computed(() => dataStore.getTracksByboxId(props.box.id))

// Suivre si un glisser est en cours depuis le bucket
const isDraggingFromBucket = ref(false)

// Gérer le dépôt d'une carte en dehors du bucket
const handleGlobalDrop = (e: DragEvent) => {
  if (isDraggingFromBucket.value) {
    e.preventDefault()
    e.stopPropagation()

    // Récupérer les données de la carte glissée
    const cardData = e.dataTransfer?.getData('application/json')
    if (cardData) {
      try {
        const track = JSON.parse(cardData)
        // Retirer la carte du panier
        cardStore.removeFromBucket(track.id)
        // La carte réapparaîtra automatiquement dans la playlist
        // grâce à la computed property filteredTracks
      } catch (e) {
        console.error('Erreur lors du traitement de la carte glissée', e)
      }
    }
  }
  isDraggingFromBucket.value = false
}

// Gérer le début du glisser depuis le bucket
const handleBucketDragStart = () => {
  isDraggingFromBucket.value = true
}

// Configurer les écouteurs d'événements
onMounted(() => {
  document.addEventListener('drop', handleGlobalDrop)
  document.addEventListener('dragover', (e) => e.preventDefault()) // Nécessaire pour permettre le drop
  document.addEventListener('bucket-drag-start', handleBucketDragStart)
})

// Nettoyer les écouteurs d'événements
onUnmounted(() => {
  document.removeEventListener('drop', handleGlobalDrop)
  document.removeEventListener('dragover', (e) => e.preventDefault())
  document.removeEventListener('bucket-drag-start', handleBucketDragStart)
})

// Utiliser une computed property pour filteredTracks qui réagit aux changements
const filteredTracks = computed(() => {
  let result = [...tracks.value]

  // Exclure les pistes déjà dans le panier
  result = result.filter(track => !cardStore.isInBucket(track.id))

  // Appliquer les autres filtres
  if (selectedSuit.value) {
    result = result.filter(track => track.card?.suit === selectedSuit.value)
  }

  if (selectedRank.value) {
    result = result.filter(track => track.card?.rank === selectedRank.value)
  }

  if (searchQuery.value) {
    const query = searchQuery.value.toLowerCase()
    result = result.filter(track => {
      const artistName = typeof track.artist === 'object' ? track.artist?.name : String(track.artist || '')
      return (
        track.title?.toLowerCase().includes(query) ||
        artistName.toLowerCase().includes(query) ||
        String(track.year || '').includes(query)
      )
    })
  }

  return result
})

// Variables réactives pour les filtres
const selectedSuit = ref('')
const selectedRank = ref('')
const searchQuery = ref('')

const isCardRevealed = (trackId: number) => {
  // Si une recherche est en cours, révéler automatiquement les cartes correspondantes
  if (searchQuery.value || (selectedRank.value && selectedSuit.value)) return true
  return cardStore.isCardRevealed(trackId)
}

const closeDatBox = (event: MouseEvent) => {
  uiStore.closeBox()
  emit('click', event)
}

const openCardSharer = () => {
  uiStore.openCardSharer()
}

const onSuitChange = (suit: string) => {
  selectedSuit.value = suit
  applyFilters()
}

const onRankChange = (rank: string) => {
  selectedRank.value = rank
  applyFilters()
}

const onSearch = (query: string) => {
  searchQuery.value = query
  applyFilters()
}

// Applique tous les filtres (couleur, rang et recherche)
// La computed property filteredTracks se mettra automatiquement à jour
// car elle dépend des mêmes réactifs que cette fonction
const applyFilters = () => {
  // Cette fonction ne fait plus que déclencher la réévaluation des dépendances
  // La computed property filteredTracks fera le reste
}
</script>

<style>
.deck {
  position: relative;
}
</style>
