<template>
  <div class="image-viewer">
    <!-- Primary image display with progressive loading -->
    <div v-if="currentImageSrc" class="primary-image relative">
      <ProgressiveImage
        :src="currentImageSrc"
        :alt="alt || 'Image'"
        :container-class="containerClass"
        :image-class="[imageClass, showLightbox ? 'cursor-pointer' : ''].join(' ')"
        :blur-radius="blurRadius"
        :transition-duration="transitionDuration"
        :loading="loading"
        :show-loading-indicator="showLoadingIndicator"
        @click="handleImageClick"
        @error="handleImageError"
      />

      <!-- Image counter badge -->
      <Badge
        v-if="showBadge && images.length > 1"
        class="absolute top-2 right-2"
        variant="secondary"
      >
        {{ currentImageIndex + 1 }} of {{ images.length }}
      </Badge>

      <!-- Image cycling controls (if multiple images) -->
      <template v-if="images.length > 1 && showCycleControls">
        <Button
          @click="previousImage"
          variant="ghost"
          size="icon"
          class="absolute left-2 top-1/2 -translate-y-1/2 bg-background/80 backdrop-blur hover:bg-background/90 opacity-0 group-hover:opacity-100 transition-opacity"
          aria-label="Previous image"
        >
          <ChevronLeft class="h-4 w-4" />
        </Button>
        <Button
          @click="nextImage"
          variant="ghost"
          size="icon"
          class="absolute right-2 top-1/2 -translate-y-1/2 bg-background/80 backdrop-blur hover:bg-background/90 opacity-0 group-hover:opacity-100 transition-opacity"
          aria-label="Next image"
        >
          <ChevronRight class="h-4 w-4" />
        </Button>
      </template>
    </div>

    <!-- Fallback when no image -->
    <div v-else :class="containerClass">
      <div class="w-full h-full bg-gradient-to-br from-muted/50 to-muted flex items-center justify-center">
        <div class="text-center">
          <Package class="w-12 h-12 mx-auto text-muted-foreground mb-2" />
          <span class="text-xs text-muted-foreground">No image available</span>
        </div>
      </div>
    </div>

    <!-- Thumbnail gallery -->
    <div
      v-if="showThumbnails && images.length > 1"
      class="thumbnail-gallery flex gap-2 mt-3 overflow-x-auto"
    >
      <button
        v-for="(imageSrc, index) in images"
        :key="index"
        @click="selectImage(index)"
        class="thumbnail-item flex-shrink-0 rounded-md overflow-hidden border-2 transition-all"
        :class="{
          'border-primary': index === currentImageIndex,
          'border-transparent hover:border-muted-foreground': index !== currentImageIndex
        }"
        :aria-label="`View image ${index + 1}`"
      >
        <ProgressiveImage
          :src="imageSrc"
          :alt="`Thumbnail ${index + 1}`"
          container-class="w-16 h-16"
          image-class="w-16 h-16 object-cover"
          :blur-radius="4"
          :transition-duration="200"
          loading="lazy"
          :show-loading-indicator="false"
        />
      </button>
    </div>

    <!-- Lightbox -->
    <ImageLightbox
      v-if="showLightbox"
      ref="lightboxRef"
      :images="lightboxImages"
      :options="lightboxOptions"
      @open="handleLightboxOpen"
      @close="handleLightboxClose"
      @navigate="handleLightboxNavigate"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { ChevronLeft, ChevronRight, Package } from 'lucide-vue-next'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import ProgressiveImage from './ProgressiveImage.vue'
import ImageLightbox from './ImageLightbox.vue'
import type { LightboxImage, UseImageLightboxOptions } from './composables/useImageLightbox'

interface Props {
  /**
   * Array of image URLs to display
   */
  images: string[]

  /**
   * Alt text for images
   */
  alt?: string

  /**
   * CSS classes for the container
   */
  containerClass?: string

  /**
   * CSS classes for the image element
   */
  imageClass?: string

  /**
   * Blur radius for progressive loading placeholder
   */
  blurRadius?: number

  /**
   * Transition duration for progressive loading
   */
  transitionDuration?: number

  /**
   * Image loading strategy
   */
  loading?: 'lazy' | 'eager'

  /**
   * Whether to show loading indicator
   */
  showLoadingIndicator?: boolean

  /**
   * Whether to show thumbnail gallery
   */
  showThumbnails?: boolean

  /**
   * Whether to enable lightbox functionality
   */
  showLightbox?: boolean

