﻿<template>
  <div class="relative w-full" :id="props.galleryId">
    <div v-if="editMode" class="grid grid-cols-3 gap-4 w-full min-h-10">
      <div
        v-for="image in combinedImages"
        :key="getKeyForImage(image)"
        class="relative cursor-move group"
        draggable="true"
        @dragstart="(event) => dragStart(event, combinedImages.indexOf(image))"
        @dragover.prevent
        @dragenter.stop.prevent="handleDragEnter(combinedImages.indexOf(image))"
        @drop.stop.prevent="drop"
      >
        <img :src="getImageSrc(image)" class="w-full h-66 object-cover rounded-lg" />
        <button
          v-if="editMode"
          class="absolute top-2 right-2 bg-white text-gray-800 w-6 h-6 flex items-center justify-center p-0 rounded-full hover:bg-gray-300 transition-opacity opacity-0 group-hover:opacity-100"
          @click.stop.prevent="removeImage(image)"
        >
          <img :src="crossIcon" alt="Delete" class="h-4 w-4" />
        </button>
      </div>
    </div>
    <div v-else>
      <Carousel v-bind="adjustedSettings" v-if="combinedImages.length != 0" ref="carousel">
        <Slide v-for="image in combinedImages" :key="getKeyForImage(image)">
          <div class="carousel__item">
            <img :src="getImageSrc(image)" alt="" class="carousel-image" />
          </div>
        </Slide>
        <template #addons>
          <Navigation />

          <Pagination />
        </template>
      </Carousel>
    </div>
    <button
      v-if="editMode"
      @click.stop.prevent="showModal = true"
      class="py-2 px-4 bg-indigo-600 text-white font-semibold rounded hover:bg-blue-700 absolute bottom-0 right-0 z-50"
    >
      +
    </button>
    <div
      v-if="showModal"
      class="fixed inset-0 bg-black/50 flex justify-center items-center z-50"
    >
      <div class="bg-white p-6 rounded shadow-lg relative w-1/4">
        <button
          @click.prevent="resetModal"
          class="absolute top-2 right-2 text-gray-600 hover:text-gray-900"
        >
          &times;
        </button>
        <h3 class="text-lg font-semibold mb-4">Add a New Image</h3>
        <div class="flex items-center">
          <input type="file" ref="fileInput" @change="handleFileUpload" class="hidden" />
          <button
            @click.prevent="triggerFileInput"
            class="bg-blue-500 text-white rounded hover:bg-blue-700 h-10 px-4"
          >
            Browse
          </button>
          <div
            v-if="fileName"
            class="ml-4 p-2 border border-gray-300 rounded flex items-center h-10 w-full overflow-hidden whitespace-nowrap text-ellipsis"
          >
            {{ formatFileName(fileName) }}
          </div>
        </div>
        <button
          @click.prevent="addImage"
          class="w-full mt-4 bg-blue-500 text-white p-2 rounded hover:bg-blue-700"
        >
          Add Image
        </button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { crossIcon } from '~/assets/icons'
import { Navigation, Pagination } from 'vue3-carousel'
import type { NewImage, ServerImage } from '../../../app/types/UItypes'
import type { Image } from '~/pages/types/UITypes'

const props = defineProps<{
  galleryId: string
  serverImages: ServerImage[]
  editMode?: boolean
}>()

const emit = defineEmits(['update:modelValue'])
const fileInput = ref<null | HTMLInputElement>(null)
const serverImages = ref<ServerImage[]>([...props.serverImages])
const newImages = ref<NewImage[]>([])
const showModal = ref(false)
const newImageFile = ref<File | null>(null)
const dragIndex = ref<number | null>(null)
const fileName = ref('')
const editMode = props.editMode ?? false

const combinedImages = computed(() => [...serverImages.value, ...newImages.value])

watch(
  [serverImages, newImages],
  () => {
    reassignOrder()
    emit('update:modelValue', combinedImages.value)
  },
  { deep: true }
)

