<template>
  <div class="custom-carousel">
    <!-- 轮播图容器 -->
    <q-responsive :ratio="36 / 9" class="carousel-container">
      <!-- 骨架屏 -->
      <div v-if="isLoading" class="carousel-skeleton full-width full-height">
        <q-skeleton animation="none" type="rect" class="full-width full-height" style="border-radius: 8px;" />
      </div>

      <!-- 单个模式 -->
      <div v-else-if="mode === 'single'" class="full-width full-height">
        <q-carousel v-model="currentSlide" animated swipeable infinite :autoplay="autoplay" :arrows="arrows"
          class="full-width full-height">
          <q-carousel-slide :padding="false" v-for="(item, index) in items" :key="index" :name="index"
            class="column no-wrap flex-center">
            <div class="slide-content full-width full-height flex flex-center">
              <q-img v-if="item.image" :src="item.image" :alt="item.title || 'Slide image'"
                class="full-width full-height" fit="cover" />
              <div v-else class="slide-placeholder bg-grey-3 full-width full-height flex flex-center">
                <span class="text-grey-6">{{ item.title || 'Slide ' + (index + 1) }}</span>
              </div>
            </div>
          </q-carousel-slide>
        </q-carousel>
      </div>

      <!-- 卡片模式 -->
      <div v-else class="carousel-cards full-width full-height relative-position">
        <div class="cards-container full-width full-height flex items-center">
          <div v-for="(item, index) in items" :key="index" class="card-slide absolute transition-all" :class="{
            'card-active': index === currentSlide,
            'card-left': getCardPosition(index) === 'left',
            'card-right': getCardPosition(index) === 'right',
            'card-hidden': getCardPosition(index) === 'hidden'
          }" :style="getCardStyle(index)" @click="goToSlide(index)">
            <q-card class="full-width full-height cursor-pointer card-hover">
              <q-img v-if="item.image" :src="item.image" :alt="item.title || 'Card image'"
                class="full-width full-height" fit="cover" />
              <div v-else class="card-placeholder bg-grey-3 full-width full-height flex flex-center">
                <span class="text-grey-6">{{ item.title || 'Card ' + (index + 1) }}</span>
              </div>
            </q-card>
          </div>
        </div>

        <!-- 卡片模式导航箭头 -->
        <q-btn v-if="arrows" round color="white" text-color="grey-8" icon="chevron_left"
          class="absolute-left q-ml-md carousel-arrow"
          style="top: 50%; transform: translateY(-50%); z-index: 10; width: 40px; height: 40px; min-width: 40px; min-height: 40px;"
          @click="previousSlide" />
        <q-btn v-if="arrows" round color="white" text-color="grey-8" icon="chevron_right"
          class="absolute-right q-mr-md carousel-arrow"
          style="top: 50%; transform: translateY(-50%); z-index: 10; width: 40px; height: 40px; min-width: 40px; min-height: 40px;"
          @click="nextSlide" />
      </div>
    </q-responsive>

    <!-- 自定义指示点 -->
    <div v-if="!isLoading" class="carousel-indicators q-mt-sm flex justify-center items-center q-gutter-xs">
      <div v-for="(item, index) in items" :key="index" class="indicator relative-position cursor-pointer"
        @click="goToSlide(index)">
        <!-- 背景指示点 -->
        <div class="indicator-background"></div>
        <!-- 激活状态指示点 -->
        <div v-if="index === currentSlide" class="indicator-active-dot"></div>
        <!-- 进度条 -->
        <div v-if="index === currentSlide && autoplay" class="indicator-progress"
          :style="{ width: progressWidth + '%' }"></div>
      </div>
    </div>

    <!-- 骨架屏指示点 -->
    <div v-else class="carousel-indicators q-mt-sm flex justify-center items-center q-gutter-xs">
      <q-skeleton v-for="n in 4" :key="n" type="rect" width="24px" height="4px" style="border-radius: 4px;" />
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'

// Props
const props = defineProps({
  items: {
    type: Array,
    default: () => []
  },
  mode: {
    type: String,
    default: 'single', // 'single' | 'cards'
    validator: (value) => ['single', 'cards'].includes(value)
  },
  autoplay: {
    type: [Boolean, Number],
    default: 3000
  },
  arrows: {
    type: Boolean,
    default: true
  },
  isLoading: {
    type: Boolean,
    default: false
  }
})

// Reactive data
const currentSlide = ref(0)
const progressWidth = ref(0)
let autoplayTimer = null
let progressTimer = null

// Computed
const totalSlides = computed(() => props.items.length)

// Methods
const goToSlide = (index) => {
  if (index >= 0 && index < totalSlides.value) {
    currentSlide.value = index
    resetProgress()
  }
}

const nextSlide = () => {
  const nextIndex = (currentSlide.value + 1) % totalSlides.value
  goToSlide(nextIndex)
}

