<template>
  <div class="video-upload-container">
    <!-- 步骤指示器 -->
    <div class="step-indicator">
      <div class="step" :class="{ active: currentStep === 1, completed: currentStep > 1 }">
        <div class="step-circle">
          <span v-if="currentStep <= 1" class="step-number" style="color: #fff;">1</span>
          <el-icon v-else class="step-check"><Check /></el-icon>
        </div>
        <span class="step-text">选择文件</span>
      </div>
      <div class="step-line" :class="{ completed: currentStep > 1 }"></div>
      <div class="step" :class="{ active: currentStep === 2, completed: currentStep > 2 }">
        <div class="step-circle">
          <span v-if="currentStep <= 2" class="step-number" style="color: #fff;">2</span>
          <el-icon v-else class="step-check"><Check /></el-icon>
        </div>
        <span class="step-text">预览文件</span>
      </div>
      <div class="step-line" :class="{ completed: currentStep > 2 }"></div>
      <div class="step" :class="{ active: currentStep === 3, completed: currentStep > 3 }">
        <div class="step-circle">
          <span v-if="currentStep <= 3" class="step-number" style="color: #fff;">3</span>
          <el-icon v-else class="step-check"><Check /></el-icon>
        </div>
        <span class="step-text">填写信息提交</span>
      </div>
    </div>

    <!-- 第一步：选择文件 -->
    <div v-if="currentStep === 1" class="step-content">
      <div class="upload-header">
        <h3>选择视频文件</h3>
        <p>支持MP4、AVI、MOV等格式，最大支持1.5GB</p>
      </div>

      <div class="file-upload-area" @click="triggerFileSelect" @drop="handleDrop" @dragover.prevent>
        <el-icon class="upload-icon"><Upload /></el-icon>
        <p class="upload-text">点击选择文件或拖拽文件到此处</p>
        <p class="upload-hint">支持 MP4、AVI、MOV 等格式</p>
        <input
          ref="fileInput"
          type="file"
          accept="video/*"
          @change="handleFileSelect"
          style="display: none"
        />
      </div>

      <div v-if="selectedFile" class="file-preview">
        <div class="file-info">
          <el-icon class="file-icon"><VideoPlay /></el-icon>
          <div class="file-details">
            <h4>{{ selectedFile.name }}</h4>
            <p>{{ formatFileSize(selectedFile.size) }} • {{ selectedFile.type }}</p>
          </div>
          <el-button @click="clearFile" type="danger" circle size="small">
            <el-icon><Delete /></el-icon>
          </el-button>
        </div>
        <div class="step-action-center">
          <el-button @click="nextStep" type="primary" size="large" class="next-btn" style="background: #0F172A; border-color: #0F172A;">
            下一步 <el-icon><ArrowRight /></el-icon>
          </el-button>
        </div>
      </div>
    </div>

    <!-- 第二步：预览文件 -->
    <div v-if="currentStep === 2" class="step-content">
      <div class="upload-header">
        <h3>预览视频文件</h3>
        <p style="color: #94A3B8;">确认选择的视频文件是否正确</p>
      </div>



      <!-- 视频预览 -->
      <div class="video-preview-section">
        <div class="video-container">
          <video
            ref="videoPlayer"
            :src="videoPreviewUrl"
            controls
            preload="metadata"
            class="video-player"
            @loadedmetadata="onVideoLoaded"
            @error="onVideoError"
          >
            您的浏览器不支持视频播放
          </video>
        </div>
        
        <div class="video-info">
          <div class="info-item">
            <el-icon><Clock /></el-icon>
            <span>时长: {{ videoDuration }}</span>
          </div>
          <div class="info-item">
            <el-icon><Monitor /></el-icon>
            <span>分辨率: {{ videoResolution }}</span>
          </div>
          <div class="info-item">
            <el-icon><Files /></el-icon>
            <span>格式: {{ selectedFile?.type || '未知' }}</span>
          </div>
        </div>
      </div>

      <div class="step-actions-row">
        <el-button @click="prevStep" :icon="ArrowLeft" class="step-btn" style="background: white; border-color: #d9d9d9; color: #000;">上一步</el-button>
        <el-button @click="nextStep" type="primary" :icon="ArrowRight" class="step-btn" style="background: #0F172A; border-color: #0F172A;">
          下一步 <el-icon><ArrowRight /></el-icon>
        </el-button>
      </div>
    </div>

    <!-- 第三步：填写信息提交 -->
    <div v-if="currentStep === 3" class="step-content">
      <div class="upload-header">
        <h3>填写视频信息</h3>
        <p>完善视频信息后开始上传</p>
      </div>

      <!-- 文件信息展示 -->
      <div class="file-summary">
        
        <el-button @click="prevStep" :icon="ArrowLeft" size="small">返回</el-button>
      </div>

      <!-- 表单信息 -->
      <div class="form-section">
        <div class="form-row">
          <div class="form-group">
            <label>视频标题 *</label>
            <el-input
              v-model="formData.title"
              placeholder="请输入视频标题"
              maxlength="128"
              show-word-limit
              required
            />
          </div>
          <div class="form-group">
            <label>分类 *</label>
            <el-select v-model="formData.cateId" placeholder="请选择分类" style="width: 100%" required>
              <el-option 
                v-for="category in courseCategories" 
                :key="category.id" 
                :label="category.name" 
                :value="category.name" 
              />
            </el-select>
          </div>
        </div>


        <div class="form-row">
          <div class="form-group">
            <label>是否免费 *</label>
            <el-select v-model="formData.isFree" placeholder="请选择" style="width: 100%" required>
              <el-option label="免费" :value="true" />
              <el-option label="付费" :value="false" />
            </el-select>
          </div>
        </div>


        <div class="form-group">
          <label>封面图片 *</label>
          <div class="cover-upload-area">
            <div v-if="!coverFile" class="cover-upload-placeholder" @click="triggerCoverSelect">
              <el-icon class="cover-upload-icon"><Picture /></el-icon>
              <p>点击上传封面图片</p>
              <p class="cover-hint">支持 JPG、PNG 格式，建议尺寸 1280×720</p>
            </div>
            <div v-else class="cover-preview">
              <img :src="coverPreviewUrl" alt="封面预览" class="cover-image" />
              <div class="cover-actions">
                <el-button @click="triggerCoverSelect" size="small" :icon="Edit">更换</el-button>
                <el-button @click="clearCover" size="small" type="danger" :icon="Delete">删除</el-button>
              </div>
            </div>
            <input
              ref="coverInput"
              type="file"
              accept="image/*"
              @change="handleCoverSelect"
              style="display: none"
            />
          </div>
        </div>

        <div class="form-group">
          <label>视频描述 *</label>
          <div class="editor-container">
            <QuillEditor
              v-model:content="formData.description"
              content-type="html"
              :options="editorOptions"
              style="height: 300px;"
              @update:content="handleContentUpdate"
            />
          </div>
        </div>

      </div>

      <!-- 上传操作 -->
      <div class="upload-actions">
        <el-button
          @click="startUpload"
          :disabled="!canUpload || isUploading"
          type="primary"
          size="large"
          :icon="Upload"
        >
          <span v-if="!isUploading">开始上传</span>
          <span v-else>上传中...</span>
        </el-button>
        
      </div>

      <!-- 上传进度 -->
      <div v-if="isUploading" class="upload-progress">
        <div class="progress-header">
          <h4><el-icon><Upload /></el-icon> 正在上传视频</h4>
          <div class="upload-status">{{ uploadStatus }}</div>
        </div>
        
        <div class="progress-info">
          <div class="progress-main">
            <span class="progress-text">{{ uploadProgress }}%</span>
            <span class="progress-speed">{{ uploadSpeed }}</span>
          </div>
          <div class="progress-time">
            <span>已用时: {{ formatTime(uploadTimeElapsed) }}</span>
            <span v-if="uploadTimeRemaining > 0">预计剩余: {{ formatTime(uploadTimeRemaining) }}</span>
          </div>
        </div>
        

        
        <el-progress 
          :percentage="uploadProgress" 
          :stroke-width="8"
          :show-text="false"
          :color="getProgressColor(uploadProgress)"
          class="progress-bar"
        />
        
        <div class="progress-details">
          <div class="file-info">
            <span>{{ formatFileSize(uploadedBytes || 0) }} / {{ formatFileSize(selectedFile?.size || 0) }}</span>
            <span class="file-name">{{ selectedFile?.name }}</span>
          </div>
          
        </div>
      </div>

      <!-- 上传结果 -->
      <div v-if="uploadResult" class="upload-result">
        <div v-if="uploadResult.success" class="success-message">
          <div class="success-content">
            <el-icon class="success-icon"><CircleCheck /></el-icon>
            <h4>上传成功！</h4>
            <p>视频已成功提交审核</p>
            <el-button @click="resetUpload" type="primary" :icon="Refresh" size="large">上传新视频</el-button>
          </div>
        </div>
        <div v-else class="error-message">
          <div class="error-content">
            <el-icon class="error-icon"><CircleClose /></el-icon>
            <h4>上传失败</h4>
            <p>{{ uploadResult.message }}</p>
            <el-button @click="retryUpload" type="primary" :icon="Refresh" size="large">重试</el-button>
          </div>
        </div>
      </div>
    </div>

    <!-- 全屏上传遮罩层：参考课程组件 -->
    <div v-if="isUploading" class="upload-overlay">
      <div class="overlay-content">
  
        <h3>正在上传视频，请稍候</h3>
        <p>正在处理并上传您的视频文件，请不要关闭或离开此页面。</p>
        <div class="overlay-progress">
          <el-progress :percentage="uploadProgress" :stroke-width="10" :show-text="true" :color="getProgressColor(uploadProgress)" />
        </div>
        <div class="overlay-stats">
          <span>进度：{{ uploadProgress }}%</span>
          <span v-if="uploadStatus"> ｜ {{ uploadStatus }}</span>
        </div>
      </div>
    </div>

    <!-- 错误提示 -->
    <div v-if="errorMessage" class="error-alert">
      <el-alert
        :title="errorMessage"
        type="error"
        :closable="true"
        @close="clearError"
        show-icon
      />
    </div>
  </div>
