<template>
  <view class="image-video-upload">
    <!-- 图片上传区域 -->
    <view class="upload-section" v-if="enableImage">
      <view class="section-title">
        <text class="title-text">图片</text>
        <text class="count-text">({{ imageList.length }}/{{ maxImageCount }})</text>
      </view>
      
      <view class="image-list">
        <view 
          class="image-item" 
          v-for="(image, index) in imageList" 
          :key="index"
        >
          <image 
            :src="image.url || image.tempPath" 
            class="image-preview"
            @click="previewImage(index)"
            mode="aspectFill"
          />
          <view class="image-actions">
            <view class="delete-btn" @click="removeImage(index)">
              <uni-icons type="close" size="16" color="#fff"></uni-icons>
            </view>
          </view>
          <view class="image-status" v-if="image.isCompressed">
            <text class="compressed-tag">已压缩</text>
          </view>
        </view>
        
        <view 
          class="add-btn" 
          v-if="imageList.length < maxImageCount"
          @click="chooseImage"
        >
          <uni-icons type="camera" size="24" color="#999"></uni-icons>
          <text class="add-text">添加图片</text>
        </view>
      </view>
    </view>

    <!-- 视频上传区域 -->
    <view class="upload-section" v-if="enableVideo">
      <view class="section-title">
        <text class="title-text">视频</text>
        <text class="count-text">({{ videoList.length }}/{{ maxVideoCount }})</text>
      </view>
      
      <view class="video-list">
        <view 
          class="video-item" 
          v-for="(video, index) in videoList" 
          :key="index"
        >
          <view class="video-preview" @click="previewVideo(index)">
            <image 
              :src="video.thumbnail || '/static/icons/video-placeholder.png'" 
              class="video-thumbnail"
              mode="aspectFill"
            />
            <view class="play-icon">
              <uni-icons type="play-filled" size="24" color="#fff"></uni-icons>
            </view>
            <view class="video-duration" v-if="video.duration">
              {{ formatDuration(video.duration) }}
            </view>
          </view>
          <view class="video-actions">
            <view class="delete-btn" @click="removeVideo(index)">
              <uni-icons type="close" size="16" color="#fff"></uni-icons>
            </view>
          </view>
          <view class="video-info">
            <text class="video-name">{{ video.name }}</text>
            <text class="video-size" v-if="video.size">{{ formatFileSize(video.size) }}</text>
          </view>
        </view>
        
        <view 
          class="add-btn" 
          v-if="videoList.length < maxVideoCount"
          @click="chooseVideo"
        >
          <uni-icons type="videocam" size="24" color="#999"></uni-icons>
          <text class="add-text">添加视频</text>
        </view>
      </view>
    </view>

    <!-- 文件上传区域 -->
    <view class="upload-section" v-if="enableFile">
      <view class="section-title">
        <text class="title-text">文件</text>
        <text class="count-text">({{ fileList.length }}/{{ maxFileCount }})</text>
      </view>
      
      <view class="file-list">
        <view 
          class="file-item" 
          v-for="(file, index) in fileList" 
          :key="index"
        >
          <view class="file-preview" @click="previewFile(index)">
            <view class="file-icon">
              <uni-icons :type="getFileIcon(file.extension || '')" size="32" color="#666"></uni-icons>
            </view>
            <view class="file-info">
              <text class="file-name">{{ file.name }}</text>
              <text class="file-size" v-if="file.size">{{ formatFileSize(file.size) }}</text>
              <text class="file-type">{{ file.extension?.toUpperCase() || 'FILE' }}</text>
            </view>
          </view>
          <view class="file-actions">
            <view class="delete-btn" @click="removeFile(index)">
              <uni-icons type="close" size="16" color="#fff"></uni-icons>
            </view>
          </view>
        </view>
        
        <view 
          class="add-btn" 
          v-if="fileList.length < maxFileCount"
          @click="chooseFile"
        >
          <uni-icons type="paperclip" size="24" color="#999"></uni-icons>
          <text class="add-text">添加文件</text>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { imagUrl } from '@/utils'
import { 
  previewFile as previewFileUtil
} from '@/utils/filePreview'

// 接口定义
interface ImageItem {
  tempPath?: string
  url?: string
  name?: string
  originalPath?: string
  isCompressed?: boolean
}

