<template>
  <article role="button" @click.stop="cardClick" @keydown.enter.stop="cardClick" @keydown.space.prevent.stop="cardClick"
    @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" class="card" :class="[
      isFaceUp ? 'face-up' : 'face-down',
      { 'current-track': playerStore.currentTrack?.id === track.id },
      { 'is-dragging': isDragging }
    ]">
    <div class="flip-inner" ref="cardElement">
      <!-- Face-Up -->
      <main draggable="true" @dragstart="dragStart" @dragend="dragEnd"
        class="face-up backdrop-blur-sm border-2 z-10 card w-56 h-80 p-3 hover:shadow-xl hover:scale-110 transition-all rounded-2xl shadow-lg flex flex-col overflow-hidden">

        <div v-if="isPlaylistTrack" class="flex items-center justify-center size-7 absolute top-7 left-7">
          <div class="suit text-7xl absolute"
            :class="[isRedCard ? 'text-red-600' : 'text-slate-800', props.track.card?.suit]">
            <img draggable="false" :src="`/${props.track.card?.suit}.svg`" />
          </div>
          <div class="rank text-white font-bold absolute -mt-1">
            {{ props.track.card?.rank }}
          </div>
        </div>

        <div v-else class="flex items-center justify-center size-7 absolute top-6 left-6">
          <div class="rank text-white font-bold absolute -mt-1">
            {{ props.track.order }}
          </div>
        </div>

        <!-- Cover -->
        <figure class="pochette flex-1 flex justify-center items-center overflow-hidden rounded-xl cursor-pointer">
          <playButton :objectToPlay="track" />
          <img draggable="false" v-if="isFaceUp" :src="coverUrl" alt="Pochette de l'album" loading="lazy"
            class="w-full h-full object-cover object-center" />
        </figure>

        <!-- Body -->
        <div
          class="card-body p-3 text-center bg-white rounded-b-xl opacity-0 -mt-16 hover:opacity-100 hover:-mt-0 transition-all duration-300">
          <div v-if="isOrder" class="label">
            {{ props.track.order }}
          </div>
          <h2 class="select-text text-sm text-neutral-500 first-letter:uppercase truncate">
            {{ props.track.title || 'title' }}
          </h2>
          <p v-if="isPlaylistTrack" class="select-text text-base text-neutral-800 font-bold capitalize truncate">
            {{ props.track.artist.name || 'artist' }}
          </p>
        </div>
      </main>

      <!-- Face-Down -->
      <footer
        class="face-down backdrop-blur-sm z-10 card w-56 h-80 p-3 bg-opacity-10 bg-white rounded-2xl shadow-lg flex flex-col overflow-hidden">
        <figure class="h-full flex text-center rounded-xl justify-center cursor-pointer"
          :style="{ backgroundColor: cardColor }">
          <playButton :objectToPlay="track" />
          <img draggable="false" src="/face-down.svg" />
        </figure>
      </footer>
    </div>
  </article>

  <!-- Clone fantôme pour le drag tactile -->
  <Teleport to="body">
    <div v-if="isDragging && touchClone" ref="ghostElement"
      class="ghost-card fixed pointer-events-none z-[9999] w-56 h-80" :style="{
        left: touchClone.x + 'px',
        top: touchClone.y + 'px',
        transform: 'translate(-50%, -50%)'
      }">
      <div class="flip-inner">
        <main
          class="face-up backdrop-blur-sm border-2 z-10 card w-56 h-80 p-3 rounded-2xl shadow-2xl flex flex-col overflow-hidden bg-white bg-opacity-90">

          <div v-if="isPlaylistTrack" class="flex items-center justify-center size-7 absolute top-7 left-7">
            <div class="suit text-7xl absolute"
              :class="[isRedCard ? 'text-red-600' : 'text-slate-800', props.track.card?.suit]">
              <img draggable="false" :src="`/${props.track.card?.suit}.svg`" />
            </div>
            <div class="rank text-white font-bold absolute -mt-1">
              {{ props.track.card?.rank }}
            </div>
          </div>
          <figure class="pochette flex-1 flex justify-center items-center overflow-hidden rounded-xl">
            <img draggable="false" :src="coverUrl" alt="Pochette de l'album"
              class="w-full h-full object-cover object-center" />
          </figure>
        </main>
      </div>
    </div>
  </Teleport>
