<template>
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
    <!-- Header -->
    <div class="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-6 sm:mb-8 space-y-4 sm:space-y-0">
      <div>
        <h1 class="text-2xl sm:text-3xl font-bold text-gray-900">Albums photos</h1>
        <p class="text-sm sm:text-base text-gray-600 mt-1">Partagez vos souvenirs en photos et vidéos</p>
      </div>
      <button
        @click="showCreateModal = true"
        class="w-full sm:w-auto btn-primary justify-center"
      >
        <Plus class="w-4 h-4 mr-2" />
        Nouvel album
      </button>
    </div>

    <!-- Albums Grid -->
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
      <div
        v-for="album in albums"
        :key="album.id"
        class="card hover:shadow-lg transition-shadow cursor-pointer"
        @click="openAlbum(album)"
      >
        <!-- Cover Image -->
        <div class="aspect-square bg-gray-100 relative overflow-hidden">
          <img
            v-if="album.cover_image"
            :src="getMediaUrl(album.cover_image)"
            :alt="album.title"
            class="w-full h-full object-cover"
          >
          <div v-else class="w-full h-full flex items-center justify-center">
            <Image class="w-16 h-16 text-gray-400" />
          </div>
          
          <!-- Media Count Badge -->
          <div class="absolute top-2 right-2 bg-black bg-opacity-70 text-white text-xs px-2 py-1 rounded">
            {{ album.media_count }} média{{ album.media_count > 1 ? 's' : '' }}
          </div>
        </div>
        
        <!-- Content -->
        <div class="p-4">
          <h3 class="font-semibold text-gray-900 mb-2">{{ album.title }}</h3>
          
          <div v-if="album.description" class="mb-3">
            <Mentions :content="album.description" :mentions="getMentionsFromContent(album.description)" class="text-sm text-gray-600 line-clamp-2" />
          </div>
          
          <div class="flex items-center space-x-2 text-sm text-gray-600 mb-3">
            <img
              v-if="album.creator_avatar"
              :src="getMediaUrl(album.creator_avatar)"
              :alt="album.creator_name"
              class="w-5 h-5 rounded-full object-cover"
            >
            <div v-else class="w-5 h-5 rounded-full bg-gray-200 flex items-center justify-center">
              <User class="w-3 h-3 text-gray-500" />
            </div>
            <router-link 
              :to="`/profile/${album.creator_id}`"
              class="text-gray-900 hover:text-primary-600 transition-colors cursor-pointer"
            >
              {{ album.creator_name }}
            </router-link>
          </div>
          
          <div class="flex items-center justify-between text-sm text-gray-500">
            <span>{{ formatRelativeDate(album.created_at) }}</span>
            <div v-if="album.event_title" class="text-primary-600">
              📅 {{ album.event_title }}
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Load more -->
    <div v-if="hasMoreAlbums" class="text-center mt-8">
      <button
        @click="loadMoreAlbums"
        :disabled="loading"
        class="btn-secondary"
      >
        {{ loading ? 'Chargement...' : 'Charger plus' }}
      </button>
    </div>

    <!-- Empty state -->
    <div v-if="albums.length === 0 && !loading" class="text-center py-12">
      <Image class="w-16 h-16 text-gray-300 mx-auto mb-4" />
      <h3 class="text-lg font-medium text-gray-900 mb-2">Aucun album</h3>
      <p class="text-gray-600">Créez le premier album pour partager vos photos !</p>
    </div>

    <!-- Create Album Modal -->
    <transition
      enter-active-class="transition ease-out duration-200"
      enter-from-class="opacity-0"
      enter-to-class="opacity-100"
      leave-active-class="transition ease-in duration-150"
      leave-from-class="opacity-100"
      leave-to-class="opacity-0"
    >
      <div
        v-if="showCreateModal"
        class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4"
      >
        <div class="bg-white rounded-xl max-w-2xl w-full p-6 max-h-[90vh] overflow-y-auto">
          <h2 class="text-xl font-semibold mb-4">Créer un nouvel album</h2>
          
          <form @submit.prevent="createAlbum" class="space-y-4">
            <div>
              <label class="label">Titre</label>
              <input
                v-model="newAlbum.title"
                type="text"
                required
                class="input"
                placeholder="Titre de l'album..."
              >
            </div>
            
            <div>
              <label class="label">Description</label>
              <MentionInput
                v-model="newAlbum.description"
                :users="users"
                :rows="3"
                placeholder="Décrivez votre album... (utilisez @username pour mentionner)"
                @mentions-changed="handleAlbumMentionsChanged"
              />
            </div>
            
            <div>
              <label class="label">Lier à un événement (optionnel)</label>
              <select
                v-model="newAlbum.event_id"
                class="input"
              >
                <option value="">Aucun événement</option>
                <option
                  v-for="event in events"
                  :key="event.id"
                  :value="event.id"
                >
                  {{ event.title }} - {{ formatDate(event.date) }}
                </option>
              </select>
            </div>
            
            <div>
              <label class="label">Photos et vidéos</label>
              <div 
                class="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center transition-colors"
                :class="{ 'border-primary-400 bg-primary-50': isDragOver }"
                @dragover.prevent="isDragOver = true"
                @dragleave.prevent="isDragOver = false"
                @drop.prevent="handleDrop"
              >
                <input
                  ref="mediaInput"
                  type="file"
                  accept="image/*,video/*"
                  multiple
                  class="hidden"
                  @change="handleMediaChange"
                >
                
                <div v-if="newAlbum.media.length === 0" class="space-y-2">
                  <Upload class="w-12 h-12 text-gray-400 mx-auto" />
                  <p class="text-gray-600">Glissez-déposez ou cliquez pour sélectionner</p>
                  <p class="text-sm text-gray-500">
                    Images et vidéos (max {{ uploadLimits.max_image_size_mb }}MB pour images, {{ uploadLimits.max_video_size_mb }}MB pour vidéos)
                    <br>
                    <span class="text-xs text-gray-400">Maximum {{ uploadLimits.max_media_per_album }} fichiers par album</span>
                  </p>
                  <button
                    type="button"
                    @click="$refs.mediaInput.click()"
                    class="btn-secondary"
                    :disabled="isUploading"
                  >
                    {{ isUploading ? 'Upload en cours...' : 'Sélectionner des fichiers' }}
                  </button>
                </div>
                
                <div v-else class="space-y-3">
                  <div class="grid grid-cols-2 md:grid-cols-3 gap-2">
                    <div
                      v-for="(media, index) in newAlbum.media"
                      :key="index"
                      class="relative aspect-square bg-gray-100 rounded overflow-hidden group"
                    >
                      <img
                        v-if="media.type === 'image'"
                        :src="media.preview"
                        :alt="media.name"
                        class="w-full h-full object-cover"
                      >
                      <video
                        v-else
                        :src="media.preview"
                        class="w-full h-full object-cover"
                        muted
                        loop
                      />
                      
                      <!-- File Info Overlay -->
                      <div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-50 transition-all duration-200 flex items-end">
                        <div class="w-full p-2 text-white text-xs opacity-0 group-hover:opacity-100 transition-opacity duration-200">
                          <div class="font-medium truncate">{{ media.name }}</div>
                          <div class="text-gray-300">
                            {{ formatFileSize(media.size) }}
                            <span v-if="media.originalSize && media.originalSize > media.size" class="text-green-300">
                              ({{ Math.round((1 - media.size / media.originalSize) * 100) }}% compression)
                            </span>
                          </div>
                        </div>
                      </div>
                      
                      <!-- Caption Input -->
                      <div class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-70 p-2">
                        <input
                          v-model="media.caption"
                          type="text"
                          :placeholder="`Légende pour ${media.name}`"
                          class="w-full text-xs bg-transparent text-white placeholder-gray-300 border-none outline-none"
                          maxlength="100"
                        >
                      </div>
                      
                      <button
                        @click="removeMedia(index)"
                        class="absolute top-1 right-1 bg-red-500 text-white rounded-full w-6 h-6 flex items-center justify-center hover:bg-red-600 transition-colors"
                      >
                        <X class="w-4 h-4" />
                      </button>
                      
                      <div class="absolute top-1 left-1 bg-black bg-opacity-70 text-white text-xs px-1 py-0.5 rounded">
                        {{ media.type === 'image' ? '📷' : '🎥' }}
                      </div>
                    </div>
                  </div>
                  
                  <button
                    type="button"
                    @click="$refs.mediaInput.click()"
                    class="btn-secondary text-sm"
                    :disabled="isUploading"
                  >
                    {{ isUploading ? 'Upload en cours...' : 'Ajouter plus de fichiers' }}
                  </button>
                </div>
              </div>
            </div>
            
            <!-- Upload Progress Bar -->
            <div v-if="isUploading" class="mt-4 p-4 bg-blue-50 rounded-lg border border-blue-200">
              <div class="flex items-center justify-between mb-2">
                <span class="text-sm font-medium text-blue-900">{{ uploadStatus }}</span>
                <span class="text-sm text-blue-700">{{ currentFileIndex }}/{{ totalFiles }}</span>
              </div>
              <div class="w-full bg-blue-200 rounded-full h-2">
                <div 
                  class="bg-blue-600 h-2 rounded-full transition-all duration-300"
                  :style="`width: ${uploadProgress}%`"
                ></div>
              </div>
              <div class="mt-2 text-xs text-blue-600">
                {{ Math.round(uploadProgress) }}% terminé
              </div>
            </div>

            <!-- Upload Results Summary -->
            <div v-if="uploadSuccess.length > 0 || uploadErrors.length > 0" class="mt-4 p-4 bg-gray-50 rounded-lg">
              <div v-if="uploadSuccess.length > 0" class="mb-2">
                <div class="text-sm font-medium text-green-700">
                  ✅ {{ uploadSuccess.length }} fichier(s) uploadé(s) avec succès
                </div>
              </div>
              <div v-if="uploadErrors.length > 0" class="mb-2">
                <div class="text-sm font-medium text-red-700">
                  ❌ {{ uploadErrors.length }} erreur(s) lors de l'upload
                </div>
                <div class="text-xs text-red-600 mt-1">
                  <div v-for="error in uploadErrors" :key="error.file" class="mb-1">
                    {{ error.file }}: {{ error.message }}
                  </div>
                </div>
              </div>
            </div>

            <div class="flex gap-3 pt-4">
              <button
                type="button"
                @click="showCreateModal = false"
                :disabled="isUploading"
                class="flex-1 btn-secondary"
              >
                Annuler
              </button>
              <button
                type="submit"
                :disabled="creating || newAlbum.media.length === 0 || isUploading"
                class="flex-1 btn-primary"
              >
                <span v-if="isUploading" class="flex items-center justify-center">
                  <svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                    <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                    <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.291z"></path>
                  </svg>
                  Upload en cours...
                </span>
                <span v-else-if="creating">
                  Création...
                </span>
                <span v-else>
                  Créer l'album
                </span>
              </button>
            </div>
          </form>
        </div>
      </div>
    </transition>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useToast } from 'vue-toastification'