interface VideoItem {
  tempPath?: string
  url?: string
  name?: string
  duration?: number
  size?: number
  thumbnail?: string
}

interface FileItem {
  tempPath?: string
  url?: string
  name?: string
  type?: string
  size?: number
  extension?: string
  mimeType?: string
}

// Props
interface Props {
  // 图片相关
  enableImage?: boolean
  maxImageCount?: number
  imageList?: ImageItem[]
  
  // 视频相关
  enableVideo?: boolean
  maxVideoCount?: number
  videoList?: VideoItem[]
  
  // 文件相关
  enableFile?: boolean
  maxFileCount?: number
  fileList?: FileItem[]
  allowedFileTypes?: string[]
  
  // 压缩配置
  compressConfig?: {
    image: {
      quality: number
      maxWidth: number
      maxHeight: number
      maxSize: number
      minQuality: number
    }
    video: {
      maxDuration: number
      maxSize: number
      quality: string
    }
  }
  
  // 上传配置
  autoUpload?: boolean
  uploadApi?: (file: any) => Promise<any>
}

const props = withDefaults(defineProps<Props>(), {
  enableImage: true,
  maxImageCount: 5,
  imageList: () => [],
  
  enableVideo: true,
  maxVideoCount: 3,
  videoList: () => [],
  
  enableFile: false,
  maxFileCount: 5,
  fileList: () => [],
  allowedFileTypes: () => ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'mp3', 'wav', 'zip', 'rar'],
  
  compressConfig: () => ({
    image: {
      quality: 60,
      maxWidth: 1280,
      maxHeight: 720,
      maxSize: 200 * 1024, // 200KB
      minQuality: 20
    },
    video: {
      maxDuration: 60,
      maxSize: 10 * 1024 * 1024, // 10MB
      quality: 'medium'
    }
  }),
  
  autoUpload: true,
  uploadApi: undefined
})

// Emits
const emit = defineEmits<{
  'update:imageList': [images: ImageItem[]]
  'update:videoList': [videos: VideoItem[]]
  'update:fileList': [files: FileItem[]]
  'image-upload-success': [image: ImageItem, index: number]
  'image-upload-error': [error: any, index: number]
  'video-upload-success': [video: VideoItem, index: number]
  'video-upload-error': [error: any, index: number]
  'file-upload-success': [file: FileItem, index: number]
  'file-upload-error': [error: any, index: number]
  'upload-progress': [type: 'image' | 'video' | 'file', current: number, total: number]
}>()

// 响应式数据
const imageList = ref<ImageItem[]>([...props.imageList])
const videoList = ref<VideoItem[]>([...props.videoList])
const fileList = ref<FileItem[]>([...props.fileList])

// 监听props变化
watch(() => props.imageList, (newList) => {
  imageList.value = [...newList]
}, { deep: true })

watch(() => props.videoList, (newList) => {
  videoList.value = [...newList]
}, { deep: true })

watch(() => props.fileList, (newList) => {
  fileList.value = [...newList]
}, { deep: true })

// 压缩配置
const COMPRESS_CONFIG = computed(() => props.compressConfig)

// 获取文件信息
const getFileInfo = (filePath: string): Promise<any> => {
  return new Promise((resolve, reject) => {
    uni.getFileInfo({
      filePath: filePath,
      success: resolve,
      fail: reject
    })
  })
}

// 图片压缩函数 - 支持H5和APP
const compressImage = (src: string, quality: number = COMPRESS_CONFIG.value.image.quality): Promise<string> => {
  return new Promise((resolve, reject) => {
    // 检查是否在H5环境
    // @ts-ignore
    if (typeof window !== 'undefined' && window.uni && window.uni.compressImage) {
      // APP环境使用uni.compressImage
      uni.compressImage({
        src: src,
        quality: quality,
        success: (res) => {
          resolve(res.tempFilePath)
        },
        fail: (error) => {
          reject(error)
        }
      })
    } else {
      // H5环境使用Canvas压缩
      compressImageWithCanvas(src, quality).then(resolve).catch(reject)
    }
  })
}

