<template>
  <div class="mosquito-poster-card" :style="{ width, height }">
    <div 
      v-if="loading" 
      class="loading-placeholder"
      :style="{ width, height }"
    >
      <div class="loading-skeleton"></div>
    </div>
    
    <div 
      v-else-if="error" 
      class="error-placeholder"
      :style="{ width, height }"
      @click="retryLoad"
    >
      <div class="error-content">
        <svg class="w-8 h-8 text-red-400 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
        </svg>
        <p class="text-sm text-gray-600">加载失败</p>
        <p class="text-xs text-gray-500 mt-1">{{ error.message }}</p>
      </div>
    </div>
    
    <img
      v-else
      :src="posterUrl"
      alt="分享海报"
      :style="{ width, height }"
      class="poster-image"
      @load="onImageLoad"
      @error="onImageError"
      @click="$emit('click')"
    />
    
    <!-- 加载指示器 -->
    <div v-if="loading" class="loading-indicator">
      <svg class="animate-spin h-6 w-6 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.647z"></path>
      </svg>
    </div>
    
    <!-- 重试按钮 -->
    <button
      v-if="showRetry"
      class="retry-button"
      @click="retryLoad"
    >
      重试
    </button>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { useMosquito } from '../index'

interface Props {
  activityId: number
  userId: number
  template?: string
  width?: string
  height?: string
}

const props = withDefaults(defineProps<Props>(), {
  template: 'default',
  width: '300px',
  height: '400px'
})

const emit = defineEmits<{
  click: []
  error: [error: Error]
  loaded: []
}>()

const { getPosterImage, config } = useMosquito()
const loading = ref(false)
const error = ref<Error | null>(null)
const posterUrl = ref('')
const retryCount = ref(0)
const showRetry = ref(false)

// 生成海报URL
const generatePosterUrl = () => {
  const timestamp = Date.now()
  return `${config.baseUrl}/api/v1/me/poster/image?activityId=${props.activityId}&userId=${props.userId}&template=${props.template}&t=${timestamp}`
}

// 加载海报
const loadPoster = async () => {
  if (loading.value) return
  
  loading.value = true
  error.value = null
  showRetry.value = false
  
  try {
    // 尝试使用API获取海报
    const imageBlob = await getPosterImage(props.activityId, props.userId, props.template)
    
    // 创建本地URL
    const url = URL.createObjectURL(imageBlob)
    posterUrl.value = url
    retryCount.value = 0
    emit('loaded')
  } catch (err) {
    console.error('加载海报失败:', err)
    error.value = err as Error
    emit('error', error.value)
    
    // 如果API失败，使用备用URL
    if (retryCount.value < 3) {
      retryCount.value++
      setTimeout(() => {
        posterUrl.value = generatePosterUrl()
      }, 1000 * retryCount.value)
    } else {
      showRetry.value = true
    }
  } finally {
    loading.value = false
  }
}

// 图片加载成功
const onImageLoad = () => {
  showRetry.value = false
  retryCount.value = 0
}

// 图片加载失败
const onImageError = () => {
  if (!error.value) {
    error.value = new Error('海报图片加载失败')
    emit('error', error.value)
  }
}

// 重试加载
const retryLoad = () => {
  posterUrl.value = generatePosterUrl()
  loadPoster()
}

// 组件挂载时加载海报
loadPoster()

// 监听参数变化重新加载
watch(() => [props.activityId, props.userId, props.template], () => {
  loadPoster()
}, { deep: true })
</script>

<style scoped>
.mosquito-poster-card {
  @apply relative overflow-hidden rounded-lg shadow-md cursor-pointer transition-shadow hover:shadow-lg;
  background-color: var(--mosquito-bg);
}

.loading-placeholder {
  @apply flex items-center justify-center;
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: loading 1.5s infinite;
}

.loading-skeleton {
  @apply w-16 h-16 bg-gray-300 rounded;
}

.error-placeholder {
  @apply flex items-center justify-center bg-mosquito-bg;
}

.error-content {
  @apply text-center;
}

.poster-image {
  @apply object-cover;
}

.loading-indicator {
  @apply absolute inset-0 flex items-center justify-center bg-black bg-opacity-50;
}

.retry-button {
  @apply absolute bottom-2 left-1/2 transform -translate-x-1/2 px-4 py-2 bg-black bg-opacity-70 text-white text-sm rounded-md hover:bg-opacity-80 transition-opacity;
}

@keyframes loading {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}
</style>