const previousSlide = () => {
  const prevIndex = currentSlide.value === 0 ? totalSlides.value - 1 : currentSlide.value - 1
  goToSlide(prevIndex)
}

// 卡片模式相关方法
const getCardPosition = (index) => {
  const diff = index - currentSlide.value
  if (diff === 0) return 'center'
  if (diff === 1 || (diff === -(totalSlides.value - 1) && totalSlides.value > 2)) return 'right'
  if (diff === -1 || (diff === totalSlides.value - 1 && totalSlides.value > 2)) return 'left'
  return 'hidden'
}

const getCardStyle = (index) => {
  const position = getCardPosition(index)
  const baseStyle = {
    height: '100%',
    transition: 'all 0.3s ease-in-out'
  }

  switch (position) {
    case 'center':
      return {
        ...baseStyle,
        width: '80%',
        left: '10%',
        top: '0',
        zIndex: 3,
        opacity: 1,
        transform: 'scale(1)'
      }
    case 'left':
      return {
        ...baseStyle,
        width: '70%',
        left: '-3%',
        zIndex: 1,
        opacity: 0.7,
        transform: 'scale(0.9)'
      }
    case 'right':
      return {
        ...baseStyle,
        width: '70%',
        right: '-3%',
        zIndex: 1,
        opacity: 0.7,
        transform: 'scale(0.9)'
      }
    default:
      return {
        ...baseStyle,
        width: '80%',
        left: '10%',
        top: '0',
        zIndex: 0,
        opacity: 0,
        transform: 'scale(0.8)'
      }
  }
}

// 自动播放相关方法
const startAutoplay = () => {
  if (!props.autoplay || totalSlides.value <= 1) return

  const interval = typeof props.autoplay === 'number' ? props.autoplay : 3000

  autoplayTimer = setInterval(() => {
    nextSlide()
  }, interval)

  startProgress(interval)
}

const stopAutoplay = () => {
  if (autoplayTimer) {
    clearInterval(autoplayTimer)
    autoplayTimer = null
  }
  stopProgress()
}

const startProgress = (duration) => {
  progressWidth.value = 0
  const startTime = Date.now()

  const updateProgress = () => {
    const elapsed = Date.now() - startTime
    const progress = Math.min((elapsed / duration) * 100, 100)
    progressWidth.value = progress

    if (progress < 100) {
      progressTimer = requestAnimationFrame(updateProgress)
    }
  }

  progressTimer = requestAnimationFrame(updateProgress)
}

const stopProgress = () => {
  if (progressTimer) {
    cancelAnimationFrame(progressTimer)
    progressTimer = null
  }
}

const resetProgress = () => {
  stopProgress()
  if (props.autoplay) {
    const interval = typeof props.autoplay === 'number' ? props.autoplay : 3000
    setTimeout(() => {
      startProgress(interval)
    }, 100)
  }
}

// 监听当前幻灯片变化
watch(currentSlide, () => {
  if (props.autoplay) {
    stopAutoplay()
    startAutoplay()
  }
})

// 生命周期
onMounted(() => {
  if (props.autoplay && totalSlides.value > 1) {
    startAutoplay()
  }
})

onUnmounted(() => {
  stopAutoplay()
})
</script>

<style scoped>
:deep(.q-carousel__slide) {
  padding: 0;
}

.custom-carousel {
  width: 100%;
  max-width: 100%;
}

.carousel-container {
  border-radius: 8px;
  overflow: hidden;
}

/* 卡片模式样式 */
.carousel-cards {
  perspective: 1000px;
}

.card-slide {
  border-radius: 8px;
  overflow: hidden;
}

.card-hover:hover {
  transform: scale(1.02) !important;
  transition: transform 0.2s ease;
}

.card-active .card-hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

/* 指示点样式 */
.carousel-indicators {
  padding: 0 16px;
}

.indicator {
  width: 24px;
  height: 4px;
  border-radius: 4px;
  position: relative;
  overflow: hidden;
}

.indicator-background {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  z-index: 1;
}

.indicator-active-dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.3);
  border-radius: 4px;
  z-index: 2;
}

.indicator-progress {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: linear-gradient(90deg, var(--q-primary) 0%, var(--q-secondary) 100%);
  border-radius: 4px;
  transform-origin: left center;
  z-index: 3;
  transition: width 0.1s linear;
}

/* 导航箭头样式 */
.carousel-arrow {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: all 0.2s ease;
}

.carousel-arrow:hover {
  transform: translateY(-50%) scale(1.1);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* 占位符样式 */
.slide-placeholder,
.card-placeholder {
  border-radius: 8px;
  border: 2px dashed #ccc;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .carousel-arrow {
    display: none;
  }

  .indicator {
    width: 24px;
    height: 4px;
  }
}
</style>