// H5环境下的Canvas压缩函数
const compressImageWithCanvas = (src: string, quality: number): Promise<string> => {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.crossOrigin = 'anonymous'
    
    img.onload = () => {
      try {
        // 计算压缩后的尺寸
        let { width, height } = calculateCompressedSize(img.width, img.height)
        
        // 创建Canvas
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')
        
        if (!ctx) {
          reject(new Error('无法获取Canvas上下文'))
          return
        }
        
        canvas.width = width
        canvas.height = height
        
        // 绘制压缩后的图片
        ctx.drawImage(img, 0, 0, width, height)
        
        // 转换为Blob
        canvas.toBlob((blob) => {
          if (blob) {
            // 创建临时URL
            const compressedUrl = URL.createObjectURL(blob)
            resolve(compressedUrl)
          } else {
            reject(new Error('Canvas压缩失败'))
          }
        }, 'image/jpeg', quality / 100)
        
      } catch (error) {
        reject(error)
      }
    }
    
    img.onerror = () => {
      reject(new Error('图片加载失败'))
    }
    
    img.src = src
  })
}

// 计算压缩后的尺寸
const calculateCompressedSize = (originalWidth: number, originalHeight: number): { width: number, height: number } => {
  const maxWidth = COMPRESS_CONFIG.value.image.maxWidth
  const maxHeight = COMPRESS_CONFIG.value.image.maxHeight
  
  let width = originalWidth
  let height = originalHeight
  
  // 按比例缩放
  if (width > maxWidth || height > maxHeight) {
    const ratio = Math.min(maxWidth / width, maxHeight / height)
    width = Math.floor(width * ratio)
    height = Math.floor(height * ratio)
  }
  
  return { width, height }
}

// 智能图片压缩
const smartCompressImage = async (filePath: string): Promise<string> => {
  try {
    const fileInfo = await getFileInfo(filePath)
    const originalSize = fileInfo.size
    
    // 如果文件已经很小，直接返回
    if (originalSize <= COMPRESS_CONFIG.value.image.maxSize) {
      return filePath
    }
    
    // 根据文件大小计算压缩质量
    let quality = COMPRESS_CONFIG.value.image.quality
    if (originalSize > COMPRESS_CONFIG.value.image.maxSize * 10) {
      quality = 15
    } else if (originalSize > COMPRESS_CONFIG.value.image.maxSize * 5) {
      quality = 25
    } else if (originalSize > COMPRESS_CONFIG.value.image.maxSize * 3) {
      quality = 35
    } else if (originalSize > COMPRESS_CONFIG.value.image.maxSize * 2) {
      quality = 45
    } else if (originalSize > COMPRESS_CONFIG.value.image.maxSize) {
      quality = 55
    }
    
    // 执行压缩
    const compressedPath = await compressImage(filePath, quality)
    
    // 检查压缩后的文件大小
    const compressedInfo = await getFileInfo(compressedPath)
    
    // 如果还是太大，进一步压缩
    if (compressedInfo.size > COMPRESS_CONFIG.value.image.maxSize && quality > COMPRESS_CONFIG.value.image.minQuality) {
      const newQuality = Math.max(quality - 10, COMPRESS_CONFIG.value.image.minQuality)
      return await smartCompressImage(compressedPath)
    }
    
    return compressedPath
  } catch (error) {
    console.error('智能压缩失败:', error)
    throw error
  }
}

// 检查视频文件大小
const checkVideoSize = async (filePath: string): Promise<boolean> => {
  try {
    const fileInfo = await getFileInfo(filePath)
    return fileInfo.size <= COMPRESS_CONFIG.value.video.maxSize
  } catch (error) {
    console.error('获取视频文件信息失败:', error)
    return false
  }
}