</template>

<script>
import { ref, reactive, computed, onMounted, onUnmounted, onBeforeUnmount, watch } from 'vue'
import { useUserStore } from '@/store/user'
import { useRouter } from 'vue-router'
import { getCurrentUser, getUserCourseCategories } from '@/api/user'
import { createUploadAuth, refreshUploadAuth } from '@/api/vod'
import { submitCourseCollectionReview } from '@/api/review'
import { uploadFileToOss, getPostSignature } from '@/api/files'
import { ElMessage } from 'element-plus'
import * as MP4Box from 'mp4box'
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
import {
  Document,
  VideoPlay,
  Edit,
  Upload,
  ArrowRight,
  ArrowLeft,
  Clock,
  Monitor,
  Files,
  CircleCheck,
  CircleClose,
  Refresh,
  Picture,
  Delete,
  Check
} from '@element-plus/icons-vue'

export default {
  name: 'VideoUploadComponent',
  components: {
    Document,
    VideoPlay,
    Edit,
    Upload,
    ArrowRight,
    ArrowLeft,
    Clock,
    Monitor,
    Files,
    CircleCheck,
    CircleClose,
    Refresh,
    Picture,
    Delete,
    Check,
    QuillEditor
  },
  setup() {
    // 路由和用户store
    const router = useRouter()
    const userStore = useUserStore()
    
    // 获取用户信息
    const userInfo = computed(() => userStore.getUserInfo)
    
    // 更新用户信息的函数
    const updateUserInfo = async () => {
      try {
  
        const response = await getCurrentUser()

        
        if (response.code === 200) {
    
          userStore.updateUserInfo(response.data)

        } else {
          console.error('VideoUploadComponent: 获取用户信息失败:', response.message)
        }
      } catch (error) {
        console.error('VideoUploadComponent: 更新用户信息失败:', error)
      }
    }
    
    // 获取用户ID的函数
    const getUserId = () => {

      
      if (!userInfo.value) {
       
        return ''
      }
      
      const userId = userInfo.value.id || ''
      
      return userId
    }
    
    // 步骤控制
    const currentStep = ref(1)
    
    // 文件相关
    const fileInput = ref(null)
    const selectedFile = ref(null)
    const videoPlayer = ref(null)
    const videoPreviewUrl = ref('')
    const videoDuration = ref('00:00')
    const videoResolution = ref('未知')
    
    // 封面图片相关
    const coverInput = ref(null)
    const coverFile = ref(null)
    const coverPreviewUrl = ref('')
    
    
    // 分类数据
    const courseCategories = ref([])
    
    // 上传状态
    const isUploading = ref(false)
    const uploadProgress = ref(0)
    const uploadedBytes = ref(0)
    const uploadSpeed = ref('0 KB/s')
    const uploadResult = ref(null)
    const errorMessage = ref('')
    const uploadStatus = ref('')
    const uploadStartTime = ref(0)
    const lastUploadedBytes = ref(0)
    const uploadTimeElapsed = ref(0)
    const uploadTimeRemaining = ref(0)

    // 表单数据
    const formData = reactive({
      title: '',
      description: '',
      cateId: '',
      isFree: true,
    })

    // Quill富文本编辑器配置
    const editorOptions = {
      theme: 'snow',
      placeholder: '请输入视频描述...',
      modules: {
        toolbar: [
          [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
          ['bold', 'italic', 'underline', 'strike'],
          [{ 'color': [] }, { 'background': [] }],
          [{ 'font': [] }],
          [{ 'align': [] }],
          [{ 'list': 'ordered'}, { 'list': 'bullet' }],
          ['link', 'image'],
          ['clean']
        ]
      }
    }

    // 处理编辑器内容更新
    const handleContentUpdate = (content) => {
      formData.description = content
    }

    // 阿里云上传器实例
    let uploader = null
    
    // 处理富文本中的base64图片上传到OSS
    const processDescriptionImages = async () => {
      if (!formData.description) return formData.description
      
      const base64Regex = /<img[^>]+src="data:image\/([^;]+);base64,([^"]+)"[^>]*>/g
      let processedDescription = formData.description
      const uploadPromises = []
      
      let match
      while ((match = base64Regex.exec(formData.description)) !== null) {
        const [fullMatch, imageType, base64Data] = match
        
        // 将base64转换为File对象
        const byteCharacters = atob(base64Data)
        const byteNumbers = new Array(byteCharacters.length)
        for (let i = 0; i < byteCharacters.length; i++) {
          byteNumbers[i] = byteCharacters.charCodeAt(i)
        }
        const byteArray = new Uint8Array(byteNumbers)
        const blob = new Blob([byteArray], { type: `image/${imageType}` })
        const file = new File([blob], `description_image_${Date.now()}.${imageType}`, { type: `image/${imageType}` })
        
        // 创建上传Promise
        const uploadPromise = uploadImageToOSS(file).then(ossUrl => {
          // 替换原来的base64图片为OSS链接
          processedDescription = processedDescription.replace(fullMatch, fullMatch.replace(`data:image/${imageType};base64,${base64Data}`, ossUrl))
        })
        
        uploadPromises.push(uploadPromise)
      }
      
      // 等待所有图片上传完成
      await Promise.all(uploadPromises)
      return processedDescription
    }
    
    // 上传图片到OSS
    const uploadImageToOSS = async (file) => {
      try {
        const result = await uploadFileToOss(file, userInfo.value?.id)
        return result.url
      } catch (error) {
        console.error('图片上传到OSS失败:', error)
        throw error
      }
    }

    // 计算属性
    const canUpload = computed(() => {
      return selectedFile.value && 
             formData.title.trim() && 
             formData.cateId &&
             formData.isFree !== null &&
             coverFile.value &&
             formData.description.trim() &&
             !isUploading.value
    })

    // 文件选择
    const triggerFileSelect = () => {
      fileInput.value?.click()
    }

    const handleFileSelect = async (event) => {
      const file = event.target.files[0]
      if (!file) return

      if (!file.type.startsWith('video/')) {
        ElMessage.error('请选择有效的视频文件')
        return
      }

      if (file.size > 1.5 * 1024 * 1024 * 1024) {
        ElMessage.error('文件大小不能超过1.5GB')
        return
      }

      // 检测视频编码
      const isH264 = await checkVideoCodec(file)
      if (!isH264) {
        ElMessage.error('当前视频文件编码不是H.264，在部分浏览器上可能出现黑屏问题。请重新导出视频并设置编码为H.264。')
        return
      }

      selectedFile.value = file
      videoPreviewUrl.value = URL.createObjectURL(file)
      clearError()
      clearUploadResult()
      
      // 自动进入预览步骤
      nextStep()
    }

    const handleDrop = async (event) => {
      event.preventDefault()
      const files = event.dataTransfer.files
      if (files.length > 0) {
        const file = files[0]
        if (file.type.startsWith('video/')) {
          // 检测视频编码
          const isH264 = await checkVideoCodec(file)
          if (!isH264) {
            ElMessage.error('当前视频文件编码不是H.264，在部分浏览器上可能出现黑屏问题。请重新导出视频并设置编码为H.264。')
            return
          }
          
          selectedFile.value = file
          videoPreviewUrl.value = URL.createObjectURL(file)
          clearError()
          clearUploadResult()
          
          // 自动进入预览步骤
          nextStep()
        } else {
          ElMessage.error('请选择有效的视频文件')
        }
      }
    }

    const clearFile = () => {
      selectedFile.value = null
      videoPreviewUrl.value = ''
      videoDuration.value = '00:00'
      videoResolution.value = '未知'
      if (fileInput.value) {
        fileInput.value.value = ''
      }
      // 重置到第一步
      currentStep.value = 1
    }

    // 封面图片处理
    const triggerCoverSelect = () => {
      coverInput.value?.click()
    }

    const handleCoverSelect = (event) => {
      const file = event.target.files[0]
      if (!file) return

      if (!file.type.startsWith('image/')) {
        ElMessage.error('请选择有效的图片文件')
        return
      }

      if (file.size > 5 * 1024 * 1024) {
        ElMessage.error('图片文件大小不能超过5MB')
        return
      }

      coverFile.value = file
      coverPreviewUrl.value = URL.createObjectURL(file)
    }

    const clearCover = () => {
      coverFile.value = null
      if (coverPreviewUrl.value) {
        URL.revokeObjectURL(coverPreviewUrl.value)
        coverPreviewUrl.value = ''
      }
      if (coverInput.value) {
        coverInput.value.value = ''
      }
    }


    // 视频预览相关
    const onVideoLoaded = () => {
      if (videoPlayer.value) {
        const video = videoPlayer.value
        // 计算时长
        const duration = Math.floor(video.duration)
        const minutes = Math.floor(duration / 60)
        const seconds = duration % 60
        videoDuration.value = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
        
        // 获取分辨率
        videoResolution.value = `${video.videoWidth} × ${video.videoHeight}`
      }
    }

    const onVideoError = () => {
      ElMessage.error('视频文件加载失败，请检查文件格式')
    }

    // 步骤控制
    const nextStep = () => {
      if (currentStep.value === 1 && selectedFile.value) {
        currentStep.value = 2
      } else if (currentStep.value === 2) {
        currentStep.value = 3
      }
    }

    const prevStep = () => {
      if (currentStep.value > 1) {
        currentStep.value--
      }
    }

    const clearUploadResult = () => {
      uploadResult.value = null
      uploadProgress.value = 0
      uploadedBytes.value = 0
      uploadSpeed.value = '0 B/s'
      uploadStatus.value = ''
      uploadTimeElapsed.value = 0
      uploadTimeRemaining.value = 0
      lastUploadedBytes.value = 0
    }

    const clearError = () => {
      errorMessage.value = ''
    }

    const resetUpload = () => {
      clearUploadResult()
      clearError()
      isUploading.value = false
      uploadPaused.value = false
      
      // 重置表单数据
      formData.description = ''
      
      // 重置到第一步
      currentStep.value = 1
    }

    // 检测视频编码是否为H.264
    const checkVideoCodec = (file) => {
      return new Promise((resolve) => {
        try {
          const mp4boxFile = MP4Box.createFile()
          const reader = new FileReader()

          reader.onload = (e) => {
            try {
              const arrayBuffer = e.target.result
              arrayBuffer.fileStart = 0
              mp4boxFile.appendBuffer(arrayBuffer)
              mp4boxFile.flush()
            } catch (error) {
              console.error('视频文件解析失败:', error)
              // 如果解析失败，默认允许上传（避免阻止正常文件）
              resolve(true)
            }
          }

          mp4boxFile.onReady = (info) => {
            try {
              console.log('视频文件信息:', info)
              const videoTrack = info.tracks.find(track => track.type === 'video')
              if (videoTrack) {
                console.log('视频编码信息:', videoTrack.codec)
                // H.264编码通常以'avc1'或'avc3'开头
                const isH264 = videoTrack.codec.startsWith('avc1') || videoTrack.codec.startsWith('avc3')
                resolve(isH264)
              } else {
                console.log('未找到视频轨道')
                // 如果没有找到视频轨道，默认允许上传
                resolve(true)
              }
            } catch (error) {
              console.error('解析视频轨道信息失败:', error)
              resolve(true)
            }
          }

          mp4boxFile.onError = (error) => {
            console.error('mp4box解析出错:', error)
            // 解析失败时默认允许上传
            resolve(true)
          }

          reader.readAsArrayBuffer(file)
        } catch (error) {
          console.error('checkVideoCodec函数执行失败:', error)
          // 如果整个检测过程出错，默认允许上传
          resolve(true)
        }
      })
    }

    // 工具方法
    const formatFileSize = (bytes) => {
      // 处理无效输入
      if (!bytes || bytes === 0 || isNaN(bytes) || !isFinite(bytes)) {
        return '0 B'
      }
      
      // 确保是数字类型
      const numBytes = Number(bytes)
      if (isNaN(numBytes) || !isFinite(numBytes)) {
        return '0 B'
      }
      
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(numBytes) / Math.log(k))
      
      // 防止数组越界
      if (i < 0 || i >= sizes.length) {
        return '0 B'
      }
      
      return parseFloat((numBytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    }


    // 上传相关 - 按照阿里云官方文档实现
    const startUpload = async () => {
      if (!canUpload.value) return

      try {
        clearError()
        clearUploadResult()
        isUploading.value = true
        uploadProgress.value = 0
        uploadedBytes.value = 0
        uploadSpeed.value = '0 B/s'
        uploadStatus.value = '准备上传...'
        uploadStartTime.value = Date.now()
        lastUploadedBytes.value = 0
        uploadTimeElapsed.value = 0
        uploadTimeRemaining.value = 0

        // 先处理富文本中的base64图片，上传到OSS并替换链接
        uploadStatus.value = '正在处理富文本中的图片...'
        const processedDescription = await processDescriptionImages()
        formData.description = processedDescription

        // 检查阿里云SDK状态
        if (typeof window.AliyunUpload === 'undefined') {
          throw new Error('阿里云上传SDK未加载，请刷新页面重试')
        }

        uploadStatus.value = '正在初始化上传...'
        // 初始化阿里云上传器
        await initAliyunUploader()
        
        // 添加文件到上传器 - 按照官方文档，最后一个参数是userData
        uploader.addFile(selectedFile.value, null, null, null, null)
        
        // 开始上传
        uploader.startUpload()
        
      } catch (error) {
        console.error('上传失败:', error)
        errorMessage.value = error.message || '上传失败，请重试'
        isUploading.value = false
        ElMessage.error(errorMessage.value)
      }
    }

    // 上传封面图片到COS
    const uploadCoverImage = async (file) => {
      try {
        // 使用POST签名方式上传
        const postSignatureResult = await getPostSignature({
          fileName: file.name,
          userId: getUserId()
        })

        if (postSignatureResult.code !== 200) {
          throw new Error(postSignatureResult.message || '获取上传签名失败')
        }

        const signatureData = postSignatureResult.data

        // 创建FormData
        const formData = new FormData()
        
        // 使用后端返回的dir生成文件key
        const fileKey = signatureData.dir + Date.now() + '_' + file.name
        
        // COS POST 表单上传必需字段
        formData.append('key', fileKey)
        formData.append('policy', signatureData.policy)
        formData.append('q-sign-algorithm', signatureData['q-sign-algorithm'])
        formData.append('q-ak', signatureData['q-ak'])
        formData.append('q-key-time', signatureData['q-key-time'])
        formData.append('q-signature', signatureData['q-signature'])
        formData.append('file', file)
        
        // 上传到COS
        const uploadResponse = await fetch(signatureData.host, {
          method: 'POST',
          body: formData
        })
        
        if (uploadResponse.ok) {
          const responseText = await uploadResponse.text()
          console.log('封面上传成功！响应内容:', responseText)
          
          // 上传成功，使用后端返回的host构建文件访问地址
          const fileUrl = `${signatureData.host}/${fileKey}`
          
          return {
            url: fileUrl,
            success: true
          }
        } else {
          const errorText = await uploadResponse.text()
          console.error('封面上传失败，状态码:', uploadResponse.status)
          console.error('响应文本:', errorText)
          throw new Error(`封面上传失败: HTTP ${uploadResponse.status} - ${errorText}`)
        }
      } catch (error) {
        console.error('封面上传失败:', error)
        throw new Error(`封面上传失败: ${error.message}`)
      }
    }

    // 初始化阿里云上传器 - 按照官方文档实现
    const initAliyunUploader = async () => {
      return new Promise((resolve, reject) => {
        try {
          // 检查阿里云SDK是否正确加载
          if (typeof window.AliyunUpload === 'undefined') {
            throw new Error('阿里云上传SDK未加载，请刷新页面重试')
          }

          // 检查AliyunUpload.Vod是否是一个构造函数
          if (typeof window.AliyunUpload.Vod !== 'function') {
            console.error('AliyunUpload.Vod不是构造函数:', typeof window.AliyunUpload.Vod, window.AliyunUpload.Vod)
            throw new Error('阿里云上传SDK初始化失败，请刷新页面重试')
          }

          // 创建上传器实例 - 按照官方文档配置
          uploader = new window.AliyunUpload.Vod({
            // userID，用于标识上传者的身份，必填
            userId: getUserId(),
            // 上传到视频点播的地域，默认值为'cn-shanghai'
            region: "cn-shanghai",
            // 分片大小默认1 MB，不能小于100 KB（100*1024）
            partSize: 1024 * 1024,
            // 并行上传分片个数，默认5
            parallel: 5,
            // 网络原因失败时，重新上传次数，默认为3
            retryCount: 3,
            // 网络原因失败时，重新上传间隔时间，默认为2秒
            retryDuration: 2,
            // 开始上传 - 按照官方文档实现
            onUploadstarted: async (uploadInfo) => {
              updateUploadStatus('正在初始化上传...')
              
              try {
                // 如果是断点续传，uploadInfo.videoId会有值
                if (!uploadInfo.videoId) {
                  // 新上传，调用创建上传凭证接口
                  const authResult = await createUploadAuth({
                    userId: getUserId(),
                    title: formData.title,
                    description: formData.description,
                    cateId: formData.cateId,
                    coverUrl: coverFile.value ? await uploadCoverImage(coverFile.value).then(result => result.url) : '',
                    isFree: formData.isFree,
                    fileName: selectedFile.value.name,
                    fileSize: selectedFile.value.size
                  })
                  
                  // 由于createUploadAuth返回的是res.data，所以authResult已经是data部分
                  // 不需要检查code字段，直接验证必要字段
                  const { uploadAuth, uploadAddress, videoId } = authResult
                  
                  // 验证必要字段是否存在
                  if (!uploadAuth || !uploadAddress || !videoId) {
                    throw new Error('上传凭证缺少必要字段')
                  }
                  
                  // 设置上传地址和凭证
                  uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
                  updateUploadStatus('开始上传文件...')
                } else {
                  // 断点续传，调用刷新上传凭证接口
                  const refreshResult = await refreshUploadAuth({
                    videoId: uploadInfo.videoId
                  })
                  
                  // 由于refreshUploadAuth返回的是res.data，所以refreshResult已经是data部分
                  const { uploadAuth, uploadAddress, videoId } = refreshResult
                  
                  // 验证必要字段是否存在
                  if (!uploadAuth || !uploadAddress || !videoId) {
                    throw new Error('刷新上传凭证缺少必要字段')
                  }
                  
                  // 设置新的上传凭证继续上传
                  uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
                  updateUploadStatus('继续上传文件...')
                }
              } catch (error) {
                console.error('获取上传凭证失败:', error)
                errorMessage.value = error.message || '获取上传凭证失败'
                isUploading.value = false
                ElMessage.error(errorMessage.value)
              }
            },
            // 文件上传成功 - 按照官方文档实现
            onUploadSucceed: async (uploadInfo) => {
              console.log('onUploadSucceed:', uploadInfo.file.name)
              updateUploadStatus('文件上传完成，正在提交审核...')
              
              try {
                updateUploadStatus('正在提交审核...')
                
                // 提交审核 - 按照要求的课程集合格式
                const reviewData = {
                  courseCollectionId: `course-collection-${Date.now()}-${Math.random().toString(36).substring(2, 15)}`, // 前端指定的课程集合ID+随机数
                  courseTitle: formData.title, // 课程标题
                  courseCategory: formData.category, 
                  courseDescription: formData.description || '', // 课程描述
                  courseIsFree: formData.isFree ? 0 : 1, // 是否免费：0收费 / 1免费
                  // 访问级别：0游客(所有人)/1普通/2VIP/3SVIP。免费=所有人(0)，收费=VIP(2)
                  courseLevel: formData.isFree ? 0 : 2,
                  chapters: [
                    {
                      chapterTitle: formData.title, // 章节标题
                      chapterDescription: formData.description || '', // 章节描述
                      videoId: uploadInfo.videoId, // 关联的视频ID
                      videoTitle: formData.title, // 视频标题
                      videoDescription: formData.description || '', // 视频描述
                      videoCoverUrl: coverFile.value ? await uploadCoverImage(coverFile.value).then(result => result.url) : '', // 视频封面URL
                      videoCategory: formData.cateId || '', // 视频分类
                      videoDuration: Math.floor(videoPlayer.value?.duration || 0), // 视频时长（秒）
                      orderNum: 1 // 章节排序
                    }
                  ]
                }

                const reviewResult = await submitCourseCollectionReview(reviewData)
                console.log('审核提交响应:', reviewResult)

                // 检查响应是否成功 - 根据实际返回的数据结构判断
                if (reviewResult && (reviewResult.courseCollectionId || reviewResult.courseId)) {
                  uploadResult.value = {
                    success: true,
                    videoId: uploadInfo.videoId,
                    courseCollectionId: reviewResult.courseCollectionId || reviewData.courseCollectionId,
                    courseId: reviewResult.courseId,
                    auditStatus: reviewResult.auditStatus || 0,
                    message: reviewResult.message || '课程集合提交审核成功'
                  }
                  updateUploadStatus('上传成功！已提交审核')
                  ElMessage.success('课程集合提交审核成功')
                  
                  // 提交成功后跳转到作品管理页面
                  setTimeout(() => {
                    router.push('/personal-center/publish?tab=manage')
                  }, 2000) // 延迟2秒跳转，让用户看到成功消息
                } else {
                  throw new Error(reviewResult?.message || '提交审核失败')
                }
              } catch (error) {
                console.error('提交审核失败:', error)
                errorMessage.value = error.message || '提交审核失败，请重试'
                updateUploadStatus('提交审核失败')
                ElMessage.error(errorMessage.value)
              } finally {
                isUploading.value = false
                uploadProgress.value = 100
                uploadedBytes.value = selectedFile.value.size
                // 重置时间相关状态
                uploadTimeElapsed.value = Math.floor((Date.now() - uploadStartTime.value) / 1000)
                uploadTimeRemaining.value = 0
                // 上传完成后清理选中文件与预览
                clearFile()
              }
            },
            // 文件上传失败 - 按照官方文档实现
            onUploadFailed: (uploadInfo, code, message) => {
              console.error('onUploadFailed:', uploadInfo.file.name, 'code:', code, 'message:', message)
              errorMessage.value = `上传失败: ${message}`
              updateUploadStatus('上传失败')
              isUploading.value = false
              ElMessage.error(errorMessage.value)
            },
            // 文件上传进度 - 按照官方文档实现
            onUploadProgress: (uploadInfo, totalSize, progress) => {
              // 根据官方文档，progress 是百分比（0-1之间的小数），不是字节数
              let progressPercent
              let uploadedBytesValue
              
              if (typeof progress === 'number' && progress >= 0 && progress <= 1) {
                // progress 是百分比（0-1）
                progressPercent = Math.round(progress * 100)
                uploadedBytesValue = Math.round(progress * totalSize)
              } else if (typeof progress === 'number' && progress > 1) {
                // progress 可能是字节数（兼容性处理）
                progressPercent = Math.round((progress / totalSize) * 100)
                uploadedBytesValue = progress
              } else {
                // 未知类型，使用默认值
                progressPercent = 0
                uploadedBytesValue = 0
              }
              
              uploadProgress.value = progressPercent
              uploadedBytes.value = uploadedBytesValue
              
              // 更新上传速度
              updateUploadSpeed(uploadedBytesValue)
              
              // 根据进度更新状态描述
              if (progressPercent < 10) {
                updateUploadStatus('正在准备上传...')
              } else if (progressPercent < 30) {
                updateUploadStatus('正在上传文件开头部分...')
              } else if (progressPercent < 70) {
                updateUploadStatus('正在上传文件主体部分...')
              } else if (progressPercent < 90) {
                updateUploadStatus('正在上传文件结尾部分...')
              } else if (progressPercent < 100) {
                updateUploadStatus('正在完成上传...')
              }
            },
            // 上传凭证过期 - 按照官方文档实现
            onUploadTokenExpired: async (uploadInfo) => {
              console.log('onUploadTokenExpired:', uploadInfo.videoId)
              updateUploadStatus('上传凭证过期，正在刷新...')
              
              try {
                // 刷新上传凭证
                const refreshResult = await refreshUploadAuth({
                  videoId: uploadInfo.videoId
                })

                if (refreshResult.code !== 200) {
                  throw new Error(refreshResult.message || '刷新上传凭证失败')
                }

                const { uploadAuth } = refreshResult.data
                
                // 使用新的凭证继续上传
                uploader.resumeUploadWithAuth(uploadAuth)
                updateUploadStatus('凭证已刷新，继续上传...')
              } catch (error) {
                console.error('刷新上传凭证失败:', error)
                errorMessage.value = error.message || '刷新上传凭证失败'
                isUploading.value = false
                ElMessage.error(errorMessage.value)
              }
            },
          })

          resolve()
        } catch (error) {
          reject(error)
        }
      })
    }

    const updateUploadSpeed = (currentBytes) => {
      const now = Date.now()
      const timeDiff = (now - uploadStartTime.value) / 1000
      
      // 计算总的上传速度（从开始到现在）
      if (timeDiff > 0 && currentBytes > 0) {
        const totalSpeed = currentBytes / timeDiff
        const formattedSpeed = formatFileSize(totalSpeed) + '/s'
        uploadSpeed.value = formattedSpeed
        
        // 计算上传耗时
        uploadTimeElapsed.value = Math.floor(timeDiff)
        
        // 计算预计剩余时间
        if (totalSpeed > 0 && uploadProgress.value < 100) {
          const remainingBytes = selectedFile.value.size - currentBytes
          const remainingTime = remainingBytes / totalSpeed
          
          // 防止异常值
          if (remainingTime > 0 && remainingTime < 86400 * 365) { // 小于1年
            uploadTimeRemaining.value = Math.floor(remainingTime)
          } else {
            uploadTimeRemaining.value = 0
          }
        }
      } else {
        // 设置默认值
        uploadSpeed.value = '0 B/s'
        uploadTimeElapsed.value = Math.floor(timeDiff)
        uploadTimeRemaining.value = 0
      }
      
      // 更新最后上传的字节数，用于计算增量速度
      lastUploadedBytes.value = currentBytes
    }

    // 格式化时间显示
    const formatTime = (seconds) => {
      if (!seconds || seconds <= 0) {
        return '0秒'
      }
      
      if (seconds < 60) {
        return `${seconds}秒`
      } else if (seconds < 3600) {
        const minutes = Math.floor(seconds / 60)
        const remainingSeconds = seconds % 60
        return `${minutes}分${remainingSeconds}秒`
      } else if (seconds < 86400) { // 小于1天
        const hours = Math.floor(seconds / 3600)
        const minutes = Math.floor((seconds % 3600) / 60)
        return `${hours}小时${minutes}分`
      } else {
        const days = Math.floor(seconds / 86400)
        const hours = Math.floor((seconds % 86400) / 3600)
        return `${days}天${hours}小时`
      }
    }

    // 获取进度条颜色
    const getProgressColor = (progress) => {
      if (!progress || progress <= 0) return '#f56c6c'
      if (progress < 30) return '#f56c6c'
      if (progress < 70) return '#e6a23c'
      return '#67c23a'
    }

    // 更新上传状态
    const updateUploadStatus = (status) => {
      uploadStatus.value = status
    }


    const retryUpload = () => {
      clearError()
      clearUploadResult()
      startUpload()
    }

    onUnmounted(() => {
      // 清理视频预览URL
      if (videoPreviewUrl.value) {
        URL.revokeObjectURL(videoPreviewUrl.value)
      }
      // 清理封面预览URL
      if (coverPreviewUrl.value) {
        URL.revokeObjectURL(coverPreviewUrl.value)
      }
      // 清理上传状态
      clearUploadResult()
      clearError()
    })

    // 组件卸载清理
    onBeforeUnmount(() => {
      // Quill编辑器会自动清理，无需手动销毁
    })

    // 获取分类数据
    const loadCategories = async () => {
      try {
        const response = await getUserCourseCategories()
        if (response && response.code === 200) {
          // 过滤出课程分类 (type === 1)
          courseCategories.value = response.data.filter(category => category.type === 1)
        }
      } catch (error) {
        console.error('获取课程分类失败:', error)
        // 失败时使用默认分类
        courseCategories.value = []
      }
    }

    // 组件挂载时
    onMounted(async () => {
      // 先获取最新用户信息
      await updateUserInfo()
      await loadCategories()
      
      // 检查阿里云上传SDK是否已加载
      if (typeof window.AliyunUpload === 'undefined') {
        console.warn('阿里云上传SDK未加载，请确保已引入相关脚本')
      } else if (typeof window.AliyunUpload.Vod === 'undefined') {
        console.warn('阿里云上传SDK.Vod模块未加载，请确保已引入相关脚本')
      } else {
        console.log('阿里云上传SDK加载成功:', {
          'AliyunUpload类型': typeof window.AliyunUpload,
          'AliyunUpload.Vod类型': typeof window.AliyunUpload.Vod
        })
      }
    })

    return {
      currentStep,
      fileInput,
      selectedFile,
      videoPlayer,
      videoPreviewUrl,
      videoDuration,
      videoResolution,
      coverInput,
      coverFile,
      coverPreviewUrl,
      isUploading,
      uploadProgress,
      uploadedBytes,
      uploadSpeed,
      uploadStatus,
      uploadTimeElapsed,
      uploadTimeRemaining,
      uploadResult,
      errorMessage,
      formData,
      courseCategories,
      canUpload,
      triggerFileSelect,
      handleFileSelect,
      handleDrop,
      clearFile,
      triggerCoverSelect,
      handleCoverSelect,
      clearCover,
      onVideoLoaded,
      onVideoError,
      nextStep,
      prevStep,
      resetUpload,
      formatFileSize,
      formatTime,
      getProgressColor,
      updateUploadStatus,
      clearError,
      clearUploadResult,
      startUpload,
      retryUpload,
      // 富文本编辑器
      editorOptions,
      handleContentUpdate
    }
  }
}
</script>