</template>

<script setup lang="ts">
import type { Track } from '~~/types/types'
import { usePlayerStore } from '~/store/player'
import { useDataStore } from '~/store/data';

const props = withDefaults(defineProps<{
  track?: Track;
  isFaceUp?: boolean;
}>(), {
  track: () => {
    const dataStore = useDataStore();
    return dataStore.getRandomPlaylistTrack() || {} as Track;
  },
  isFaceUp: true,
})

const playerStore = usePlayerStore()
const isManifesto = computed(() => props.track.boxId.startsWith('ES00'))
const isOrder = computed(() => props.track.order && !isManifesto)
const isPlaylistTrack = computed(() => props.track.type === 'playlist')
const isRedCard = computed(() => (props.track.card?.suit === '♥' || props.track.card?.suit === '♦'))
const dataStore = useDataStore()
const cardColor = computed(() => dataStore.getYearColor(props.track.year || 0))
const coverUrl = computed(() => props.track.coverId || '/card-dock.svg')

const isDragging = ref(false)
const cardElement = ref<HTMLElement | null>(null)
const ghostElement = ref<HTMLElement | null>(null)

// État pour le tactile
const touchClone = ref<{ x: number, y: number } | null>(null)
const touchStartPos = ref<{ x: number, y: number } | null>(null)
const longPressTimer = ref<number | null>(null)
const LONG_PRESS_DURATION = 200 // ms
const hasMovedDuringPress = ref(false)

const cardClick = () => {
  if (!isDragging.value && !hasMovedDuringPress.value) {
    console.log('card click')
    playerStore.playTrack(props.track)
  }
  hasMovedDuringPress.value = false
}

// Drag desktop
const dragStart = (event: DragEvent) => {
  if (event.dataTransfer && cardElement.value) {
    event.dataTransfer.effectAllowed = 'move';
    event.dataTransfer.setData('application/json', JSON.stringify(props.track));
    isDragging.value = true
  }
};

const instance = getCurrentInstance();
const dragEnd = (event: DragEvent) => {
  isDragging.value = false

  if (event.dataTransfer?.dropEffect === 'move' && instance?.vnode?.el?.parentNode) {
    instance.vnode.el.parentNode.removeChild(instance.vnode.el);
    const parent = instance.parent;
    if (parent?.update) {
      parent.update();
    }
  }
}

// Touch events
const touchStart = (event: TouchEvent) => {
  const touch = event.touches[0]
  touchStartPos.value = { x: touch.clientX, y: touch.clientY }
  hasMovedDuringPress.value = false

  // Démarrer un timer pour le long press
  longPressTimer.value = window.setTimeout(() => {
    startTouchDrag(touch)
  }, LONG_PRESS_DURATION)
}

const startTouchDrag = (touch: Touch) => {
  isDragging.value = true
  touchClone.value = {
    x: touch.clientX,
    y: touch.clientY
  }

  // Vibration feedback si disponible
  if (navigator.vibrate) {
    navigator.vibrate(50)
  }
}

const touchMove = (event: TouchEvent) => {
  if (longPressTimer.value) {
    // Annuler le long press si l'utilisateur bouge trop
    const touch = event.touches[0]
    const dx = touch.clientX - (touchStartPos.value?.x || 0)
    const dy = touch.clientY - (touchStartPos.value?.y || 0)
    const distance = Math.sqrt(dx * dx + dy * dy)

    if (distance > 10) {
      clearTimeout(longPressTimer.value)
      longPressTimer.value = null
      hasMovedDuringPress.value = true
    }
  }

  if (isDragging.value && touchClone.value) {
    event.preventDefault()
    const touch = event.touches[0]
    touchClone.value = {
      x: touch.clientX,
      y: touch.clientY
    }

    // Déterminer l'élément sous le doigt
    checkDropTarget(touch.clientX, touch.clientY)
  }
}