import { useRouter } from 'vue-router'
import axios from '@/utils/axios'
import { getMediaUrl } from '@/utils/axios'
import { formatDistanceToNow, format } from 'date-fns'
import { fr } from 'date-fns/locale'
import {
  Plus,
  Image,
  User,
  Upload,
  X
} from 'lucide-vue-next'
import Mentions from '@/components/Mentions.vue'
import MentionInput from '@/components/MentionInput.vue'

const router = useRouter()
const toast = useToast()

const albums = ref([])
const events = ref([])
const users = ref([])
const loading = ref(false)
const creating = ref(false)
const showCreateModal = ref(false)
const hasMoreAlbums = ref(true)
const offset = ref(0)
const uploadLimits = ref({
  max_image_size_mb: 10,
  max_video_size_mb: 100,
  max_media_per_album: 50
})

const newAlbum = ref({
  title: '',
  description: '',
  event_id: '',
  media: []
})

const albumMentions = ref([])

// Upload optimization states
const uploadProgress = ref(0)
const isUploading = ref(false)
const uploadStatus = ref('')
const currentFileIndex = ref(0)
const totalFiles = ref(0)
const uploadErrors = ref([])
const uploadSuccess = ref([])
const isDragOver = ref(false)

function formatRelativeDate(date) {
  return formatDistanceToNow(new Date(date), { addSuffix: true, locale: fr })
}

