<script setup lang="ts">
/**
 * Galerie d'images d'un projet.
 *
 *  - Grille de miniatures (lazy-load).
 *  - Click thumb -> overlay plein écran avec navigation gauche/droite,
 *    fermeture par clic hors image / Échap.
 *  - Mode admin (token Bearer présent) : bouton Supprimer par image + uploader.
 */

import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { api, ApiError } from '@/api/client'
import { useAuth } from '@/composables/useAuth'
import type { ProjectImage, Wrapped } from '@/types/api'
import ImageUploader from './ImageUploader.vue'
import LoadingState from './LoadingState.vue'

const props = defineProps<{ projectSlug: string }>()
const { isAuthenticated } = useAuth()

const images = ref<ProjectImage[]>([])
const loading = ref(true)
const error = ref<string | null>(null)
const lightboxIndex = ref<number | null>(null)

async function load() {
  loading.value = true
  error.value = null
  try {
    const r = await api.get<Wrapped<ProjectImage>>(`/api/projects/${encodeURIComponent(props.projectSlug)}/images`)
    images.value = r.data
  } catch (e) {
    error.value = e instanceof ApiError ? (e.payload.message ?? e.code) : 'Erreur réseau'
  } finally {
    loading.value = false
  }
}

onMounted(load)
watch(() => props.projectSlug, load)

function openLightbox(idx: number) {
  lightboxIndex.value = idx
}
function closeLightbox() {
  lightboxIndex.value = null
}
function next() {
  if (lightboxIndex.value === null) return
  lightboxIndex.value = (lightboxIndex.value + 1) % images.value.length
}
function prev() {
  if (lightboxIndex.value === null) return
  lightboxIndex.value = (lightboxIndex.value - 1 + images.value.length) % images.value.length
}

// Navigation clavier dans la lightbox.
function onKey(e: KeyboardEvent) {
  if (lightboxIndex.value === null) return
  if (e.key === 'Escape') closeLightbox()
  if (e.key === 'ArrowRight') next()
  if (e.key === 'ArrowLeft') prev()
}
onMounted(() => window.addEventListener('keydown', onKey))
onUnmounted(() => window.removeEventListener('keydown', onKey))

async function remove(img: ProjectImage) {
  if (!confirm(`Supprimer l'image « ${img.caption ?? 'sans légende'} » ?`)) return
  try {
    await api.delete(`/api/projects/${encodeURIComponent(props.projectSlug)}/images/${img.id}`)
    images.value = images.value.filter(i => i.id !== img.id)
    if (lightboxIndex.value !== null && lightboxIndex.value >= images.value.length) {
      lightboxIndex.value = images.value.length === 0 ? null : images.value.length - 1
    }
  } catch (e) {
    console.error('image delete failed', e)
  }
}

function onUploaded(newImg: ProjectImage) {
  images.value.push(newImg)
}

const currentImage = computed(() =>
  lightboxIndex.value === null ? null : images.value[lightboxIndex.value],
)
</script>

<template>
  <div>
    <LoadingState v-if="loading" />
    <div v-else-if="error" class="text-sm text-red-700">{{ error }}</div>

    <div v-else-if="images.length === 0" class="text-sm text-donut-muted">
      Pas encore d'image.
      <span v-if="!isAuthenticated">Connecte-toi en admin pour en ajouter.</span>
    </div>

    <!-- Grille -->
    <div v-else class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3">
      <div
        v-for="(img, idx) in images" :key="img.id"
        class="group relative aspect-square rounded-lg overflow-hidden bg-gray-100 cursor-pointer"
        @click="openLightbox(idx)"
      >
        <img
          :src="img.url"
          :alt="img.caption ?? `Image ${idx + 1} du projet`"
          loading="lazy"
          class="absolute inset-0 w-full h-full object-cover transition-transform group-hover:scale-105"
        />
        <div
          v-if="img.caption"
          class="absolute inset-x-0 bottom-0 px-2.5 py-1.5 bg-gradient-to-t from-black/70 to-transparent text-white text-xs"
        >
          {{ img.caption }}
        </div>
        <button
          v-if="isAuthenticated"
          type="button"
          class="absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 transition-opacity bg-red-500/90 hover:bg-red-600 text-white rounded-md p-1.5"
          title="Supprimer"
          @click.stop="remove(img)"
        >
          <svg viewBox="0 0 24 24" class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round">
            <path d="M18 6 6 18M6 6l12 12"/>
          </svg>
        </button>
      </div>
    </div>

    <!-- Uploader (admin uniquement) -->
    <div v-if="isAuthenticated" class="mt-4 pt-4 border-t border-donut-border">
      <ImageUploader :project-slug="projectSlug" @uploaded="onUploaded" />
    </div>

    <!-- Lightbox -->
    <Teleport to="body">
      <div
        v-if="currentImage"
        class="fixed inset-0 z-50 flex items-center justify-center bg-black/90 px-4"
        @click.self="closeLightbox"
      >
        <button
          type="button"
          class="absolute top-4 right-4 text-white/80 hover:text-white"
          @click="closeLightbox"
          aria-label="Fermer"
        >
          <svg viewBox="0 0 24 24" class="w-7 h-7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
            <path d="M18 6 6 18M6 6l12 12"/>
          </svg>
        </button>

        <button
          v-if="images.length > 1"
          type="button"
          class="absolute left-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2"
          @click="prev"
          aria-label="Image précédente"
        >
          <svg viewBox="0 0 24 24" class="w-8 h-8" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="m15 18-6-6 6-6"/>
          </svg>
        </button>

        <div class="max-w-5xl max-h-full flex flex-col items-center">
          <img
            :src="currentImage.url"
            :alt="currentImage.caption ?? 'Image projet'"
            class="max-h-[80vh] max-w-full object-contain rounded-lg"
          />
          <div v-if="currentImage.caption" class="mt-3 text-white/90 text-sm">
            {{ currentImage.caption }}
          </div>
          <div class="mt-1 text-white/40 text-xs">
            {{ (lightboxIndex ?? 0) + 1 }} / {{ images.length }}
          </div>
        </div>

        <button
          v-if="images.length > 1"
          type="button"
          class="absolute right-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2"
          @click="next"
          aria-label="Image suivante"
        >
          <svg viewBox="0 0 24 24" class="w-8 h-8" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="m9 18 6-6-6-6"/>
          </svg>
        </button>
      </div>
    </Teleport>
  </div>
</template>