// 选择图片
const chooseImage = () => {
  uni.chooseImage({
    count: props.maxImageCount - imageList.value.length,
    sizeType: ['original'],
    sourceType: ['album', 'camera'],
    success: async (res) => {
      const tempFilePaths = res.tempFilePaths as string[]
      
      showLoading('压缩图片中...')
      
      try {
        const compressedImages = []
        
        // 并行压缩所有图片
        const compressPromises = tempFilePaths.map(async (path, index) => {
          try {
            showLoading(`压缩图片中... (${index + 1}/${tempFilePaths.length})`)
            
            const compressedPath = await smartCompressImage(path)
            
            return {
              tempPath: compressedPath,
              name: path.split('/').pop() || 'image.jpg',
              originalPath: path,
              isCompressed: true
            }
          } catch (error) {
            console.error(`图片 ${path} 压缩失败:`, error)
            return {
              tempPath: path,
              name: path.split('/').pop() || 'image.jpg',
              isCompressed: false
            }
          }
        })
        
        const results = await Promise.all(compressPromises)
        compressedImages.push(...results)
        
        // 添加到列表
        imageList.value = [...imageList.value, ...compressedImages]
        emit('update:imageList', imageList.value)
        
        hideLoading()
        
        // 显示压缩结果统计
        const compressedCount = results.filter(r => r.isCompressed).length
        if (compressedCount > 0) {
          showToast({ 
            title: `已压缩 ${compressedCount} 张图片`, 
            icon: 'success',
            duration: 2000
          })
        }
        
        // 自动上传
        if (props.autoUpload && props.uploadApi) {
          await uploadImages(compressedImages)
        }
      } catch (error) {
        hideLoading()
        showToast({ title: '图片处理失败', icon: 'none' })
        console.error('图片处理失败:', error)
      }
    },
    fail: (error) => {
      console.error('选择图片失败:', error)
      showToast({ title: '选择图片失败', icon: 'none' })
    }
  })
}

// 选择视频
const chooseVideo = () => {
  uni.chooseVideo({
    sourceType: ['album', 'camera'],
    maxDuration: COMPRESS_CONFIG.value.video.maxDuration,
    camera: 'back',
    success: async (res) => {
      const tempFilePath = res.tempFilePath
      
      try {
        // 检查视频文件大小
        const isValidSize = await checkVideoSize(tempFilePath)
        
        if (!isValidSize) {
          const fileInfo = await getFileInfo(tempFilePath)
          const fileSizeMB = (fileInfo.size / 1024 / 1024).toFixed(1)
          
          uni.showModal({
            title: '视频文件过大',
            content: `视频文件大小为 ${fileSizeMB}MB，超过限制的 ${(COMPRESS_CONFIG.value.video.maxSize / 1024 / 1024).toFixed(1)}MB，请选择较小的视频文件。`,
            showCancel: false,
            confirmText: '知道了'
          })
          return
        }
        
        // 文件大小合适，添加到列表
        const newVideo = {
          tempPath: tempFilePath,
          name: tempFilePath.split('/').pop() || 'video.mp4',
          duration: res.duration,
          size: res.size
        }
        
        videoList.value = [...videoList.value, newVideo]
        emit('update:videoList', videoList.value)
        
        // 自动上传
        if (props.autoUpload && props.uploadApi) {
          await uploadVideos([newVideo])
        }
      } catch (error) {
        console.error('视频处理失败:', error)
        showToast({ title: '视频处理失败', icon: 'none' })
      }
    },
    fail: (error) => {
      console.error('选择视频失败:', error)
      showToast({ title: '选择视频失败', icon: 'none' })
    }
  })
}

// 选择文件
const chooseFile = () => {
  uni.chooseFile({
    count: props.maxFileCount - fileList.value.length,
    type: 'all',
    success: async (res) => {
      const tempFiles = res.tempFiles
      if (Array.isArray(tempFiles) && tempFiles.length > 0) {
        try {
          for (const file of tempFiles) {
            const fileInfo = file as any
            const fileName = fileInfo.name || ''
            const fileExtension = fileName.split('.').pop()?.toLowerCase() || ''
            
            // 检查文件类型是否被允许
            if (props.allowedFileTypes && props.allowedFileTypes.length > 0) {
              if (!props.allowedFileTypes.includes(fileExtension)) {
                showToast({ 
                  title: `不支持的文件类型: ${fileExtension}`, 
                  icon: 'none' 
                })
                continue
              }
            }
            
            // 确定文件类型
            let fileType = 'document'
            if (['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp'].includes(fileExtension)) {
              fileType = 'image'
            } else if (['mp4', 'mov', 'avi', 'wmv', 'flv'].includes(fileExtension)) {
              fileType = 'video'
            } else if (['mp3', 'wav', 'aac', 'ogg'].includes(fileExtension)) {
              fileType = 'audio'
            }
            
            // 创建文件项
            const fileItem: FileItem = {
              tempPath: fileInfo.path,
              name: fileName,
              type: fileType,
              size: fileInfo.size,
              extension: fileExtension,
              mimeType: fileInfo.type || ''
            }
            
            // 添加到文件列表
            fileList.value.push(fileItem)
            
            // 如果启用自动上传
            if (props.autoUpload && props.uploadApi) {
              await uploadFile(fileItem, fileList.value.length - 1)
            }
          }
          
          // 更新父组件
          emit('update:fileList', fileList.value)
          
        } catch (error) {
          console.error('文件处理失败:', error)
          showToast({ title: '文件处理失败', icon: 'none' })
        }
      }
    },
    fail: (error) => {
      console.error('选择文件失败:', error)
      if (error.errMsg && !error.errMsg.includes('cancel')) {
        showToast({ title: '选择文件失败', icon: 'none' })
      }
    }
  })
}