function formatDate(date) {
  return format(new Date(date), 'dd/MM/yyyy', { locale: fr })
}

function formatFileSize(bytes) {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
}

function openAlbum(album) {
  router.push(`/albums/${album.id}`)
}

function handleAlbumMentionsChanged(mentions) {
  albumMentions.value = mentions
}

function getMentionsFromContent(content) {
  if (!content) return []
  
  const mentions = []
  const mentionRegex = /@(\w+)/g
  let match
  
  while ((match = mentionRegex.exec(content)) !== null) {
    const username = match[1]
    const user = users.value.find(u => u.username === username)
    if (user) {
      mentions.push({
        id: user.id,
        username: user.username,
        full_name: user.full_name
      })
    }
  }
  
  return mentions
}

async function fetchUsers() {
  try {
    const response = await axios.get('/api/users')
    users.value = response.data
  } catch (error) {
    console.error('Error fetching users:', error)
  }
}

async function fetchUploadLimits() {
  try {
    const response = await axios.get('/api/settings/public/upload-limits')
    uploadLimits.value = response.data
  } catch (error) {
    console.error('Error fetching upload limits:', error)
  }
}

async function handleMediaChange(event) {
  const files = Array.from(event.target.files)
  const maxFiles = uploadLimits.value.max_media_per_album
  
  if (newAlbum.value.media.length + files.length > maxFiles) {
    toast.error(`Maximum ${maxFiles} fichiers autorisés par album`)
    event.target.value = ''
    return
  }
  
  let validFiles = 0
  let skippedFiles = 0
  
  for (const file of files) {
    try {
      // Validate file type
      if (!file.type.startsWith('image/') && !file.type.startsWith('video/')) {
        toast.error(`${file.name} n'est pas un fichier image ou vidéo valide`)
        skippedFiles++
        continue
      }
      
      // Validate file size
      const maxSizeMB = file.type.startsWith('image/') ? uploadLimits.value.max_image_size_mb : uploadLimits.value.max_video_size_mb
      const maxSizeBytes = maxSizeMB * 1024 * 1024
      
      if (file.size > maxSizeBytes) {
        toast.error(`${file.name} est trop volumineux (max ${maxSizeMB}MB)`)
        skippedFiles++
        continue
      }
      
      // Validate file name (prevent special characters issues)
      if (file.name.length > 100) {
        toast.error(`${file.name} a un nom trop long (max 100 caractères)`)
        skippedFiles++
        continue
      }
      
      // Optimize image if it's an image file
      let optimizedFile = file
      if (file.type.startsWith('image/')) {
        try {
          optimizedFile = await optimizeImage(file)
        } catch (error) {
          console.warn(`Could not optimize ${file.name}:`, error)
          optimizedFile = file // Fallback to original file
        }
      }
      
      // Create media object with optimized preview
      const media = {
        file: optimizedFile,
        originalFile: file, // Keep reference to original for size display
        name: file.name,
        type: file.type.startsWith('image/') ? 'image' : 'video',
        size: optimizedFile.size,
        originalSize: file.size,
        preview: URL.createObjectURL(optimizedFile),
        caption: '' // Add caption field for user input
      }
      
      newAlbum.value.media.push(media)
      validFiles++
      
    } catch (error) {
      console.error(`Error processing file ${file.name}:`, error)
      toast.error(`Erreur lors du traitement de ${file.name}`)
      skippedFiles++
    }
  }
  
  // Show summary
  if (validFiles > 0) {
    if (skippedFiles > 0) {
      toast.info(`${validFiles} fichier(s) ajouté(s), ${skippedFiles} ignoré(s)`)
    } else {
      toast.success(`${validFiles} fichier(s) ajouté(s)`)
    }
  }
  
  event.target.value = ''
}

