<template>
  <div class="image-carousel">
    <swiper
      :modules="modules"
      :slides-per-view="props.slidesPerView / props.rows"
      :space-between="props.spaceBetween"
      :loop="true"
      :autoplay="{
        delay: 10,
        disableOnInteraction: false,
        pauseOnMouseEnter: true,
      }"
      :speed="3000"
      :grab-cursor="true"
      :allow-touch-move="true"
      :loop-add-blank-slides="true"
      :grid="{
        rows: props.rows,
        fill: 'column',
      }"
      class="swiper-container"
    >
      <swiper-slide v-for="(image, index) in images" :key="index">
        <el-image
          :src="image.url"
          fit="cover"
          class="carousel-image"
          :preview-src-list="previewList"
          :preview-teleported="true"
        >
          <template #placeholder>
            <div class="image-placeholder">
              <el-icon><Picture /></el-icon>
              <span>图片加载中</span>
            </div>
          </template>
          <template #error>
            <div class="image-placeholder">
              <el-icon><Picture /></el-icon>
              <span>图片加载失败</span>
            </div>
          </template>
        </el-image>
      </swiper-slide>
    </swiper>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { Swiper, SwiperSlide } from 'swiper/vue'
import { Autoplay, FreeMode, Grid } from 'swiper/modules'
import { Picture } from '@element-plus/icons-vue'

// 导入 Swiper 样式
import 'swiper/css'
import 'swiper/css/free-mode'
import 'swiper/css/grid'

// Props
const props = withDefaults(
  defineProps<{
    images: Array<{
      id: number
      url: string
      alt: string
    }>
    slidesPerView?: number
    rows?: number
    itemWidth?: number
    itemHeight?: number
    spaceBetween?: number
  }>(),
  {
    slidesPerView: 4,
    rows: 1,
    itemWidth: 150,
    itemHeight: 190,
    spaceBetween: 16,
  }
)

// Swiper 模块
const modules = [Autoplay, FreeMode, Grid]

// 占位符图片URL
const placeholderUrl =
  'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUwIiBoZWlnaHQ9IjE5MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTUwIiBoZWlnaHQ9IjE5MCIgZmlsbD0iIzE4MTg1MSIvPjx0ZXh0IHg9Ijc1IiB5PSI5NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1mYW1pbHk9IkFyaWFsIiBmb250LXNpemU9IjIwIiBmaWxsPSIjMDBmZmU2Ij7mmK/lu7rliIPlh7rluo88L3RleHQ+PC9zdmc+'

// 预览图片列表
const previewList = computed(() => {
  return props.images.map((image) => image.url || placeholderUrl)
})
</script>

<style lang="scss" scoped>
.image-carousel {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  overflow: hidden;

  .swiper-container {
    width: 100%;
    height: 100%;
  }

  :deep(.swiper-slide) {
    cursor: pointer;
  }

  .carousel-image {
    width: calc(v-bind('props.itemWidth') * 1px) !important;
    height: calc(v-bind('props.itemHeight') * 1px);
  }

  .image-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(0, 255, 230, 0.3);
    color: rgba(0, 255, 230, 0.5);

    .el-icon {
      font-size: calc(v-bind('props.itemHeight') * 0.3 * 1px);
      margin-bottom: 12px;
    }

    span {
      font-size: 14px;
    }
  }
}
</style>