// 上传文件
const uploadFile = async (fileItem: FileItem, index: number) => {
  if (!props.uploadApi || !fileItem.tempPath) return
  
  try {
    const result = await props.uploadApi(fileItem.tempPath)
    
    if (result && result.resultCode === 1 && result.result && result.result.length > 0) {
      const uploadedFile = result.result[0]
      
      // 更新文件项
      fileItem.url = uploadedFile.filePath
      fileItem.tempPath = undefined // 清除临时路径
      
      // 触发成功事件
      emit('file-upload-success', fileItem, index)
      
      showToast({ title: '文件上传成功', icon: 'success' })
    } else {
      throw new Error('上传失败')
    }
  } catch (error) {
    console.error('文件上传失败:', error)
    emit('file-upload-error', error, index)
    showToast({ title: '文件上传失败', icon: 'none' })
    
    // 移除上传失败的文件
    fileList.value.splice(index, 1)
  }
}

// 预览文件
const previewFile = (index: number) => {
  const file = fileList.value[index]
  if (!file) return
  
  if (file.type === 'image' && file.url) {
    // 图片预览
    uni.previewImage({
      urls: [file.url],
      current: file.url
    })
  } else if (file.url) {
    // 使用公文预览方式预览其他文件
    const fileUrl = imagUrl(file.url)
    const fileName = file.name || '未知文件'
    const fileExtension = file.extension || file.url.split('.').pop() || ''
    
    // 统一使用 kkview 预览
    const fullFileName = fileExtension ? `${fileName}.${fileExtension}` : fileName
    previewFileUtil(fileUrl, fullFileName, fileExtension)
      .catch((error: any) => {
        uni.showToast({
          title: '预览失败',
          icon: 'error'
        })
      })
  } else {
    // 其他文件类型显示提示
    showToast({ 
      title: `预览 ${file.name} 功能待实现`, 
      icon: 'none' 
    })
  }
}

// 移除文件
const removeFile = (index: number) => {
  fileList.value.splice(index, 1)
  emit('update:fileList', fileList.value)
}

// 获取文件图标
const getFileIcon = (extension: string): string => {
  const iconMap: { [key: string]: string } = {
    // 文档
    'pdf': 'book',
    'doc': 'book',
    'docx': 'book',
    'txt': 'book',
    // 表格
    'xls': 'table',
    'xlsx': 'table',
    // 演示文稿
    'ppt': 'slideshow',
    'pptx': 'slideshow',
    // 音频
    'mp3': 'mic',
    'wav': 'mic',
    'aac': 'mic',
    'ogg': 'mic',
    // 压缩文件
    'zip': 'folder',
    'rar': 'folder',
    '7z': 'folder',
    // 其他
    'default': 'paperclip'
  }
  
  return iconMap[extension.toLowerCase()] || iconMap['default']
}