function handleDrop(event) {
  isDragOver.value = false
  const files = Array.from(event.dataTransfer.files)
  if (files.length > 0) {
    // Simulate file input change
    const fakeEvent = { target: { files: files } }
    handleMediaChange(fakeEvent)
  }
}

async function optimizeImage(file) {
  return new Promise((resolve) => {
    if (!file.type.startsWith('image/')) {
      resolve(file) // Return original file for non-images
      return
    }
    
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    const img = new Image()
    
    img.onload = () => {
      // Calculate optimal dimensions (much higher for modern screens)
      const maxWidth = 3840  // 4K support
      const maxHeight = 2160 // 4K support
      let { width, height } = img
      
      // Only resize if image is REALLY too large
      if (width > maxWidth || height > maxHeight) {
        const ratio = Math.min(maxWidth / width, maxHeight / height)
        width *= ratio
        height *= ratio
      } else {
        // Keep original dimensions for most images
        resolve(file)
        return
      }
      
      canvas.width = width
      canvas.height = height
      
      // Draw optimized image
      ctx.drawImage(img, 0, 0, width, height)
      
      // Convert to blob with HIGH quality
      canvas.toBlob((blob) => {
        const optimizedFile = new File([blob], file.name, {
          type: file.type,
          lastModified: Date.now()
        })
        resolve(optimizedFile)
      }, file.type, 0.95) // 95% quality for minimal loss
    }
    
    img.src = URL.createObjectURL(file)
  })
}

