<template>
  <div class="media-asset-board-wrapper" :class="{ selected }" :style="{
    width: props.width + 'px',
    height: props.height + 'px',
    position: 'relative',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    overflow: 'hidden',
    flexDirection: 'column',
    gap: '8px',
    padding: '8px'
  }" @click="$emit('click', $event)">
    <!-- 预览窗口 -->
    <div v-if="mediaItems.length > 0" class="preview-container">
      <template v-for="(item, index) in mediaItems" :key="index">
        <div v-show="currentMediaIndex === index" class="media-item" :class="{ 'active': currentMediaIndex === index }">
          <img v-if="item.type === 1" :src="item.url" :alt="item.name" class="media-content" />
          <video v-else-if="item.type === 2" :src="item.url" class="media-content" preload="metadata" muted
            @loadeddata="onVideoLoaded"></video>
        </div>
      </template>

      <!-- 轮播组名称显示 -->
      <div v-if="carouselGroup.name" class="group-name-overlay">
        {{ carouselGroup.name }}
      </div>
    </div>

    <!-- 无媒体时的默认状态 -->
    <div v-else class="media-asset-icon">
      <svg width="32" height="32" viewBox="0 0 32 32" fill="none">
        <rect x="3" y="3" width="26" height="26" rx="6" fill="#f3f6fa" stroke="#409eff" stroke-width="2" />
        <path d="M8 22l6-6 4 4 6-6" stroke="#409eff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
        <circle cx="11" cy="12" r="2" fill="#409eff" />
      </svg>
      <div v-if="!props.readonly" class="select-hint">
        {{ carouselGroup.name ? `轮播组：${carouselGroup.name}` : '请选择轮播组' }}
      </div>
    </div>

    <!-- Resize -->
    <template v-if="selected && !props.readonly">
      <div v-for="dir in ['nw', 'ne', 'sw', 'se']" :key="dir" class="resize-handle" :class="'resize-' + dir"
        @mousedown.stop="onResizeMouseDown(dir, $event)" />
    </template>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onUnmounted, defineProps, defineEmits } from 'vue';
import { getItem, getItemFileRelList } from '@/api/smsb/source/item';
import { getMinioData } from '@/api/smsb/source/minioData';

const emit = defineEmits(['update:mediaId', 'resize', 'click']);

const props = withDefaults(
  defineProps<{
    width: number;
    height: number;
    mediaId?: string;
    selected?: boolean;
    readonly?: boolean;
    modelValue?: any;
  }>(),
  {
    selected: false,
    readonly: false,
    modelValue: null
  }
);

interface MediaItem {
  id: string | number;
  type: number; // 1-图片 2-视频
  url: string;
  duration: number; // 秒
  name?: string;
}

const mediaItems = ref<MediaItem[]>([]);
const currentMediaIndex = ref(0);
let slideInterval: number | null = null;

// 解析轮播组数据
const carouselGroup = computed(() => {
  try {
    if (props.mediaId) {
      return JSON.parse(props.mediaId);
    }
  } catch (e) {
    console.error('Failed to parse mediaId:', e);
  }
  return {};
});

const selected = computed(() => !!props.selected);

// 清理轮播
const clearSlideShow = () => {
  if (slideInterval !== null) {
    clearInterval(slideInterval);
    slideInterval = null;
  }
};

// 开始轮播
const startSlideShow = () => {
  clearSlideShow();
  if (mediaItems.value.length <= 1) return;

  const playNext = () => {
    const currentItem = mediaItems.value[currentMediaIndex.value];
    const duration = (currentItem?.duration || 5) * 1000; // 转为毫秒，默认5秒

    // console.log(`播放第 ${currentMediaIndex.value + 1}/${mediaItems.value.length} 项，类型: ${currentItem.type}，时长: ${duration}ms`);

    slideInterval = window.setTimeout(() => {
      currentMediaIndex.value = (currentMediaIndex.value + 1) % mediaItems.value.length;
      playNext();
    }, duration);
  };

  // 开始第一项播放
  playNext();
};

// 获取文件类型（1-图片，2-视频）
const getFileType = (type: number): number => {
  // 1-图片，2-视频，3-音频
  return type === 2 ? 2 : 1; // 视频为2，其他都视为图片
};