// 上传图片
const uploadImages = async (images: ImageItem[]) => {
  if (!props.uploadApi) return
  
  try {
    showLoading('上传图片中...')
    
    let successCount = 0
    let failCount = 0
    
    for (let i = 0; i < images.length; i++) {
      const image = images[i]
      if (image.tempPath) {
        try {
          showLoading(`上传图片中... (${i + 1}/${images.length})`)
          emit('upload-progress', 'image', i + 1, images.length)
          
          const uploadResult = await props.uploadApi(image.tempPath)
          
          if (uploadResult && uploadResult.resultCode === 1 && uploadResult.result && uploadResult.result.length > 0) {
            const serverPath = uploadResult.result[0].filePath
            
            // 更新图片对象
            const index = imageList.value.findIndex(img => img.tempPath === image.tempPath)
            if (index !== -1) {
              imageList.value[index].url = serverPath
              delete imageList.value[index].tempPath
              delete imageList.value[index].originalPath
            }
            
            emit('image-upload-success', imageList.value[index], index)
            successCount++
          } else {
            throw new Error('上传响应格式异常')
          }
        } catch (error) {
          console.error('图片上传失败:', error)
          emit('image-upload-error', error, i)
          
          const index = imageList.value.findIndex(img => img.tempPath === image.tempPath)
          if (index !== -1) {
            imageList.value.splice(index, 1)
          }
          
          failCount++
        }
      }
    }
    
    emit('update:imageList', imageList.value)
    hideLoading()
    
    if (failCount === 0) {
      showToast({ title: `成功上传 ${successCount} 张图片`, icon: 'success' })
    } else {
      showToast({ 
        title: `上传完成：成功 ${successCount} 张，失败 ${failCount} 张`, 
        icon: 'none',
        duration: 3000
      })
    }
  } catch (error) {
    hideLoading()
    console.error('批量上传图片失败:', error)
    showToast({ title: '图片上传失败，请重试', icon: 'none' })
  }
}

// 上传视频
const uploadVideos = async (videos: VideoItem[]) => {
  if (!props.uploadApi) return
  
  try {
    showLoading('上传视频中...')
    
    let successCount = 0
    let failCount = 0
    
    for (let i = 0; i < videos.length; i++) {
      const video = videos[i]
      if (video.tempPath) {
        try {
          showLoading(`上传视频中... (${i + 1}/${videos.length})`)
          emit('upload-progress', 'video', i + 1, videos.length)
          
          const uploadResult = await props.uploadApi(video.tempPath)
          
          if (uploadResult && uploadResult.resultCode === 1 && uploadResult.result && uploadResult.result.length > 0) {
            const serverPath = uploadResult.result[0].filePath
            
            // 更新视频对象
            const index = videoList.value.findIndex(v => v.tempPath === video.tempPath)
            if (index !== -1) {
              videoList.value[index].url = serverPath
              delete videoList.value[index].tempPath
            }
            
            emit('video-upload-success', videoList.value[index], index)
            successCount++
          } else {
            throw new Error('上传响应格式异常')
          }
        } catch (error) {
          console.error('视频上传失败:', error)
          emit('video-upload-error', error, i)
          
          const index = videoList.value.findIndex(v => v.tempPath === video.tempPath)
          if (index !== -1) {
            videoList.value.splice(index, 1)
          }
          
          failCount++
        }
      }
    }
    
    emit('update:videoList', videoList.value)
    hideLoading()
    
    if (failCount === 0) {
      showToast({ title: `成功上传 ${successCount} 个视频`, icon: 'success' })
    } else {
      showToast({ 
        title: `上传完成：成功 ${successCount} 个，失败 ${failCount} 个`, 
        icon: 'none',
        duration: 3000
      })
    }
  } catch (error) {
    hideLoading()
    console.error('批量上传视频失败:', error)
    showToast({ title: '视频上传失败，请重试', icon: 'none' })
  }
}

// 预览图片
const previewImage = (index: number) => {
  const urls = imageList.value.map(img => img.url || img.tempPath).filter(Boolean)
  uni.previewImage({
    urls: urls,
    current: index
  })
}

// 预览视频
const previewVideo = (index: number) => {
  const video = videoList.value[index]
  if (video.url || video.tempPath) {
    uni.previewVideo({
      sources: [{
        src: video.url || video.tempPath,
        type: 'mp4'
      }]
    })
  }
}

// 删除图片
const removeImage = (index: number) => {
  imageList.value.splice(index, 1)
  emit('update:imageList', imageList.value)
}

// 删除视频
const removeVideo = (index: number) => {
  videoList.value.splice(index, 1)
  emit('update:videoList', videoList.value)
}