const touchEnd = (event: TouchEvent) => {
  if (longPressTimer.value) {
    clearTimeout(longPressTimer.value)
    longPressTimer.value = null
  }

  if (isDragging.value) {
    event.preventDefault()
    const touch = event.changedTouches[0]

    // Trouver l'élément de drop
    const dropTarget = document.elementFromPoint(touch.clientX, touch.clientY)
    const bucket = dropTarget?.closest('.bucket')

    // Nettoyer les classes de drop target
    document.querySelectorAll('.bucket').forEach(b => {
      b.classList.remove('drop-target-active')
    })

    if (bucket) {
      // Émettre un événement personnalisé pour le bucket
      const dropEvent = new CustomEvent('card-dropped-touch', {
        detail: props.track,
        bubbles: true
      })
      bucket.dispatchEvent(dropEvent)

      // Vibration de confirmation
      if (navigator.vibrate) {
        navigator.vibrate(100)
      }

      // Supprimer la carte
      if (instance?.vnode?.el?.parentNode) {
        instance.vnode.el.parentNode.removeChild(instance.vnode.el);
        const parent = instance.parent;
        if (parent?.update) {
          parent.update();
        }
      }
    }

    isDragging.value = false
    touchClone.value = null
  }
}

const checkDropTarget = (x: number, y: number) => {
  const element = document.elementFromPoint(x, y)
  const bucket = element?.closest('.bucket')

  if (bucket) {
    bucket.classList.add('drop-target-active')
  } else {
    document.querySelectorAll('.bucket').forEach(b => {
      b.classList.remove('drop-target-active')
    })
  }
}

// Cleanup
onUnmounted(() => {
  if (longPressTimer.value) {
    clearTimeout(longPressTimer.value)
  }
})
</script>

<style lang="scss">
.label {
  @apply rounded-full size-7 p-2 bg-esyellow leading-3 -mt-6;
  font-weight: bold;
  text-align: center;
}

.♠,
.♣,
.♦,
.♥ {
  @apply text-5xl size-14;
}

/* Flip effect */
.card {
  perspective: 1000px;
  @apply transition-all scale-100 w-56 h-80 min-w-56 min-h-80;
  touch-action: none;

  .flip-inner {
    position: relative;
    width: 100%;
    height: 100%;
    transition: transform 0.6s;
    transform-style: preserve-3d;
    transform-origin: center;
  }

  .face-down,
  .face-up {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    will-change: transform;
    background-color: rgba(255, 255, 255, 0.5);
  }

  .face-up {
    transform: rotateY(0deg);
    transition: box-shadow 0.6s;
  }

  .face-down {
    transform: rotateY(-180deg);
  }

  &.face-down .flip-inner {
    transform: rotateY(180deg);
  }

  &.face-up .flip-inner {
    transform: rotateY(0deg);
  }

  &.face-down:hover {
    .play-button {
      opacity: 1;
    }

    .flip-inner {
      transform: rotateY(170deg);
    }
  }

  &.current-track,
  &:focus {
    @apply z-50 scale-110;

    .face-up {
      @apply shadow-2xl;
      transition:
        box-shadow 0.6s,
        transform 0.6s;
    }

    .play-button {
      @apply opacity-100;
    }
  }

  .play-button {
    opacity: 0;
  }

  .face-up:hover {
    .play-button {
      opacity: 1;
    }

    .flip-inner {
      transform: rotateY(-170deg);
    }
  }

  .play-button {
    @apply absolute bottom-1/2 top-24 opacity-0 hover:opacity-100;
  }

  .pochette:active,
  .face-down:active {
    .play-button {
      @apply scale-90;
    }
  }

  &.is-dragging {
    @apply opacity-50 scale-95 rotate-6;
    cursor: grabbing !important;

    .face-up {
      @apply shadow-2xl;
    }

    .play-button,
    .card-body {
      display: none;
    }
  }
}

/* Ghost card styles */
.ghost-card {
  transition: none;

  .card {
    @apply shadow-2xl scale-95 rotate-6;

    .play-button,
    .card-body {
      display: none;
    }
  }

  .flip-inner {
    perspective: 1000px;
  }
}
</style>