function removeMedia(index) {
  const media = newAlbum.value.media[index]
  
  // Clean up preview URLs
  if (media.preview && media.preview.startsWith('blob:')) {
    URL.revokeObjectURL(media.preview)
  }
  
  // Clean up original file preview if different
  if (media.originalFile && media.originalFile !== media.file) {
    // Note: originalFile doesn't have preview, but we could add cleanup here if needed
  }
  
  newAlbum.value.media.splice(index, 1)
}

async function createAlbum() {
  if (!newAlbum.value.title || newAlbum.value.media.length === 0) return
  
  // Check max media per album limit
  if (uploadLimits.value.max_media_per_album && newAlbum.value.media.length > uploadLimits.value.max_media_per_album) {
    toast.error(`Nombre maximum de médias par album dépassé : ${uploadLimits.value.max_media_per_album}`)
    return
  }
  
  creating.value = true
  isUploading.value = true
  uploadProgress.value = 0
  currentFileIndex.value = 0
  totalFiles.value = newAlbum.value.media.length
  uploadErrors.value = []
  uploadSuccess.value = []
  
  try {
    // First create the album
    const albumData = {
      title: newAlbum.value.title,
      description: newAlbum.value.description,
      event_id: newAlbum.value.event_id || null
    }
    
    uploadStatus.value = 'Création de l\'album...'
    const albumResponse = await axios.post('/api/albums', albumData)
    const album = albumResponse.data
    
    // Upload media files in batches for better performance
    const batchSize = 5 // Upload 5 files at a time
    const totalBatches = Math.ceil(newAlbum.value.media.length / batchSize)
    
    for (let batchIndex = 0; batchIndex < totalBatches; batchIndex++) {
      const startIndex = batchIndex * batchSize
      const endIndex = Math.min(startIndex + batchSize, newAlbum.value.media.length)
      const batch = newAlbum.value.media.slice(startIndex, endIndex)
      
      uploadStatus.value = `Upload du lot ${batchIndex + 1}/${totalBatches}...`
      
      try {
        const formData = new FormData()
        batch.forEach((media, index) => {
          formData.append('files', media.file)
          if (media.caption) {
            formData.append('captions', media.caption)
          }
        })
        
        await axios.post(`/api/albums/${album.id}/media`, formData, {
          headers: { 'Content-Type': 'multipart/form-data' },
          onUploadProgress: (progressEvent) => {
            // Update progress for this batch
            const batchProgress = (progressEvent.loaded / progressEvent.total) * 100
            const overallProgress = ((batchIndex * batchSize + batch.length) / newAlbum.value.media.length) * 100
            uploadProgress.value = Math.min(overallProgress, 100)
          }
        })
        
        // Mark batch as successful
        batch.forEach((media, index) => {
          const globalIndex = startIndex + index
          currentFileIndex.value = globalIndex + 1
          uploadSuccess.value.push({
            file: media.name,
            type: media.type
          })
        })
        
      } catch (error) {
        console.error(`Error uploading batch ${batchIndex + 1}:`, error)
        
        // Mark batch as failed
        batch.forEach((media, index) => {
          const globalIndex = startIndex + index
          currentFileIndex.value = globalIndex + 1
          uploadErrors.value.push({
            file: media.name,
            message: error.response?.data?.detail || 'Erreur lors de l\'upload'
          })
        })
      }
      
      // Small delay between batches to avoid overwhelming the server
      if (batchIndex < totalBatches - 1) {
        await new Promise(resolve => setTimeout(resolve, 100))
      }
    }
    
    uploadStatus.value = 'Finalisation...'
    uploadProgress.value = 100
    
    // Refresh albums list
    await fetchAlbums()
    
    // Show results
    if (uploadErrors.value.length === 0) {
      toast.success(`Album créé avec succès ! ${uploadSuccess.value.length} fichier(s) uploadé(s)`)
    } else if (uploadSuccess.value.length > 0) {
      toast.warning(`Album créé avec ${uploadSuccess.value.length} fichier(s) uploadé(s) et ${uploadErrors.value.length} erreur(s)`)
    } else {
      toast.error('Erreur lors de l\'upload de tous les fichiers')
    }
    
    showCreateModal.value = false
    resetForm()
    
  } catch (error) {
    console.error('Error creating album:', error)
    toast.error('Erreur lors de la création de l\'album')
  } finally {
    creating.value = false
    isUploading.value = false
    uploadProgress.value = 0
    currentFileIndex.value = 0
    totalFiles.value = 0
    uploadStatus.value = ''
  }
}