function handleFileUpload(event: Event) {
  const file = (event.target as HTMLInputElement).files?.[0]
  if (file) {
    fileName.value = file.name
    newImageFile.value = file
  }
}

function addImage() {
  if (newImageFile.value) {
    newImages.value.push({
      file: newImageFile.value,
      order: combinedImages.value.length + 1,
    })
    resetModal()
  }
}

function removeImage(image: Image) {
  if ('id' in image) {
    const index = serverImages.value.findIndex((img) => img.id === image.id)
    if (index !== -1) {
      serverImages.value.splice(index, 1)
    }
  } else {
    const index = newImages.value.findIndex((img) => img.file === image.file)
    if (index !== -1) {
      newImages.value.splice(index, 1)
    }
  }
}

function resetModal() {
  newImageFile.value = null
  fileName.value = ''
  showModal.value = false
}

function triggerFileInput() {
  fileInput.value?.click()
}

function dragStart(event: DragEvent, index: number) {
  dragIndex.value = index
  event.dataTransfer!.effectAllowed = 'move'
}

function handleDragEnter(index: number) {
  if (dragIndex.value !== null && index !== dragIndex.value) {
    const sourceArray =
      dragIndex.value < serverImages.value.length ? serverImages.value : newImages.value
    const draggedItem = sourceArray.splice(dragIndex.value, 1)[0]
    sourceArray.splice(index, 0, draggedItem as any) // Utilisation de 'as any' pour r├®soudre le probl├¿me de typage
    dragIndex.value = index
  }
}

function drop() {
  dragIndex.value = null
  reassignOrder()
}

function reassignOrder() {
  combinedImages.value.forEach((image, index) => {
    image.order = index + 1
  })
}

function getImageSrc(image: Image): string {
  return 'link' in image ? image.link : URL.createObjectURL(image.file)
}

function getKeyForImage(image: Image): string {
  return 'id' in image ? `server-${image.id}` : `new-${image.file.name}`
}

function formatFileName(fileName: string): string {
  const maxLength = 39 // Ajustez cette valeur selon vos besoins
  const extension = fileName.split('.').pop()
  const nameWithoutExtension = fileName.slice(0, -(extension!.length + 1))

  if (fileName.length <= maxLength) {
    return fileName
  }

  const truncatedName = nameWithoutExtension.slice(-maxLength + extension!.length + 3)
  return `...${truncatedName}.${extension}`
}

// Carousel settings

// Carousel settings
const settings = {
  itemsToShow: 2.5,
  snapAlign: 'center',
  wrapAround: true,
  transition: 500,
}

const adjustedSettings = computed(() => {
  const imageCount = combinedImages.value.length
  if (imageCount === 1) {
    return { ...settings, itemsToShow: 1, wrapAround: false }
  } else {
    return settings
  }
})
</script>

<style scoped>
.carousel__item {
  min-height: 310px;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
}

.carousel-image {
  height: 310px;
  object-fit: cover;
  object-position: center;
}

.carousel__slide {
  padding: 5px;
}

.carousel__viewport {
  perspective: 2000px;
}

.carousel__track {
  transform-style: preserve-3d;
}

.carousel__slide--sliding {
  transition: 0.5s;
}

.carousel__slide {
  opacity: 0.9;
  transform: rotateY(-20deg) scale(0.9);
}

.carousel__slide--active ~ .carousel__slide {
  transform: rotateY(20deg) scale(0.9);
}

.carousel__slide--active {
  opacity: 1;
  transform: rotateY(0) scale(1.1);
}

.carousel-nav-button {
  background-color: var(--color-gray-50);
  border-radius: var(--radius-full);
  padding: 10px;
  box-shadow: var(--shadow-sm);
  transition: background-color var(--duration-base) var(--ease-in-out);
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

.carousel-nav-button:hover {
  background-color: var(--color-gray-100);
}

.carousel-nav-button svg {
  width: 24px;
  height: 24px;
}

.carousel-nav-button-prev {
  left: -30px; /* Adjust as needed */
}

.carousel-nav-button-next {
  right: -30px; /* Adjust as needed */
}
</style>