  /**
   * Whether to show image counter badge
   */
  showBadge?: boolean

  /**
   * Whether to show image cycling controls on hover
   */
  showCycleControls?: boolean

  /**
   * Initial image index to display
   */
  initialIndex?: number

  /**
   * Lightbox configuration options
   */
  lightboxOptions?: UseImageLightboxOptions
}

const props = withDefaults(defineProps<Props>(), {
  alt: '',
  containerClass: 'w-full h-48 bg-muted/50 group',
  imageClass: 'w-full h-48 object-cover',
  blurRadius: 8,
  transitionDuration: 400,
  loading: 'lazy',
  showLoadingIndicator: true,
  showThumbnails: true,
  showLightbox: true,
  showBadge: true,
  showCycleControls: true,
  initialIndex: 0,
  lightboxOptions: () => ({})
})

const emit = defineEmits<{
  error: [error: Event]
  imageChange: [index: number, src: string]
  lightboxOpen: [index: number]
  lightboxClose: []
}>()

// Component state
const currentImageIndex = ref(props.initialIndex)
const lightboxRef = ref<InstanceType<typeof ImageLightbox>>()

// Computed properties
const filteredImages = computed(() => {
  return props.images.filter(img => img && img.trim() !== '')
})

const currentImageSrc = computed(() => {
  if (filteredImages.value.length === 0) return null
  const index = Math.min(currentImageIndex.value, filteredImages.value.length - 1)
  return filteredImages.value[index]
})

const lightboxImages = computed((): LightboxImage[] => {
  return filteredImages.value.map((src, index) => ({
    src,
    alt: `${props.alt || 'Image'} ${index + 1}`
  }))
})

// Methods
const selectImage = (index: number) => {
  if (index >= 0 && index < filteredImages.value.length) {
    currentImageIndex.value = index
    emit('imageChange', index, filteredImages.value[index])
  }
}

const previousImage = () => {
  const newIndex = currentImageIndex.value > 0
    ? currentImageIndex.value - 1
    : filteredImages.value.length - 1
  selectImage(newIndex)
}

const nextImage = () => {
  const newIndex = currentImageIndex.value < filteredImages.value.length - 1
    ? currentImageIndex.value + 1
    : 0
  selectImage(newIndex)
}

const handleImageClick = () => {
  if (props.showLightbox && lightboxRef.value) {
    lightboxRef.value.open(currentImageIndex.value)
  }
}

const handleImageError = (error: Event) => {
  emit('error', error)
}

const handleLightboxOpen = (index: number) => {
  emit('lightboxOpen', index)
}

const handleLightboxClose = () => {
  emit('lightboxClose')
}

const handleLightboxNavigate = (index: number) => {
  // Sync the main viewer with lightbox navigation
  currentImageIndex.value = index
  emit('imageChange', index, filteredImages.value[index])
}

// Watch for changes in images array
watch(() => props.images, () => {
  // Reset to first image if current index is out of bounds
  if (currentImageIndex.value >= filteredImages.value.length) {
    currentImageIndex.value = 0
  }
}, { immediate: true })

// Watch for initialIndex changes
watch(() => props.initialIndex, (newIndex) => {
  if (newIndex !== currentImageIndex.value) {
    selectImage(newIndex)
  }
}, { immediate: true })

// Expose methods for parent components
defineExpose({
  selectImage,
  openLightbox: () => lightboxRef.value?.open(currentImageIndex.value),
  closeLightbox: () => lightboxRef.value?.close(),
  getCurrentIndex: () => currentImageIndex.value,
  getCurrentImage: () => currentImageSrc.value,
  previousImage,
  nextImage
})
</script>

<style scoped>
.image-viewer {
  @apply w-full;
}

.thumbnail-gallery {
  scrollbar-width: thin;
  scrollbar-color: hsl(var(--muted-foreground)) transparent;
}

.thumbnail-gallery::-webkit-scrollbar {
  height: 6px;
}

.thumbnail-gallery::-webkit-scrollbar-track {
  background: transparent;
}

.thumbnail-gallery::-webkit-scrollbar-thumb {
  background-color: hsl(var(--muted-foreground));
  border-radius: 3px;
}

.thumbnail-gallery::-webkit-scrollbar-thumb:hover {
  background-color: hsl(var(--foreground));
}

/* Smooth transitions for all interactive elements */
.thumbnail-item,
.primary-image button {
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
</style>