// 加载轮播组媒体项
const loadCarouselGroupMedia = async () => {
  // console.log('开始加载轮播组媒体项', carouselGroup.value);
  try {
    if (!carouselGroup.value || !carouselGroup.value.id) {
      // console.log('轮播组ID不存在');
      mediaItems.value = [];
      return;
    }

    // 1. 获取轮播组关联的文件关系列表
    const relRes = await getItemFileRelList(carouselGroup.value.id);
    // console.log('获取到轮播组关联文件关系:', relRes.data);

    if (!Array.isArray(relRes.data) || relRes.data.length === 0) {
      // console.log('轮播组没有关联的文件');
      mediaItems.value = [];
      return;
    }

    // 2. 处理每个关联文件
    const items: MediaItem[] = [];
    for (const rel of relRes.data) {
      try {
        // 获取文件详情
        // console.log(`加载文件详情: ${rel.fileId}`);
        const fileRes = await getMinioData(rel.fileId);
        const fileInfo = fileRes.data;
        // console.log('文件详情:', fileInfo);

        if (fileInfo) {
          // 使用 fileUrl 如果存在，否则回退到构建的 URL
          const fileUrl = fileInfo.fileUrl || `/api/source/file/${rel.fileId}`;
          // console.log(`文件 ${fileInfo.originalName} 的 URL:`, fileUrl);

          items.push({
            id: rel.fileId,
            type: getFileType(fileInfo.type),
            url: fileUrl,
            duration: rel.duration || 5, // 使用关联关系中的 duration
            name: fileInfo.originalName
          });
        }
      } catch (fileError) {
        console.error(`加载文件 ${rel.fileId} 详情失败:`, fileError);
      }
    }

    // 3. 按sort排序
    items.sort((a, b) => (a as any).sort - (b as any).sort);
    mediaItems.value = items;
    // console.log('最终媒体项列表:', mediaItems.value);

    // 4. 开始轮播
    currentMediaIndex.value = 0;
    startSlideShow();
  } catch (error) {
    console.error('加载轮播组媒体项失败:', error);
    mediaItems.value = [];
  }
};

// 监听mediaId变化
watch(
  () => props.mediaId,
  (newVal) => {
    if (newVal) {
      loadCarouselGroupMedia();
    } else {
      mediaItems.value = [];
      clearSlideShow();
    }
  },
  { immediate: true }
);

const onVideoLoaded = (event: Event) => {
  const video = event.target as HTMLVideoElement;
  video.pause();
  video.currentTime = 0;
};

onUnmounted(() => {
  clearSlideShow();
});

// 暴露方法，供父组件调用
const getCarouselGroupId = () => {
  return props.mediaId;
};

defineExpose({
  getCarouselGroupId
});

let startX = 0,
  startY = 0,
  startW = 0,
  startH = 0;

function onResizeMouseDown(dir: string, e: MouseEvent) {
  e.stopPropagation();
  startX = e.clientX;
  startY = e.clientY;
  startW = props.width;
  startH = props.height;

  function onMouseMove(ev: MouseEvent) {
    let dx = ev.clientX - startX;
    let dy = ev.clientY - startY;
    let newW = startW;
    let newH = startH;
    if (dir.includes('e')) newW = Math.max(40, startW + dx);
    if (dir.includes('s')) newH = Math.max(40, startH + dy);
    if (dir.includes('w')) newW = Math.max(40, startW - dx);
    if (dir.includes('n')) newH = Math.max(40, startH - dy);
    emit('resize', { width: newW, height: newH });
  }

  function onMouseUp() {
    window.removeEventListener('mousemove', onMouseMove);
    window.removeEventListener('mouseup', onMouseUp);
  }

  window.addEventListener('mousemove', onMouseMove);
  window.addEventListener('mouseup', onMouseUp);
}
</script>

<style scoped>
.media-asset-board-wrapper {
  background: #f9fbfd;
  border: 2px dashed #b3c7e6;
  border-radius: 10px;
  transition: border-color 0.2s;
  position: relative;
  overflow: hidden;
  box-sizing: border-box;
}

.select-hint {
  margin-top: 8px;
  font-size: 12px;
  color: #909399;
}

.media-asset-board-wrapper.selected {
  border-color: #409eff;
}

.preview-container {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.media-item {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.5s ease-in-out;
}

.media-item.active {
  opacity: 1;
}

.media-content {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.media-asset-icon {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: #f5f7fa;
}

.group-name-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  padding: 4px 8px;
  font-size: 12px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.resize-handle {
  position: absolute;
  width: 10px;
  height: 10px;
  background: #fff;
  border: 2px solid #409eff;
  border-radius: 50%;
  z-index: 10;
  cursor: pointer;
}

.resize-nw {
  left: -6px;
  top: -6px;
  cursor: nwse-resize;
}

.resize-ne {
  right: -6px;
  top: -6px;
  cursor: nesw-resize;
}

.resize-sw {
  left: -6px;
  bottom: -6px;
  cursor: nesw-resize;
}

.resize-se {
  right: -6px;
  bottom: -6px;
  cursor: nwse-resize;
}
</style>