<style scoped>
/* 全屏上传遮罩层（参考课程组件样式） */
.upload-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.75);
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.overlay-content {
  width: min(560px, 90%);
  background: rgba(20, 20, 20, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 10px 40px rgba(0,0,0,0.5);
  border-radius: 16px;
  padding: 28px 24px;
  color: #fff;
  text-align: center;
}

.overlay-icon { font-size: 36px; color: #000; margin-bottom: 8px; }
.overlay-content h3 { margin: 6px 0 10px; font-size: 20px; font-weight: 700; color: #fff; }
.overlay-content p { margin: 0 0 14px; color: #ddd; line-height: 1.6; }
.overlay-progress { margin: 14px 0; }
.overlay-stats { margin-top: 6px; color: #cfd8dc; font-size: 13px; }
.video-upload-container {
  margin: 0 auto;
  padding: 20px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  display: block;
  width: 100%;
  box-sizing: border-box;
}

/* 步骤指示器 */
.step-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 15px;
  padding: 20px 40px;
  background: #f5f5f5;
  border-radius: 12px;
  box-sizing: border-box;
}

.step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  position: relative;
  z-index: 2;
}

.step-circle {
  position: relative;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #e9ecef;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
  border: 2px solid #e9ecef;
}

.step-number {
  font-size: 14px;
  font-weight: 600;
  color: #6c757d;
  transition: all 0.3s ease;
}


.step.active .step-circle {
  background: #000;
  border-color: #000;
}

.step.active .step-number {
  color: white;
}


.step.completed .step-circle {
  background: #fff;
  border-color: #000;
  border-width: 3px;
}

.step.completed .step-number {
  color: #000;
}

.step-check {
  font-size: 18px;
  color: #000;
  font-weight: bold;
}


.step-text {
  font-size: 14px;
  color: #6c757d;
  font-weight: 400;
  text-align: center;
  transition: all 0.3s ease;
  margin-top: 8px;
}

.step.active .step-text {
  color: #000;
  font-weight: 500;
}

.step.completed .step-text {
  color: #000;
  font-weight: 500;
}

.step-line {
  width: 80px;
  height: 3px;
  background: #e9ecef;
  margin: 0 20px;
  transition: all 0.3s ease;
  position: relative;
  top: -16px;
  z-index: 1;
}

.step-line.completed {
  background: #000;
}

/* 步骤内容 */
.step-content {
  animation: fadeIn 0.3s ease-in-out;
  padding: 0px;
  box-sizing: border-box;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.upload-header {
  text-align: center;
  margin-bottom: 20px;
  padding: 0;
  margin-top: 10px;
}

.upload-header h3 {
  color: #333;
  margin-bottom: 10px;
  font-size: 24px;
  font-weight: 600;
}

.upload-header p {
  color: #666;
  font-size: 14px;
}

/* 文件上传区域 */
.file-upload-area {
  border: 2px dashed #ddd;
  border-radius: 12px;
  padding: 60px 20px;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s;
  background: #fafafa;
  margin-bottom: 20px;
}

.file-upload-area:hover {
  border-color: #070707;
  background: #f5f5f5;
}

.upload-icon {
  font-size: 48px;
  margin-bottom: 16px;
  color: #0c0c0c;
}

.upload-text {
  font-size: 18px;
  color: #333;
  margin-bottom: 8px;
  font-weight: 500;
}

.upload-hint {
  font-size: 14px;
  color: #666;
}

/* 文件预览 */
.file-preview {
  margin-top: 30px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
}

.file-info {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 20px;
}

.file-icon {
  font-size: 32px;
  color: #000;
}

.file-details h4 {
  margin: 0 0 4px 0;
  color: #333;
  font-size: 16px;
}

.file-details p {
  margin: 0;
  color: #666;
  font-size: 14px;
}

.step-action-center {
  display: flex;
  justify-content: center;
  margin: 20px 0;
}

.step-actions-row {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin: 20px 0;
}

.step-btn {
  flex: 0 0 120px;
  height: 40px;
  font-size: 14px;
}

.next-btn {
  min-width: 120px;
}

/* 文件摘要 */
.file-summary {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
  margin-bottom: 30px;
}

/* 视频预览区域 */
.video-preview-section {
  margin-bottom: 30px;
}

.video-container {
  margin-bottom: 20px;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

.video-player {
  width: 100%;
  max-height: 400px;
  background: #000;
}

.video-info {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 15px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
}

.info-item {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #666;
  font-size: 14px;
}

.info-item .el-icon {
  color: #000;
}

/* 步骤操作按钮 */
.step-actions {
  display: flex;
  justify-content: space-between;
  margin-top: 30px;
}

/* 表单区域 */
.form-section {
  margin-bottom: 30px;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 20px;
}

.form-group {
  margin-bottom: 20px;
}

.form-group label {
  display: block;
  margin-bottom: 8px;
  font-weight: 500;
  color: #333;
  font-size: 14px;
  text-align: left;
}

/* 封面上传区域 */
.cover-upload-area {
  border: 2px dashed #ddd;
  border-radius: 8px;
  overflow: hidden;
  transition: all 0.3s;
}

.cover-upload-area:hover {
  border-color: #000;
}

.cover-upload-placeholder {
  padding: 40px 20px;
  text-align: center;
  cursor: pointer;
  background: #fafafa;
}

.cover-upload-icon {
  font-size: 32px;
  color: #000;
  margin-bottom: 12px;
}

.cover-upload-placeholder p {
  margin: 8px 0;
  color: #666;
  font-size: 14px;
}

.cover-hint {
  font-size: 12px;
  color: #999;
}

.cover-preview {
  position: relative;
  text-align: center;
}

.cover-image {
  width: 100%;
  max-height: 200px;
  object-fit: cover;
  border-radius: 8px;
}

.cover-actions {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  gap: 8px;
}

/* 上传操作 */
.upload-actions {
  display: flex;
  gap: 15px;
  margin-bottom: 30px;
}

.upload-actions .el-button {
  flex: 1;
}

.upload-actions .el-button--primary {
  background: #333 !important;
  border-color: #333 !important;
  color: #fff !important;
  font-weight: 500 !important;
  border-radius: 8px !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important;
}

.upload-actions .el-button--primary:hover {
  background: #222 !important;
  border-color: #222 !important;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25) !important;
}

/* 上传进度 */
.upload-progress {
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
  margin-bottom: 30px;
}

.progress-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.progress-header h4 {
  margin: 0;
  font-size: 16px;
  color: #000;
  display: flex;
  align-items: center;
  gap: 8px;
}

.upload-status {
  font-size: 14px;
  color: #666;
}

.progress-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.progress-main {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.progress-text {
  font-size: 18px;
  font-weight: 600;
  color: #000;
}

.progress-speed {
  font-size: 14px;
  color: #666;
}

.progress-time {
  font-size: 14px;
  color: #666;
  display: flex;
  flex-direction: column;
  gap: 5px;
  text-align: right;
}

.progress-time span {
  display: block;
  line-height: 1.4;
}

.progress-bar {
  margin-bottom: 10px;
}

.progress-bar :deep(.el-progress-bar__outer) {
  border-radius: 10px;
  background-color: #f0f0f0;
}

.progress-bar :deep(.el-progress-bar__inner) {
  border-radius: 10px;
  transition: all 0.3s ease;
}

.progress-details {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 14px;
  color: #666;
}

.file-info {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.file-name {
  font-weight: 500;
  color: #333;
}


/* 上传结果 */
.upload-result {
  margin-bottom: 30px;
}

.success-message,
.error-message {
  padding: 40px 20px;
  border-radius: 16px;
  text-align: center;
}

.success-message {
  background: linear-gradient(135deg, #f5f5f5 0%, #e5e5e5 100%);
  border: 2px solid #d0d0d0;
  color: #000;
}

.error-message {
  background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%);
  border: 2px solid #f5c6cb;
  color: #721c24;
}

.success-content,
.error-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.success-icon {
  font-size: 48px;
  color: #67c23a;
  margin-bottom: 8px;
}

.error-icon {
  font-size: 48px;
  color: #f56c6c;
  margin-bottom: 8px;
}

.upload-result h4 {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
}

.upload-result p {
  margin: 0;
  font-size: 16px;
  color: #666;
  max-width: 400px;
}

/* Quill富文本编辑器样式 */
.editor-container {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background: #fff;
}

.editor-container :deep(.ql-toolbar) {
  border-bottom: 1px solid #e4e7ed;
  background: #fafafa;
  text-align: left;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: wrap;
}

.editor-container :deep(.ql-container) {
  border: none;
  font-size: 14px;
}

.editor-container :deep(.ql-editor) {
  min-height: 250px;
  padding: 15px;
  line-height: 1.6;
}

.editor-container :deep(.ql-editor.ql-blank::before) {
  color: #c0c4cc;
  font-style: normal;
}

/* 确保工具栏按钮组左对齐 */
.editor-container :deep(.ql-formats) {
  margin-right: 15px;
}

.editor-container :deep(.ql-formats:first-child) {
  margin-left: 0;
}



/* 响应式设计 */
@media (max-width: 768px) {
  .video-upload-container {
    padding: 15px;
    margin: 10px;
  }
  
  .form-row {
    grid-template-columns: 1fr;
    gap: 0;
  }
  
  .upload-actions {
    flex-direction: column;
  }
  
  .step-line {
    width: 40px;
  }
  
  .step-indicator {
    flex-direction: column;
    gap: 10px;
  }
  
  .step-line {
    width: 2px;
    height: 40px;
  }
  
  .video-info {
    grid-template-columns: 1fr;
  }
  
  .file-upload-area {
    padding: 40px 15px;
  }
  
  .step-content {
    padding: 15px;
  }
}

@media (max-width: 480px) {
  .video-upload-container {
    padding: 10px;
    margin: 5px;
  }
  
  .step-indicator {
    padding: 15px 0;
  }
  
  .step-circle {
    width: 50px;
    height: 50px;
  }
  
  
  .file-upload-area {
    padding: 30px 10px;
  }
  
  .step-content {
    padding: 10px;
  }
}
</style>