function resetForm() {
  // Clean up media previews
  newAlbum.value.media.forEach(media => {
    if (media.preview && media.preview.startsWith('blob:')) {
      URL.revokeObjectURL(media.preview)
    }
  })
  
  // Reset form data
  newAlbum.value = {
    title: '',
    description: '',
    event_id: '',
    media: []
  }
  
  // Reset upload states
  uploadProgress.value = 0
  isUploading.value = false
  uploadStatus.value = ''
  currentFileIndex.value = 0
  totalFiles.value = 0
  uploadErrors.value = []
  uploadSuccess.value = []
}

async function fetchAlbums() {
  loading.value = true
  try {
    const response = await axios.get(`/api/albums?limit=12&offset=${offset.value}`)
    if (offset.value === 0) {
      albums.value = response.data
    } else {
      albums.value.push(...response.data)
    }
    
    hasMoreAlbums.value = response.data.length === 12
  } catch (error) {
    toast.error('Erreur lors du chargement des albums')
  }
  loading.value = false
}

async function fetchEvents() {
  try {
    const response = await axios.get('/api/events')
    events.value = response.data
  } catch (error) {
    console.error('Error fetching events:', error)
  }
}

async function loadMoreAlbums() {
  offset.value += 12
  await fetchAlbums()
}

onMounted(() => {
  fetchAlbums()
  fetchEvents()
  fetchUsers()
  fetchUploadLimits()
})
</script>