<template>
  <div class="progressive-image-container" :class="containerClass" :style="containerStyle">
    <!-- Blur placeholder background -->
    <div v-if="!isLoaded"
         :class="['progressive-image-placeholder', { 'shimmer-active': !isLoaded && !hasError }]"
         :style="placeholderStyle">
      <!-- Branded shimmer effect using semantic colors -->
      <div v-if="!isLoaded && !hasError" class="absolute inset-0 bg-gradient-to-r from-accent/40 via-primary/40 via-accent/70 to-accent/50 animate-pulse"></div>
    </div>

    <!-- Main image -->
    <img ref="imageRef" :src="src" :alt="alt" :class="[
      'progressive-image',
      imageClass,
      {
        'progressive-image-loading': !isLoaded,
        'progressive-image-loaded': isLoaded,
        'progressive-image-error': hasError
      }
    ]" :loading="loading" @load="handleLoad" @error="handleError" /> -->

    <!-- Loading indicator (optional) -->
    <div v-if="showLoadingIndicator && !isLoaded && !hasError" class="progressive-image-loading-indicator">
      <div class="progressive-image-spinner" />
    </div>

    <!-- Error or no image state (optional) -->
    <div v-if="hasError && showErrorState" class="progressive-image-error-state">
      <slot name="error">
        <div class="progressive-image-error-content">
          <Package class="w-6 h-6 text-muted-foreground" />
          <span class="text-xs text-muted-foreground">{{ errorMessage }}</span>
        </div>
      </slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { Package } from 'lucide-vue-next'

interface Props {
  /**
   * The main image source URL
   */
  src: string

  /**
   * Alt text for the image
   */
  alt: string

  /**
   * Optional base64 thumbnail for blur effect
   * If not provided, will use CSS blur with background color
   */
  thumbnail?: string

  /**
   * Blur radius for the placeholder (in pixels)
   */
  blurRadius?: number

  /**
   * Background color for the placeholder when no thumbnail is provided
   */
  backgroundColor?: string

  /**
   * Duration of the fade-in transition (in milliseconds)
   */
  transitionDuration?: number

  /**
   * Loading strategy for the image
   */
  loading?: 'lazy' | 'eager'

  /**
   * Additional CSS classes for the container
   */
  containerClass?: string | string[]

  /**
   * Additional CSS classes for the image
   */
  imageClass?: string | string[]

  /**
   * Whether to show a loading spinner
   */
  showLoadingIndicator?: boolean

  /**
   * Whether to show error state when image fails to load
   */
  showErrorState?: boolean

  /**
   * Custom container styles
   */
  containerStyle?: Record<string, string>
}

interface Emits {
  (e: 'load', event: Event): void
  (e: 'error', event: Event): void
  (e: 'loading-start'): void
  (e: 'loading-complete'): void
}

const props = withDefaults(defineProps<Props>(), {
  blurRadius: 10,
  backgroundColor: 'hsl(var(--muted))',
  transitionDuration: 300,
  loading: 'lazy',
  showLoadingIndicator: false,
  showErrorState: true
})

const emit = defineEmits<Emits>()

// Reactive state
const imageRef = ref<HTMLImageElement>()
const isLoaded = ref(false)
const hasError = ref(false)
const isLoading = ref(false)

// Check if this is a placeholder/no-image URL
const isNoImage = computed(() => {
  return props.src.includes('/placeholder-product.png') ||
         props.src === '' ||
         !props.src
})

// Dynamic error message based on whether image exists
const errorMessage = computed(() => {
  if (isNoImage.value) {
    return 'No image available'
  }
  return 'Failed to load'
})

// Computed styles
const placeholderStyle = computed(() => {
  const hasThumb = props.thumbnail && props.thumbnail.trim()

  // Create a subtle gradient pattern when no thumbnail (theme-aware)
  const gradientBg = hasThumb
    ? 'none'
    : `linear-gradient(135deg, hsl(var(--muted)) 0%, hsl(var(--muted) / 0.5) 50%, hsl(var(--muted)) 100%)`

  return {
    '--blur-radius': `${props.blurRadius}px`,
    '--transition-duration': `${props.transitionDuration}ms`,
    '--placeholder-bg': gradientBg,
    backgroundImage: hasThumb ? `url(${props.thumbnail})` : gradientBg,
    backgroundColor: hasThumb ? 'transparent' : props.backgroundColor,
    filter: hasThumb ? `blur(${props.blurRadius}px)` : 'none',
    transform: hasThumb ? 'scale(1.1)' : 'scale(1)', // Only scale if using thumbnail
  }
})

// Note: generatePlaceholder function can be added here if needed for dynamic thumbnail generation

// Event handlers
const handleLoad = (event: Event) => {
  isLoaded.value = true
  isLoading.value = false
  emit('load', event)
  emit('loading-complete')
}

const handleError = (event: Event) => {
  hasError.value = true
  isLoading.value = false
  emit('error', event)
  emit('loading-complete')
}

// Initialize loading state
onMounted(() => {
  if (imageRef.value && !imageRef.value.complete) {
    isLoading.value = true
    emit('loading-start')
  } else if (imageRef.value?.complete) {
    isLoaded.value = true
  }
})

// Expose methods for parent components
defineExpose({
  reload: () => {
    if (imageRef.value) {
      isLoaded.value = false
      hasError.value = false
      isLoading.value = true
      imageRef.value.src = props.src
      emit('loading-start')
    }
  },
  isLoaded: () => isLoaded.value,
  hasError: () => hasError.value,
  isLoading: () => isLoading.value
})
</script>

<style scoped>
.progressive-image-container {
  position: relative;
  overflow: hidden;
}

.progressive-image-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  transition: opacity var(--transition-duration, 300ms) ease-out;
}

/* Add shimmer effect when image is loading - follows Tailwind animation patterns */
.progressive-image-placeholder.shimmer-active {
  position: relative;
  background: linear-gradient(135deg, hsl(var(--muted)) 0%, hsl(var(--muted) / 0.5) 50%, hsl(var(--muted)) 100%) !important;
  overflow: hidden;
}

/* Accessibility: Respect user's reduced motion preference */
@media (prefers-reduced-motion: reduce) {
  .shimmer-overlay {
    animation: none !important;
  }
}


.progressive-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--transition-duration, 300ms) ease-out;
}

.progressive-image-loading {
  opacity: 0;
}

.progressive-image-loaded {
  opacity: 1;
}

.progressive-image-error {
  opacity: 0.5;
}

/* Hide placeholder when image is loaded */
.progressive-image-loaded + .progressive-image-placeholder {
  opacity: 0;
}

.progressive-image-loading-indicator {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(255, 255, 255, 0.8);
}

.progressive-image-spinner {
  width: 1.5rem;
  height: 1.5rem;
  border: 2px solid;
  border-color: hsl(var(--primary));
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

.progressive-image-error-state {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, hsl(var(--muted) / 0.5), hsl(var(--muted)));
}

.progressive-image-error-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
}

/* Ensure smooth transitions */
.progressive-image-container * {
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

/* Keyframe animations */
@keyframes spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

/* DEBUG: Enhanced keyframes for testing */
@keyframes shimmer {
  0% {
    background-position: -100% 0;
  }
  100% {
    background-position: 100% 0;
  }
}

@keyframes fadeInScale {
  from {
    opacity: 0;
    transform: scale(1.05);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

.progressive-image-loaded {
  animation: fadeInScale var(--transition-duration, 300ms) ease-out;
}
</style>