// 格式化时长
const formatDuration = (seconds: number): string => {
  const mins = Math.floor(seconds / 60)
  const secs = Math.floor(seconds % 60)
  return `${mins}:${secs.toString().padStart(2, '0')}`
}

// 格式化文件大小
const formatFileSize = (bytes: number): string => {
  if (bytes < 1024) return bytes + 'B'
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + 'KB'
  return (bytes / 1024 / 1024).toFixed(1) + 'MB'
}

// 工具函数
const showLoading = (title: string) => {
  uni.showLoading({ title })
}

const hideLoading = () => {
  uni.hideLoading()
}

const showToast = (options: { title: string; icon?: string; duration?: number }) => {
  uni.showToast(options)
}

// 暴露方法给父组件
defineExpose({
  chooseImage,
  chooseVideo,
  chooseFile,
  uploadImages,
  uploadVideos,
  uploadFile,
  removeImage,
  removeVideo,
  removeFile
})
</script>

<style scoped>
.image-video-upload {
  width: 100%;
}

.upload-section {
  margin-bottom: 20rpx;
}

.section-title {
  display: flex;
  align-items: center;
  margin-bottom: 16rpx;
}

.title-text {
  font-size: 28rpx;
  font-weight: 500;
  color: #333;
}

.count-text {
  font-size: 24rpx;
  color: #999;
  margin-left: 8rpx;
}

.image-list, .video-list {
  display: flex;
  flex-wrap: wrap;
  gap: 16rpx;
}

.image-item, .video-item {
  position: relative;
  width: 160rpx;
  height: 160rpx;
  border-radius: 8rpx;
  overflow: hidden;
}

.image-preview {
  width: 100%;
  height: 100%;
}

.video-preview {
  position: relative;
  width: 100%;
  height: 100%;
}

.video-thumbnail {
  width: 100%;
  height: 100%;
}

.play-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, 0.6);
  border-radius: 50%;
  width: 48rpx;
  height: 48rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.video-duration {
  position: absolute;
  bottom: 4rpx;
  right: 4rpx;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-size: 20rpx;
  padding: 2rpx 6rpx;
  border-radius: 4rpx;
}

.image-actions, .video-actions {
  position: absolute;
  top: 4rpx;
  right: 4rpx;
}

.delete-btn {
  width: 32rpx;
  height: 32rpx;
  background: rgba(0, 0, 0, 0.6);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.image-status {
  position: absolute;
  bottom: 4rpx;
  left: 4rpx;
}

.compressed-tag {
  background: #4CAF50;
  color: #fff;
  font-size: 20rpx;
  padding: 2rpx 6rpx;
  border-radius: 4rpx;
}

.video-info {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.8));
  padding: 8rpx;
}

.video-name, .video-size {
  color: #fff;
  font-size: 20rpx;
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.video-size {
  margin-top: 2rpx;
  opacity: 0.8;
}

.add-btn {
  width: 160rpx;
  height: 160rpx;
  border: 2rpx dashed #ddd;
  border-radius: 8rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #fafafa;
}

.add-text {
  font-size: 24rpx;
  color: #999;
  margin-top: 8rpx;
}

/* 文件相关样式 */
.file-list {
  display: flex;
  flex-direction: column;
  gap: 12rpx;
}

.file-item {
  display: flex;
  align-items: center;
  background: #f8f9fa;
  border-radius: 8rpx;
  padding: 16rpx;
  border: 1rpx solid #e9ecef;
  position: relative;
}

.file-preview {
  display: flex;
  align-items: center;
  flex: 1;
  cursor: pointer;
}

.file-icon {
  width: 60rpx;
  height: 60rpx;
  background: white;
  border-radius: 8rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 16rpx;
  border: 1rpx solid #dee2e6;
}

.file-info {
  flex: 1;
  min-width: 0;
}

.file-name {
  font-size: 28rpx;
  color: #333;
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 4rpx;
}

.file-size {
  font-size: 24rpx;
  color: #999;
  display: block;
  margin-bottom: 2rpx;
}

.file-type {
  font-size: 20rpx;
  color: #666;
  display: block;
}

.file-actions {
  position: absolute;
  top: 8rpx;
  right: 8rpx;
}

.file-actions .delete-btn {
  width: 32rpx;
  height: 32rpx;
  background: rgba(255, 59, 48, 0.8);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
