<script setup lang="ts">
/**
 * Uploader d'images : drag-and-drop OU file picker, + champ légende optionnel.
 * Accepte plusieurs fichiers, les upload en série pour conserver l'ordre.
 */

import { ref } from 'vue'
import { uploadFile, ApiError } from '@/api/client'
import type { ProjectImage } from '@/types/api'

const props = defineProps<{ projectSlug: string }>()
const emit = defineEmits<{
  (e: 'uploaded', img: ProjectImage): void
}>()

const fileInput = ref<HTMLInputElement | null>(null)
const dragOver = ref(false)
const caption = ref('')
const uploading = ref(false)
const queueSize = ref(0)
const queueDone = ref(0)
const error = ref<string | null>(null)

const ACCEPT = 'image/jpeg,image/png,image/webp,image/gif'
const MAX_BYTES = 5 * 1024 * 1024

async function uploadOne(file: File): Promise<void> {
  if (file.size > MAX_BYTES) {
    error.value = `« ${file.name } » fait ${(file.size / 1024 / 1024).toFixed(1)} Mo (max 5 Mo)`
    return
  }
  try {
    const img = await uploadFile<ProjectImage>(
      `/api/projects/${encodeURIComponent(props.projectSlug)}/images`,
      file,
      { caption: caption.value.trim() || undefined },
    )
    emit('uploaded', img)
  } catch (e) {
    if (e instanceof ApiError) {
      if (e.status === 422 && e.fields.file === 'too_large') {
        error.value = `« ${file.name} » est trop volumineux (max 5 Mo)`
      } else if (e.status === 422 && e.fields.file === 'unsupported_mime') {
        error.value = `« ${file.name} » : type non supporté (JPG/PNG/WebP/GIF uniquement)`
      } else if (e.status === 401) {
        error.value = 'Tu dois être admin pour uploader.'
      } else {
        error.value = e.payload.message ?? `Échec de l'upload de « ${file.name} »`
      }
    } else {
      error.value = `Erreur réseau pendant l'upload de « ${file.name} »`
    }
  }
}

async function processFiles(files: FileList | File[]) {
  error.value = null
  const list = Array.from(files).filter(f => f.type.startsWith('image/'))
  if (list.length === 0) {
    error.value = "Aucun fichier image dans la sélection."
    return
  }
  uploading.value = true
  queueSize.value = list.length
  queueDone.value = 0
  for (const f of list) {
    await uploadOne(f)
    queueDone.value++
  }
  uploading.value = false
  caption.value = ''   // reset après une session d'upload
  if (fileInput.value) fileInput.value.value = ''
}

function onFileChange(e: Event) {
  const target = e.target as HTMLInputElement
  if (target.files) processFiles(target.files)
}

function onDrop(e: DragEvent) {
  e.preventDefault()
  dragOver.value = false
  if (e.dataTransfer?.files) processFiles(e.dataTransfer.files)
}
</script>

<template>
  <div>
    <div
      class="rounded-lg border-2 border-dashed transition-colors p-5 text-center cursor-pointer"
      :class="dragOver ? 'border-donut-text bg-gray-50' : 'border-donut-border hover:border-gray-400 hover:bg-gray-50'"
      @click="fileInput?.click()"
      @dragenter.prevent="dragOver = true"
      @dragover.prevent="dragOver = true"
      @dragleave="dragOver = false"
      @drop="onDrop"
    >
      <svg viewBox="0 0 24 24" class="w-7 h-7 mx-auto text-donut-muted" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
        <rect x="3" y="3" width="18" height="18" rx="2"/>
        <circle cx="9" cy="9" r="2"/>
        <path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/>
      </svg>
      <div class="mt-2 text-sm text-donut-text">
        <span class="font-medium">Déposer des images ici</span> ou cliquer pour parcourir
      </div>
      <div class="mt-0.5 text-xs text-donut-muted">JPG / PNG / WebP / GIF — 5 Mo max</div>
      <input
        ref="fileInput"
        type="file"
        :accept="ACCEPT"
        multiple
        class="hidden"
        @change="onFileChange"
      />
    </div>

    <div class="mt-2 flex items-center gap-2">
      <input
        v-model="caption"
        type="text"
        placeholder="Légende commune à cette série (optionnel)"
        class="flex-1 bg-donut-surface border border-donut-border rounded-md px-2.5 py-1.5 text-xs outline-none focus:border-donut-text"
      />
    </div>

    <div v-if="uploading" class="mt-2 flex items-center gap-2 text-xs text-donut-muted">
      <svg viewBox="0 0 24 24" class="w-3.5 h-3.5 animate-spin" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round">
        <path d="M21 12a9 9 0 1 1-6.219-8.56" />
      </svg>
      Upload {{ queueDone + 1 }}/{{ queueSize }}…
    </div>

    <div v-if="error" class="mt-2 rounded-md border border-red-200 bg-red-50 text-red-700 px-2.5 py-1.5 text-xs">
      {{ error }}
    </div>
  </div>
</template>
