<template>
  <div class="workflow-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 class="step-line" :class="{ completed: currentStep > 3 }"></div>
      <div class="step" :class="{ active: currentStep === 4, completed: currentStep > 4 }">
        <div class="step-circle">
          <span v-if="currentStep <= 4" class="step-number" style="color: #fff;">4</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 > 4 }"></div>
      <div class="step" :class="{ active: currentStep === 5, completed: currentStep > 5 }">
        <div class="step-circle">
          <span v-if="currentStep <= 5" class="step-number" style="color: #fff;">5</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>完善工作流的基本信息，包括名称、分类和描述</p>
      </div>

      <div class="form-section">
        <div class="form-row">
          <div class="form-group">
            <label>工作流名称 *</label>
            <el-input 
              v-model="workflowForm.name" 
              placeholder="请输入工作流名称"
              maxlength="100"
              show-word-limit
              size="large"
            />
          </div>
          <div class="form-group">
            <label>工作流分类 *</label>
            <el-select v-model="workflowForm.category" placeholder="请选择分类" style="width: 100%" size="large">
              <el-option 
                v-for="category in workflowCategories" 
                :key="category.id" 
                :label="category.name" 
                :value="category.name" 
              />
            </el-select>
          </div>
        </div>

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

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

    <!-- 第二步：工作流内容 -->
    <div v-if="currentStep === 2" class="step-content">
      <div class="upload-header">
        <h3>提供工作流内容</h3>
        <p>选择其中一种方式提供工作流内容：JSON数据或文件资源包</p>
      </div>

      <div class="content-tabs">
        <el-tabs v-model="activeTab" class="workflow-tabs">
          <el-tab-pane label="JSON数据模式" name="json">
            <div class="form-group">
              <label>工作流JSON配置</label>
              <el-input 
                v-model="workflowForm.data" 
                type="textarea" 
                :rows="10"
                placeholder="请输入工作流JSON配置数据"
                :disabled="!!workflowForm.dataFileUrl"
                size="large"
              />
              <div class="form-tip">
                <el-icon><InfoFilled /></el-icon>
                <span>直接输入工作流的JSON配置数据</span>
              </div>
              <div v-if="workflowForm.dataFileUrl" class="form-warning">
                <el-icon><Warning /></el-icon>
                <span>当前已选择文件模式，请切换到"文件资源包模式"标签页</span>
              </div>
              <div v-else class="form-success">
                <el-icon><CircleCheck /></el-icon>
                <span>当前为JSON模式，可以输入JSON配置数据</span>
              </div>
              
            </div>
          </el-tab-pane>

          <el-tab-pane label="文件资源包模式" name="file">
            <div class="form-group">
              <label>资源包文件</label>
              <el-upload
                class="upload-demo"
                drag
                :before-upload="beforeResourceUpload"
                :on-change="onResourceChange"
                :on-remove="onResourceRemove"
                :file-list="resourceFileList"
                :disabled="!!workflowForm.data && workflowForm.data.trim()"
                accept=".zip,.rar,.7z,.tar.gz"
                :limit="1"
                :auto-upload="false"
              >
                <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                <div class="el-upload__text">
                  将文件拖到此处，或<em>点击上传</em>
                </div>
                <template #tip>
                  <div class="el-upload__tip">
                    支持 zip、rar、7z、tar.gz 格式，文件大小不超过10MB
                  </div>
                </template>
              </el-upload>
              

          
            </div>
          </el-tab-pane>
        </el-tabs>
      </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" class="step-btn" :disabled="!canGoNext" 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="form-section">
        <div class="form-row">
          <div class="form-group">
            <label>封面图片</label>
            <div class="cover-upload-area">
              <div v-if="!workflowForm.coverUrl" class="cover-upload-placeholder" @click="triggerCoverSelect">
                <el-icon class="cover-upload-icon"><Picture /></el-icon>
                <p>点击上传封面图片</p>
                <p class="cover-hint">建议尺寸：800x600px，支持 JPG、PNG 格式</p>
              </div>
              <div v-else class="cover-preview">
                <img :src="workflowForm.coverUrl" 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="video-upload-area" @click="triggerVideoSelect" @drop="handleVideoDrop" @dragover.prevent>
              <div v-if="!selectedVideoFile" class="video-upload-placeholder">
                <el-icon class="video-upload-icon"><VideoCamera /></el-icon>
                <p>点击选择视频文件或拖拽文件到此处</p>
                <p class="video-hint">支持 MP4、AVI、MOV 格式，大小不超过1.5GB</p>
              </div>
              <div v-else class="video-preview-container">
                <video
                  ref="videoPlayer"
                  :src="videoPreviewUrl"
                  controls
                  preload="metadata"
                  class="video-player"
                  @loadedmetadata="onVideoLoaded"
                  @error="onVideoError"
                >
                  您的浏览器不支持视频播放
                </video>
                <div class="video-overlay">
                  <div class="video-actions">
                    <el-button @click="triggerVideoSelect" size="small" :icon="Edit">更换</el-button>
                    <el-button @click="clearVideo" size="small" type="danger" :icon="Delete">删除</el-button>
                  </div>
                </div>
              </div>
              <input
                ref="videoInput"
                type="file"
                accept="video/*"
                @change="handleVideoSelect"
                style="display: none"
              />
            </div>
            

       
          </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" class="step-btn" style="background: #0F172A; border-color: #0F172A;">
          下一步 <el-icon><ArrowRight /></el-icon>
        </el-button>
      </div>
    </div>

    <!-- 第四步：权限设置 -->
    <div v-if="currentStep === 4" class="step-content">
      <div class="upload-header">
        <h3>设置访问权限</h3>
        <p>配置工作流的访问权限和复制权限</p>
      </div>

      <div class="form-section">
        <div class="form-group">
          <label>是否免费</label>
          <el-select v-model="workflowForm.isFree" placeholder="请选择" style="width: 100%" size="large" @change="onFreeStatusChange">
            <el-option label="收费" :value="0" />
            <el-option label="免费" :value="1" />
          </el-select>
          <div class="permission-hint">
            <el-icon><InfoFilled /></el-icon>
            <span v-if="workflowForm.isFree === 1">免费内容：所有普通用户均可查看和复制</span>
            <span v-else>收费内容：默认VIP用户权限，查看和复制需要VIP身份</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" class="step-btn" style="background: #0F172A; border-color: #0F172A;">
          下一步 <el-icon><ArrowRight /></el-icon>
        </el-button>
      </div>
    </div>

    <!-- 第五步：提交工作流 -->
    <div v-if="currentStep === 5" class="step-content">
      <div class="upload-header">
        <h3 v-if="!submitting">确认并提交工作流</h3>
        <h3 v-else>正在上传文件并提交工作流</h3>
        <p v-if="!submitting">检查所有信息无误后，提交工作流</p>
        <p v-else>请耐心等待文件上传完成，请勿关闭或刷新页面</p>
      </div>

      <!-- 信息摘要 -->
      <div v-if="!submitting" class="summary-section">
        <h4>工作流信息摘要</h4>
        <div class="summary-grid">
          <div class="summary-item">
            <span class="summary-label">名称：</span>
            <span class="summary-value">{{ workflowForm.name }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">分类：</span>
            <span class="summary-value">{{ getCategoryLabel(workflowForm.category) }}</span>
          </div>
          <div class="summary-item summary-item-description">
            <span class="summary-label">描述：</span>
            <div class="summary-value summary-description-content" v-html="displayDescription"></div>
          </div>
          <div class="summary-item">
            <span class="summary-label">内容类型：</span>
            <span class="summary-value">{{ workflowForm.data ? 'JSON数据' : '资源包文件' }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">是否免费：</span>
            <span class="summary-value">{{ workflowForm.isFree === 1 ? '免费' : '收费' }}</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="handleSubmitWorkflow" type="primary" class="step-btn" :loading="submitting" style="background: #0F172A; border-color: #0F172A;">
          <el-icon><Check /></el-icon>
          {{ submitting ? '提交中...' : '提交工作流' }}
        </el-button>
      </div>
      
      <!-- 上传进度显示 -->
      <div v-if="submitting && uploadSteps.length > 0" class="upload-progress-section">
        <!-- 离开页面警告 -->
        <div class="leave-page-warning">
          <el-alert
            title="⚠️ 重要提醒"
            type="warning"
            :closable="false"
            show-icon
            class="warning-alert"
          >
            <template #default>
              <div class="warning-content">
                <p><strong>请勿关闭或刷新页面！</strong></p>
                <p>文件正在上传中，离开页面可能导致上传失败。请耐心等待所有文件上传完成。</p>
                <div class="warning-tips">
                  <el-icon><InfoFilled /></el-icon>
                  <span>上传完成后会自动提交工作流，请保持页面打开状态</span>
                </div>
              </div>
            </template>
          </el-alert>
        </div>
        
        <div class="upload-progress-header">
          <h4><el-icon><UploadFilled /></el-icon> 文件上传进度</h4>
          <div class="upload-status-text">{{ uploadStatus }}</div>
        </div>
        
        <!-- 封面图片OSS上传进度条 -->
        <div v-if="coverFile && (isUploadingCover || coverUploadProgress > 0)" class="cover-upload-progress">
          <div class="progress-header">
            <h4><el-icon><Picture /></el-icon> 正在上传封面图片</h4>
            <div class="upload-status">{{ isUploadingCover ? '图片上传中...' : '上传完成' }}</div>
          </div>
          
          <div class="progress-info">
           
            <div class="progress-time">
              <span>已用时: {{ formatTime(coverUploadTimeElapsed) }}</span>
              <span v-if="coverUploadTimeRemaining > 0">预计剩余: {{ formatTime(coverUploadTimeRemaining) }}</span>
            </div>
          </div>
          
          <el-progress 
            :percentage="coverUploadProgress" 
            :stroke-width="8"
            :show-text="false"
            :color="getProgressColor(coverUploadProgress)"
            class="progress-bar"
          />
          
          <div class="progress-details">
            <div class="file-info">
              <span>{{ formatFileSize(coverUploadedBytes || 0) }} / {{ formatFileSize(coverFile?.size || 0) }}</span>
              <span class="file-name">{{ coverFile?.name }}</span>
            </div>
          </div>
        </div>
        
        <!-- 资源包OSS上传进度条 -->
        <div v-if="resourceFile && (isUploadingResource || resourceUploadProgress > 0)" class="resource-upload-progress">
          <div class="progress-header">
            <h4><el-icon><Files /></el-icon> 正在上传资源包</h4>
            <div class="upload-status">{{ isUploadingResource ? '资源包上传中...' : '上传完成' }}</div>
          </div>
          
          <div class="progress-info">
           
            <div class="progress-time">
              <span>已用时: {{ formatTime(resourceUploadTimeElapsed) }}</span>
              <span v-if="resourceUploadTimeRemaining > 0">预计剩余: {{ formatTime(resourceUploadTimeRemaining) }}</span>
            </div>
          </div>
          
          <el-progress 
            :percentage="resourceUploadProgress" 
            :stroke-width="8"
            :show-text="false"
            :color="getProgressColor(resourceUploadProgress)"
            class="progress-bar"
          />
          
          <div class="progress-details">
            <div class="file-info">
              <span>{{ formatFileSize(resourceUploadedBytes || 0) }} / {{ formatFileSize(resourceFile?.size || 0) }}</span>
              <span class="file-name">{{ resourceFile?.name }}</span>
            </div>
          </div>
        </div>
        
        <!-- 视频VOD上传进度条 -->
        <div v-if="selectedVideoFile && (isUploadingVideo || videoUploadProgress > 0)" class="video-upload-progress">
          <div class="progress-header">
            <h4><el-icon><VideoPlay /></el-icon> 正在上传视频到VOD</h4>
            <div class="upload-status">{{ isUploadingVideo ? '视频上传中...' : '上传完成' }}</div>
          </div>
          
          <div class="progress-info">
            <div class="progress-main">
              <span class="progress-text">{{ videoUploadProgress }}%</span>
              <span class="progress-speed">{{ videoUploadSpeed }}</span>
            </div>
            <div class="progress-time">
              <span>已用时: {{ formatTime(videoUploadTimeElapsed) }}</span>
              <span v-if="videoUploadTimeRemaining > 0">预计剩余: {{ formatTime(videoUploadTimeRemaining) }}</span>
            </div>
          </div>
          
          <el-progress 
            :percentage="videoUploadProgress" 
            :stroke-width="8"
            :show-text="false"
            :color="getProgressColor(videoUploadProgress)"
            class="progress-bar"
          />
          
          <div class="progress-details">
            <div class="file-info">
              <span>{{ formatFileSize(videoUploadedBytes || 0) }} / {{ formatFileSize(selectedVideoFile?.size || 0) }}</span>
              <span class="file-name">{{ selectedVideoFile?.name }}</span>
            </div>
            <div class="upload-controls" v-if="isUploadingVideo">
              
            </div>
          </div>
        </div>
        
        <!-- 提交结果显示 -->
        <div v-if="showSubmitResultFlag && submitResult" class="submit-result-section">
          <div class="result-header">
            <h4><el-icon><CircleCheck /></el-icon> 工作流提交成功</h4>
          </div>
          
          <div class="result-content">
            <div class="result-item">
              <span class="result-label">工作流ID：</span>
              <span class="result-value">{{ submitResult.workflowId }}</span>
            </div>
            <div class="result-item">
              <span class="result-label">工作流名称：</span>
              <span class="result-value">{{ submitResult.workflowName }}</span>
            </div>
            <div class="result-item">
              <span class="result-label">提交时间：</span>
              <span class="result-value">{{ submitResult.submitTime }}</span>
            </div>
          </div>
          
          <div class="result-actions">
            <el-button @click="resetForm" type="primary" size="large">
              继续创建新工作流
            </el-button>
            <el-button @click="goToWorkflowList" size="large">
              查看我的工作流
            </el-button>
          </div>
        </div>
      </div>
    </div>

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

    <!-- 全屏上传遮罩层：参考其他上传页面 -->
    <div v-if="submitting" class="upload-overlay">
      <div class="overlay-content">
        <h3>正在上传并提交，请稍候</h3>
        <p>文件正在上传，请不要关闭或离开此页面。</p>
        <div class="overlay-progress">
          <el-progress :percentage="totalUploadProgress" :stroke-width="10" :show-text="true" :color="getProgressColor(totalUploadProgress)" />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, watch, onUnmounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
import { 
  Files,
  Picture,
  Check,
  InfoFilled, 
  UploadFilled, 
  VideoPlay, 
  VideoCamera,
  ArrowRight,
  ArrowLeft,
  Warning,
  CircleCheck,
  Edit,
  Delete
} from '@element-plus/icons-vue'
import { submitWorkflow } from '@/api/workflow'
import { getPostSignature } from '@/api/files'
import { createUploadAuth, refreshUploadAuth } from '@/api/vod'
import { useUserStore } from '@/store/user'
import { getCurrentUser, getUserWorkflowCategories } from '@/api/user'
import * as MP4Box from 'mp4box'
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'

// 路由和用户store
const router = useRouter()
const userStore = useUserStore()

// 获取用户信息
const userInfo = computed(() => userStore.getUserInfo)

// 更新用户信息的函数
const updateUserInfo = async () => {
  try {
    console.log('WorkflowUploadComponent: 开始获取最新用户信息')
    const response = await getCurrentUser()
    console.log('WorkflowUploadComponent: API响应数据:', response)
    
    if (response.code === 200) {
      console.log('WorkflowUploadComponent: 更新用户信息到store:', response.data)
      userStore.updateUserInfo(response.data)
      console.log('WorkflowUploadComponent: 用户信息已更新到store')
    } else {
      console.error('WorkflowUploadComponent: 获取用户信息失败:', response.message)
    }
  } catch (error) {
    console.error('WorkflowUploadComponent: 更新用户信息失败:', error)
  }
}

// 表单引用
const workflowFormRef = ref()
  // 已移除未使用的模板引用（resourceUploadRef、coverUploadRef）

// 当前步骤
const currentStep = ref(1)

// 当前激活的标签页
const activeTab = ref('json')

// 提交状态
const submitting = ref(false)

// 提交结果状态
const submitResult = ref(null)
const showSubmitResultFlag = ref(false)

// 错误信息
const errorMessage = ref('')

// 文件列表
const resourceFileList = ref([])

// 表单数据
const workflowForm = reactive({
  name: '',
  description: '',
  data: '',
  dataFileUrl: '',
  coverUrl: '',
  videoId: null,
  category: '',
  isFree: 0, // 默认收费
  isPublic: 1, // 默认公开，用户无法修改
  fullAccessRole: 2, // 默认VIP用户权限
  copyAccessRole: 2  // 默认VIP用户权限
})

// 文件相关状态
const coverFile = ref(null)
const resourceFile = ref(null)
const isUploadingCover = ref(false)
const isUploadingResource = ref(false)
const isUploadingVideo = ref(false)
const uploadProgress = ref(0)
const overallUploadProgress = ref(0)


// 分类数据
const workflowCategories = ref([])

// OSS上传进度相关状态
const coverUploadProgress = ref(0)
const coverUploadSpeed = ref('0 KB/s')
const coverUploadTimeElapsed = ref(0)
const coverUploadTimeRemaining = ref(0)
const coverUploadedBytes = ref(0)
const coverUploadStartTime = ref(0)
const coverLastUploadedBytes = ref(0)

const resourceUploadProgress = ref(0)
const resourceUploadSpeed = ref('0 KB/s')
const resourceUploadTimeElapsed = ref(0)
const resourceUploadTimeRemaining = ref(0)
const resourceUploadedBytes = ref(0)
const resourceUploadStartTime = ref(0)
const resourceLastUploadedBytes = ref(0)

// 视频上传进度相关状态
const videoUploadProgress = ref(0)
const videoUploadSpeed = ref('0 KB/s')
const videoUploadTimeElapsed = ref(0)
const videoUploadTimeRemaining = ref(0)
const videoUploadedBytes = ref(0)
const videoUploadStartTime = ref(0)
const videoLastUploadedBytes = ref(0)
const videoUploadPaused = ref(false)

// 上传状态管理
const uploadStatus = ref('')
const uploadSteps = ref([])
const currentUploadStep = ref(0)

// 计算总上传进度（用于全屏遮罩层进度显示）
const totalUploadProgress = computed(() => {
  const progresses = []
  if (coverFile.value) progresses.push(Number(coverUploadProgress.value || 0))
  if (resourceFile.value) progresses.push(Number(resourceUploadProgress.value || 0))
  if (selectedVideoFile.value) progresses.push(Number(videoUploadProgress.value || 0))
  if (progresses.length === 0) return 0
  const sum = progresses.reduce((acc, n) => acc + n, 0)
  const avg = Math.round(sum / progresses.length)
  return Math.max(0, Math.min(100, avg))
})

// 阿里云上传器实例
let uploader = null

// 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) => {
  workflowForm.description = content
}

// 检查富文本内容是否有实际文本（去除HTML标签后）
const hasActualContent = (htmlContent) => {
  if (!htmlContent) return false
  // 创建临时DOM元素来提取纯文本
  const tempDiv = document.createElement('div')
  tempDiv.innerHTML = htmlContent
  const textContent = tempDiv.textContent || tempDiv.innerText || ''
  return textContent.trim().length > 0
}

// 计算属性：获取要显示的描述内容
const displayDescription = computed(() => {
  if (!workflowForm.description || !workflowForm.description.trim()) {
    return '<p style="color: #999; font-style: italic;">暂无描述</p>'
  }
  return workflowForm.description
})

// 处理富文本中的base64图片上传到OSS
const processDescriptionImages = async () => {
  if (!workflowForm.description) return workflowForm.description
  
  const base64Regex = /<img[^>]+src="data:image\/([^;]+);base64,([^"]+)"[^>]*>/g
  let processedDescription = workflowForm.description
  const uploadPromises = []
  
  let match
  while ((match = base64Regex.exec(workflowForm.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
}

// 上传图片到COS
const uploadImageToOSS = async (file) => {
  try {
    const userId = getUserId()
    if (!userId) {
      throw new Error('无法获取用户ID，请重新登录')
    }
    
    // 使用POST签名方式上传
    const postSignatureResult = await getPostSignature({
      fileName: file.name,
      userId: userId
    })

    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) {
      // 上传成功，使用后端返回的host构建文件访问地址
      const fileUrl = `${signatureData.host}/${fileKey}`
      return fileUrl
    } else {
      const errorText = await uploadResponse.text()
      throw new Error(`图片上传失败: HTTP ${uploadResponse.status} - ${errorText}`)
    }
  } catch (error) {
    console.error('图片上传到COS失败:', error)
    throw error
  }
}

// 计算属性：是否可以进入下一步
const canGoNext = computed(() => {
  let result = false
  
  switch (currentStep.value) {
    case 1:
      result = workflowForm.name.trim() && hasActualContent(workflowForm.description) && workflowForm.category
      break
    case 2:
      // 第2步：JSON模式需要data，文件模式需要resourceFile
      if (activeTab.value === 'json') {
        result = workflowForm.data.trim()
        console.log('JSON模式验证:', { data: workflowForm.data, result })
      } else {
        result = resourceFile.value !== null
        console.log('文件模式验证:', { 
          activeTab: activeTab.value, 
          resourceFile: resourceFile.value, 
          resourceFileList: resourceFileList.value,
          result 
        })
      }
      break
    case 3:
      result = selectedVideoFile.value // 第3步必须选择视频
      break
    case 4:
      result = true
      break
    default:
      result = false
  }
  
  console.log(`第${currentStep.value}步 canGoNext:`, result, {
    step: currentStep.value,
    activeTab: activeTab.value,
    data: workflowForm.data,
    resourceFile: resourceFile.value,
    selectedVideoFile: selectedVideoFile.value
  })
  
  return result
})

// 已移除 uploadAction 与 uploadHeaders（不使用 el-upload 自动上传）

// 监听标签页切换，清空对应的内容
watch(activeTab, (newTab) => {
  console.log('标签页切换:', newTab)
  if (newTab === 'json') {
    console.log('切换到JSON模式，清空文件URL')
    workflowForm.dataFileUrl = ''
    // 不要清空resourceFileList，因为用户可能已经选择了文件
  } else {
    console.log('切换到文件模式，清空JSON数据')
    workflowForm.data = ''
  }
})

// 步骤控制
const nextStep = () => {
  if (currentStep.value < 5 && canGoNext.value) {
    currentStep.value++
  }
}

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

// 资源包文件变化处理改为依赖 beforeResourceUpload（已移除 @change 监听）

// 资源包上传前验证 (优化版本)
const beforeResourceUpload = (file) => {
  console.log('beforeResourceUpload 被调用，文件:', file)
  
  const isValidType = /\.(zip|rar|7z|tar\.gz)$/i.test(file.name)
  const isLt100M = file.size / 1024 / 1024 < 100

  if (!isValidType) {
    ElMessage.error('只能上传压缩包格式文件!')
    return false
  }
  if (!isLt100M) {
    ElMessage.error('文件大小不能超过 100MB!')
    return false
  }
  
  console.log('文件验证通过，设置状态')
  
  // 保存文件引用 - 直接设置，不依赖异步
  resourceFile.value = file
  
  console.log('beforeResourceUpload 状态设置完成:')
  console.log('- resourceFile.value:', resourceFile.value)
  console.log('- canGoNext.value:', canGoNext.value)
  
  // 成功消息提示
  ElMessage.success(`文件 ${file.name} 验证通过，将在提交时上传`)
  
  // 返回false阻止自动上传，但文件会被添加到文件列表
  return false
}

// 已移除 onResourceUploadSuccess（不再使用，改为手动上传）

// 资源包文件变化处理 (使用 on-change 事件) - 备选方案
const onResourceChange = (file, fileList) => {
  console.log('onResourceChange 被调用', { 
    file: file, 
    fileList: fileList,
    fileStatus: file?.status,
    fileName: file?.name
  })
  
  // 处理文件添加情况
  if (file && (file.status === 'ready' || !file.status)) {
    // 确保我们获取到原始文件对象
    const rawFile = file.raw || file
    
    // 再次验证文件（防止通过其他方式添加了无效文件）
    const isValidType = /\.(zip|rar|7z|tar\.gz)$/i.test(rawFile.name)
    const isLt100M = rawFile.size / 1024 / 1024 < 100
    
    if (!isValidType || !isLt100M) {
      console.log('onResourceChange: 文件验证失败')
      resourceFile.value = null
      return
    }
    
    // 文件验证通过，更新状态
    resourceFile.value = rawFile
    
    console.log('onResourceChange 设置状态成功:')
    console.log('- resourceFile.value:', resourceFile.value)
    console.log('- 文件名:', rawFile.name)
    console.log('- 文件大小:', rawFile.size)
    console.log('- canGoNext.value:', canGoNext.value)
    
    // 确保canGoNext能正确更新
    nextTick(() => {
      console.log('onResourceChange nextTick后检查:')
      console.log('- activeTab.value:', activeTab.value)
      console.log('- resourceFile.value存在:', !!resourceFile.value)
      console.log('- canGoNext.value:', canGoNext.value)
      
      // 如果仍然无法进入下一步，强制触发更新
      if (!canGoNext.value && resourceFile.value) {
        console.warn('检测到canGoNext状态异常，尝试修复...')
        // 触发响应式更新
        const temp = resourceFile.value
        resourceFile.value = null
        setTimeout(() => {
          resourceFile.value = temp
          console.log('强制更新后 canGoNext.value:', canGoNext.value)
        }, 50)
      }
    })
    
  } else if (file && file.status === 'fail') {
    // 文件选择失败
    console.log('onResourceChange: 文件状态为fail')
    resourceFile.value = null
  } else if (fileList.length === 0) {
    // 文件列表为空，清理状态
    console.log('onResourceChange: 文件列表为空，清理状态')
    resourceFile.value = null
  }
}

// 资源包移除
const onResourceRemove = () => {
  workflowForm.dataFileUrl = ''
  resourceFile.value = null
  resourceFileList.value = [] // 清空文件列表
  console.log('资源包已移除，resourceFile.value:', resourceFile.value, 'resourceFileList.value:', resourceFileList.value)
}

// 手动上传资源包到OSS
const handleManualResourceUpload = async () => {
  if (!resourceFile.value) {
    ElMessage.error('请选择要上传的文件')
    return
  }

  try {
    isUploadingResource.value = true
    uploadProgress.value = 0
    
    // 模拟上传进度
    const progressInterval = setInterval(() => {
      if (uploadProgress.value < 90) {
        uploadProgress.value += Math.random() * 10
      }
    }, 200)
    
    const uploadResult = await uploadResourceToOSS(resourceFile.value)
    
    // 清除进度模拟
    clearInterval(progressInterval)
    uploadProgress.value = 100

    if (uploadResult.success) {
      workflowForm.dataFileUrl = uploadResult.url
      ElMessage.success('资源包上传成功')
    } else {
      throw new Error(uploadResult.message || '上传失败')
    }
  } catch (error) {
    console.error('手动资源包上传失败:', error)
    ElMessage.error(error.message || '资源包上传失败')
  } finally {
    isUploadingResource.value = false
  }
}

// 上传资源包到OSS - 使用XMLHttpRequest，按照示例代码简化逻辑
const uploadResourceToOSS = async (file) => {
  try {
    // 兼容 element-plus 的 UploadFile，优先取 raw File
    const rawFile = file && file.raw ? file.raw : file
    console.log('开始上传资源包:', rawFile?.name || file?.name)
    
    // 获取用户ID并验证
    const userId = getUserId()
    console.log('uploadResourceToOSS - 获取到的userId:', userId)
    
    if (!userId) {
      throw new Error('无法获取用户ID，请重新登录')
    }
    
    // 使用POST签名方式上传
    console.log('uploadResourceToOSS - 调用getPostSignature，参数:', { fileName: rawFile.name, userId: userId })
    
    const postSignatureResult = await getPostSignature({
      fileName: file.name,
      userId: userId
    })
    
    console.log('uploadResourceToOSS - getPostSignature响应:', postSignatureResult)

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

    const signatureData = postSignatureResult.data
    console.log('uploadResourceToOSS - POST签名响应:', signatureData)
    
    // 创建FormData
    const formData = new FormData()
    
    // 使用后端返回的dir生成文件路径
    const objectKey = signatureData.dir + Date.now() + '_' + rawFile.name
    
    console.log('uploadResourceToOSS - 使用COS策略中的路径:', objectKey)
    
    // COS POST 表单上传必需字段
    formData.append('key', objectKey)
    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'])
    
    // 添加对象的Content-Type，满足OSS策略对Content-Type前缀的要求（application/）
    try {
      const inferContentType = (f) => {
        const name = (f?.name || '').toLowerCase()
        const ext = name.includes('.') ? name.substring(name.lastIndexOf('.') + 1) : ''
        // 文件自带类型优先，且满足application/*
        if (f?.type && f.type.startsWith('application/')) return f.type
        // 基于扩展名兜底
        switch (ext) {
          case 'zip': return 'application/zip'
          case 'rar': return 'application/x-rar-compressed'
          case '7z': return 'application/x-7z-compressed'
          case 'tar': return 'application/x-tar'
          case 'gz':
          case 'tgz': return 'application/gzip'
          case 'bz2': return 'application/x-bzip2'
          case 'xz': return 'application/x-xz'
          default: return 'application/octet-stream'
        }
      }
      const contentType = inferContentType(rawFile)
      formData.append('Content-Type', contentType)
      console.log('uploadResourceToOSS - 设定Content-Type:', contentType)
    } catch (_) {
      // 兜底
      formData.append('Content-Type', 'application/octet-stream')
      console.log('uploadResourceToOSS - 设定Content-Type: application/octet-stream (fallback)')
    }
    
    // 添加文件 - 必须在最后添加，确保Content-Type正确
    formData.append('file', rawFile)
    
    console.log('uploadResourceToOSS - FormData准备完成，开始上传到OSS')
    console.log('uploadResourceToOSS - 上传参数:', {
      key: objectKey,
      host: signatureData.host,
      fileSize: rawFile.size,
      fileName: rawFile.name
    })
    
    // 使用XMLHttpRequest上传到OSS
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest()
      
      // 监听上传进度
      xhr.upload.addEventListener('progress', function(e) {
        if (e.lengthComputable) {
          const percentComplete = (e.loaded / e.total) * 100
          resourceUploadProgress.value = Math.round(percentComplete)
          resourceUploadedBytes.value = e.loaded
          
          // 更新上传速度和时间
          updateResourceUploadSpeed()
          updateResourceUploadTime()
        }
      })
      
      // 监听上传完成
      xhr.addEventListener('load', function() {
        if (xhr.status >= 200 && xhr.status < 300) {
          const responseText = xhr.responseText
          console.log('uploadResourceToOSS - 资源包上传成功！响应内容:', responseText)
          
          // 上传成功，使用后端返回的host构建文件访问地址
          const fileUrl = `${signatureData.host}/${objectKey}`
          console.log('uploadResourceToOSS - 构建的文件URL:', fileUrl)
          
          resolve({
            url: fileUrl,
            success: true
          })
        } else {
          const errorText = xhr.responseText
          console.error('uploadResourceToOSS - 资源包上传失败，状态码:', xhr.status)
          console.error('uploadResourceToOSS - 响应文本:', errorText)
          reject(new Error(`资源包上传失败: HTTP ${xhr.status} - ${errorText}`))
        }
      })
      
      // 监听上传错误
      xhr.addEventListener('error', function() {
        console.error('uploadResourceToOSS - 上传过程中发生错误')
        reject(new Error('上传过程中发生错误'))
      })
      
      // 监听上传中止
      xhr.addEventListener('abort', function() {
        console.error('uploadResourceToOSS - 上传被中止')
        reject(new Error('上传被中止'))
      })
      
      // 发送请求
      xhr.open('POST', signatureData.host)
      xhr.send(formData)
    })
    
  } catch (error) {
    console.error('资源包上传失败:', error)
    throw new Error(`资源包上传失败: ${error.message}`)
  }
}

// 封面图片处理
const coverInput = ref(null)

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
  // 创建本地预览URL
  workflowForm.coverUrl = URL.createObjectURL(file)
  ElMessage.success('封面图片选择成功，将在提交时上传')
}

// 上传封面图片到OSS - 使用XMLHttpRequest，按照示例代码简化逻辑
const uploadCoverImageToOSS = async (file) => {
  try {
    console.log('开始上传封面图片:', file.name)
    
    // 获取用户ID并验证
    const userId = getUserId()
    console.log('uploadCoverImageToOSS - 获取到的userId:', userId)
    
    if (!userId) {
      throw new Error('无法获取用户ID，请重新登录')
    }
    
    // 使用POST签名方式上传
    const postSignatureResult = await getPostSignature({
      fileName: file.name,
      userId: userId
    })

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

    const signatureData = postSignatureResult.data
    console.log('uploadCoverImageToOSS - POST签名响应:', signatureData)

    // 创建FormData
    const formData = new FormData()
    
    // 使用后端返回的dir生成文件路径
    const objectKey = signatureData.dir + Date.now() + '_' + file.name
    
    console.log('uploadCoverImageToOSS - 使用COS策略中的路径:', objectKey)
    
    // COS POST 表单上传必需字段
    formData.append('key', objectKey)
    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'])
    
    // 添加文件 - 必须在最后添加，确保Content-Type正确
    formData.append('file', file)
    
    console.log('uploadCoverImageToOSS - FormData准备完成，开始上传到OSS')
    console.log('uploadCoverImageToOSS - 上传参数:', {
      key: objectKey,
      host: signatureData.host,
      fileSize: file.size,
      fileName: file.name
    })
    
    // 使用XMLHttpRequest上传到OSS
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest()
      
      // 监听上传进度
      xhr.upload.addEventListener('progress', function(e) {
        if (e.lengthComputable) {
          const percentComplete = (e.loaded / e.total) * 100
          coverUploadProgress.value = Math.round(percentComplete)
          coverUploadedBytes.value = Math.round(percentComplete * file.size)
          
          // 更新上传速度和时间
          updateCoverUploadSpeed()
          updateCoverUploadTime()
        }
      })
      
      // 监听上传完成
      xhr.addEventListener('load', function() {
        if (xhr.status >= 200 && xhr.status < 300) {
          const responseText = xhr.responseText
          console.log('uploadCoverImageToOSS - 封面上传成功！响应内容:', responseText)
          
          // 上传成功，使用后端返回的host构建文件访问地址
          const fileUrl = `${signatureData.host}/${objectKey}`
          console.log('uploadCoverImageToOSS - 构建的文件URL:', fileUrl)
          
          resolve({
            url: fileUrl,
            success: true
          })
        } else {
          const errorText = xhr.responseText
          console.error('uploadCoverImageToOSS - 封面上传失败，状态码:', xhr.status)
          console.error('uploadCoverImageToOSS - 响应文本:', errorText)
          reject(new Error(`封面上传失败: HTTP ${xhr.status} - ${errorText}`))
        }
      })
      
      // 监听上传错误
      xhr.addEventListener('error', function() {
        console.error('uploadCoverImageToOSS - 上传过程中发生错误')
        reject(new Error('上传过程中发生错误'))
      })
      
      // 监听上传中止
      xhr.addEventListener('abort', function() {
        console.error('uploadCoverImageToOSS - 上传被中止')
        reject(new Error('上传被中止'))
      })
      
      // 发送请求
      xhr.open('POST', signatureData.host)
      xhr.send(formData)
    })
    
  } catch (error) {
    console.error('uploadCoverImageToOSS - 封面上传失败:', error)
    throw new Error(`封面上传失败: ${error.message}`)
  }
}

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

// 视频处理
const videoInput = ref(null)
const videoPlayer = ref(null)
const selectedVideoFile = ref(null)
const videoPreviewUrl = ref('')
const videoDuration = ref('00:00')
const videoResolution = ref('未知')

const triggerVideoSelect = () => {
  videoInput.value?.click()
}

const handleVideoSelect = 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
  }

  // 保存文件引用，但不立即上传
  selectedVideoFile.value = file
  videoPreviewUrl.value = URL.createObjectURL(file)
  workflowForm.videoId = null // 清空之前的视频ID
  ElMessage.success('视频文件选择成功，将在提交时上传')
}

const handleVideoDrop = 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
      }

      selectedVideoFile.value = file
      videoPreviewUrl.value = URL.createObjectURL(file)
      workflowForm.videoId = null
      ElMessage.success('视频文件选择成功，将在提交时上传')
    } else {
      ElMessage.error('请选择有效的视频文件')
    }
  }
}

const clearVideo = () => {
  if (videoPreviewUrl.value) {
    URL.revokeObjectURL(videoPreviewUrl.value)
  }
  selectedVideoFile.value = null
  videoPreviewUrl.value = ''
  videoDuration.value = '00:00'
  videoResolution.value = '未知'
  workflowForm.videoId = null
  if (videoInput.value) {
    videoInput.value.value = ''
  }
}


// 上传视频到VOD
const uploadVideoToVOD = async (file) => {
  try {
    console.log('开始上传视频到VOD:', file.name)
    
    // 初始化视频上传进度状态
    videoUploadProgress.value = 0
    videoUploadSpeed.value = '0 KB/s'
    videoUploadTimeElapsed.value = 0
    videoUploadTimeRemaining.value = 0
    videoUploadedBytes.value = 0
    videoUploadStartTime.value = Date.now()
    videoLastUploadedBytes.value = 0
    videoUploadPaused.value = false
    
    // 检查阿里云SDK状态
    if (typeof window.AliyunUpload === 'undefined') {
      throw new Error('阿里云上传SDK未加载，请刷新页面重试')
    }

    // 初始化阿里云上传器
    await initAliyunUploader()
    
    // 添加文件到上传器
    uploader.addFile(file, null, null, null, null)
    
    // 开始上传
    uploader.startUpload()
    
    // 返回Promise，等待上传完成
    return new Promise((resolve, reject) => {
      // 保存resolve和reject，供回调函数使用
      uploader._resolve = resolve
      uploader._reject = reject
    })
    
  } 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) => {
          try {
            // 如果是断点续传，uploadInfo.videoId会有值
            if (!uploadInfo.videoId) {
              // 获取用户ID并验证
              const userId = getUserId()
              console.log('视频上传 - 获取到的userId:', userId)
              
              if (!userId) {
                throw new Error('无法获取用户ID，请重新登录')
              }
              
              // 新上传，调用创建上传凭证接口
              const authResult = await createUploadAuth({
                userId: userId,
                title: workflowForm.name || '工作流预览视频',
                description: workflowForm.description || '',
                cateId: '',
                coverUrl: '',
                fileName: selectedVideoFile.value.name,
                fileSize: selectedVideoFile.value.size
              })
              
              const { uploadAuth, uploadAddress, videoId } = authResult
              
              // 验证必要字段是否存在
              if (!uploadAuth || !uploadAddress || !videoId) {
                throw new Error('上传凭证缺少必要字段')
              }
              
              // 设置上传地址和凭证
              uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
            } else {
              // 断点续传，调用刷新上传凭证接口
              const refreshResult = await refreshUploadAuth({
                videoId: uploadInfo.videoId
              })
              
              const { uploadAuth, uploadAddress, videoId } = refreshResult
              
              // 验证必要字段是否存在
              if (!uploadAuth || !uploadAddress || !videoId) {
                throw new Error('刷新上传凭证缺少必要字段')
              }
              
              // 设置新的上传凭证继续上传
              uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
            }
          } catch (error) {
            console.error('获取上传凭证失败:', error)
            if (uploader._reject) {
              uploader._reject(error)
            }
          }
        },
        // 文件上传成功
        onUploadSucceed: (uploadInfo) => {
          console.log('视频上传成功:', uploadInfo.videoId)
          videoUploadProgress.value = 100
          videoUploadedBytes.value = selectedVideoFile.value.size
          videoUploadTimeElapsed.value = Math.floor((Date.now() - videoUploadStartTime.value) / 1000)
          videoUploadTimeRemaining.value = 0
          
          if (uploader._resolve) {
            uploader._resolve({
              videoId: uploadInfo.videoId,
              success: true
            })
          }
        },
        // 文件上传失败
        onUploadFailed: (uploadInfo, code, message) => {
          console.error('视频上传失败:', uploadInfo.file.name, 'code:', code, 'message:', message)
          if (uploader._reject) {
            uploader._reject(new Error(`视频上传失败: ${message}`))
          }
        },
        // 文件上传进度
        onUploadProgress: (uploadInfo, totalSize, progress) => {
          // 更新上传进度
          if (typeof progress === 'number' && progress >= 0 && progress <= 1) {
            videoUploadProgress.value = Math.round(progress * 100)
            videoUploadedBytes.value = Math.round(progress * totalSize)
            
            // 更新上传速度
            updateVideoUploadSpeed()
            
            // 更新上传时间
            updateVideoUploadTime()
          }
        },
        // 上传凭证过期
        onUploadTokenExpired: async (uploadInfo) => {
          console.log('上传凭证过期，正在刷新...')
          try {
            // 刷新上传凭证
            const refreshResult = await refreshUploadAuth({
              videoId: uploadInfo.videoId
            })

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

            const { uploadAuth } = refreshResult.data
            
            // 设置新的上传凭证继续上传
            uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadInfo.uploadAddress, uploadInfo.videoId)
          } catch (error) {
            console.error('刷新上传凭证失败:', error)
            if (uploader._reject) {
              uploader._reject(error)
            }
          }
        }
      })
      
      resolve()
    } catch (error) {
      reject(error)
    }
  })
}

// 更新视频上传速度
const updateVideoUploadSpeed = () => {
  const now = Date.now()
  const timeDiff = (now - videoUploadStartTime.value) / 1000
  const bytesDiff = videoUploadedBytes.value - videoLastUploadedBytes.value
  
  if (timeDiff > 0) {
    const speed = bytesDiff / timeDiff
    videoUploadSpeed.value = formatFileSize(speed) + '/s'
  }
  
  videoLastUploadedBytes.value = videoUploadedBytes.value
}

// 更新视频上传时间
const updateVideoUploadTime = () => {
  videoUploadTimeElapsed.value = Math.floor((Date.now() - videoUploadStartTime.value) / 1000)
  
  if (videoUploadProgress.value > 0) {
    const totalTime = videoUploadTimeElapsed.value / (videoUploadProgress.value / 100)
    videoUploadTimeRemaining.value = Math.max(0, Math.floor(totalTime - videoUploadTimeElapsed.value))
  }
}

// 暂停/继续视频上传
const toggleVideoUploadPause = () => {
  if (uploader) {
    if (videoUploadPaused.value) {
      uploader.resumeUpload()
      videoUploadPaused.value = false
    } else {
      uploader.pauseUpload()
      videoUploadPaused.value = true
    }
  }
}

// 取消视频上传
const cancelVideoUpload = () => {
  if (uploader) {
    uploader.cancelUpload()
    videoUploadProgress.value = 0
    videoUploadedBytes.value = 0
    videoUploadSpeed.value = '0 KB/s'
    videoUploadTimeElapsed.value = 0
    videoUploadTimeRemaining.value = 0
  }
}

// 格式化时间
const formatTime = (seconds) => {
  if (seconds < 60) {
    return `${seconds}秒`
  } else if (seconds < 3600) {
    const minutes = Math.floor(seconds / 60)
    const remainingSeconds = seconds % 60
    return `${minutes}分${remainingSeconds}秒`
  } else {
    const hours = Math.floor(seconds / 3600)
    const minutes = Math.floor((seconds % 3600) / 60)
    const remainingSeconds = seconds % 60
    return `${hours}小时${minutes}分${remainingSeconds}秒`
  }
}

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

// 视频预览相关
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('视频文件加载失败，请检查文件格式')
}

// 已移除 onUploadError（不再绑定 el-upload 的 on-error）

// 重置表单
const resetForm = () => {
  console.log('重置表单')
  
  // 清理上传器实例
  if (uploader) {
    try {
      uploader.cancelUpload()
    } catch (error) {
      console.error('清理上传器失败:', error)
    }
    uploader = null
  }
  
  // 清理封面图片预览URL
  if (workflowForm.coverUrl) {
    URL.revokeObjectURL(workflowForm.coverUrl)
  }
  
  // 清理视频预览URL
  if (videoPreviewUrl.value) {
    URL.revokeObjectURL(videoPreviewUrl.value)
  }
  
  Object.assign(workflowForm, {
    name: '',
    description: '',
    data: '',
    dataFileUrl: '',
    coverUrl: '',
    videoId: null,
    category: '',
    isFree: 0, // 默认收费
    isPublic: 1, // 默认公开，用户无法修改
    fullAccessRole: 2, // 默认VIP用户权限
    copyAccessRole: 2  // 默认VIP用户权限
  })
  
  // 重置提交结果状态
  submitResult.value = null
  showSubmitResultFlag.value = false
  
  // 重置文件相关状态
  coverFile.value = null
  resourceFile.value = null
  selectedVideoFile.value = null
  isUploadingCover.value = false
  isUploadingResource.value = false
  isUploadingVideo.value = false
  uploadProgress.value = 0
  overallUploadProgress.value = 0
  uploadStatus.value = ''
  uploadSteps.value = []
  currentUploadStep.value = 0
  
  
  // 重置OSS上传进度状态
  coverUploadProgress.value = 0
  coverUploadSpeed.value = '0 KB/s'
  coverUploadTimeElapsed.value = 0
  coverUploadTimeRemaining.value = 0
  coverUploadedBytes.value = 0
  coverUploadStartTime.value = 0
  coverLastUploadedBytes.value = 0
  
  resourceUploadProgress.value = 0
  resourceUploadSpeed.value = '0 KB/s'
  resourceUploadTimeElapsed.value = 0
  resourceUploadTimeRemaining.value = 0
  resourceUploadedBytes.value = 0
  resourceUploadStartTime.value = 0
  resourceLastUploadedBytes.value = 0
  
  // 重置视频上传进度状态
  videoUploadProgress.value = 0
  videoUploadSpeed.value = '0 KB/s'
  videoUploadTimeElapsed.value = 0
  videoUploadTimeRemaining.value = 0
  videoUploadedBytes.value = 0
  videoUploadStartTime.value = 0
  videoLastUploadedBytes.value = 0
  videoUploadPaused.value = false
  
  resourceFileList.value = []
  activeTab.value = 'json'
  currentStep.value = 1
  clearError()
  
  // 清理文件输入框
  if (coverInput.value) {
    coverInput.value.value = ''
  }
  if (videoInput.value) {
    videoInput.value.value = ''
  }
  
  console.log('表单重置完成，当前状态:', {
    data: workflowForm.data,
    dataFileUrl: workflowForm.dataFileUrl,
    activeTab: activeTab.value
  })
}

// 显示提交结果
const showSubmitResult = (workflowId) => {
  submitResult.value = {
    workflowId: workflowId,
    workflowName: workflowForm.name,
    submitTime: new Date().toLocaleString()
  }
  showSubmitResultFlag.value = true
  submitting.value = false
}

// 跳转到工作流列表
const goToWorkflowList = () => {
  // 这里可以跳转到工作流列表页面
  // 暂时使用路由跳转，如果没有路由配置，可以显示提示信息
  ElMessage.info('跳转到工作流列表功能待实现')
  // 重置表单，回到第1步
  resetForm()
}

// 清除错误信息
const clearError = () => {
  errorMessage.value = ''
}

// 获取分类标签
  const getCategoryLabel = (category) => {
    const categoryMap = {
      // Coze 平台
      'Coze-图像生成': 'Coze-图像生成',
      'Coze-文案生成': 'Coze-文案生成', 
      'Coze-视频生成': 'Coze-视频生成',
      'Coze-音频生成': 'Coze-音频生成',
      'Coze-代码生成': 'Coze-代码生成',
      'Coze-数据分析': 'Coze-数据分析',
      'Coze-自动化流程': 'Coze-自动化流程',
      
      // Dify 平台
      'Dify-图像生成': 'Dify-图像生成',
      'Dify-文案生成': 'Dify-文案生成',
      'Dify-视频生成': 'Dify-视频生成',
      'Dify-音频生成': 'Dify-音频生成',
      'Dify-代码生成': 'Dify-代码生成',
      'Dify-数据分析': 'Dify-数据分析',
      'Dify-自动化流程': 'Dify-自动化流程',
      
      // ComfyUI 平台
      'ComfyUI-图像生成': 'ComfyUI-图像生成',
      'ComfyUI-视频生成': 'ComfyUI-视频生成',
      'ComfyUI-图像编辑': 'ComfyUI-图像编辑',
      'ComfyUI-风格转换': 'ComfyUI-风格转换',
      'ComfyUI-批量处理': 'ComfyUI-批量处理',
      
      // 多平台集成
      '跨平台图像生成': '跨平台图像生成',
      '跨平台文案生成': '跨平台文案生成',
      '跨平台视频生成': '跨平台视频生成',
      '跨平台自动化': '跨平台自动化',
      
      // 通用功能
      '数据处理': '数据处理',
      '工作流模板': '工作流模板',
      '其他': '其他'
    }
    return categoryMap[category] || category
  }

// 检测视频编码是否为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 onFreeStatusChange = (value) => {
  if (value === 1) {
    // 免费：设置为普通用户权限
    workflowForm.fullAccessRole = 1
    workflowForm.copyAccessRole = 1
  } else {
    // 收费：设置为VIP用户权限
    workflowForm.fullAccessRole = 2
    workflowForm.copyAccessRole = 2
  }
  
  // 权限设置说明
  if (value === 1) {
    ElMessage.success('已设置为免费内容，所有普通用户均可查看和复制')
  } else {
    ElMessage.success('已设置为收费内容，默认VIP用户权限')
  }
}

// 提交工作流
const handleSubmitWorkflow = async () => {
  try {
    submitting.value = true
    clearError()
    
    // 检查是否有封面图片
    if (!coverFile.value) {
      throw new Error('请选择封面图片')
    }
    
    // 检查是否有工作流内容
    if (!workflowForm.data && !resourceFile.value) {
      throw new Error('请提供工作流内容（JSON数据或资源包文件）')
    }
    
    // 检查是否有视频文件
    if (!selectedVideoFile.value) {
      throw new Error('请选择预览视频')
    }
    
    // 初始化上传步骤
    initUploadSteps()
    
    // 先处理富文本中的base64图片，上传到OSS并替换链接
    uploadStatus.value = '正在处理富文本中的图片...'
    const processedDescription = await processDescriptionImages()
    workflowForm.description = processedDescription

    // 开始上传所有文件
    await uploadAllFiles()
    
    // 构建提交数据
    const submitData = {
      name: workflowForm.name,
      description: workflowForm.description,
      coverUrl: workflowForm.coverUrl,
      videoId: workflowForm.videoId,
      category: workflowForm.category,
      isFree: workflowForm.isFree,
      isPublic: workflowForm.isPublic,
      fullAccessRole: workflowForm.fullAccessRole,
      copyAccessRole: workflowForm.copyAccessRole
    }
    
    // 根据模式设置不同的字段
    if (activeTab.value === 'json') {
      // JSON模式：设置data字段
      submitData.data = workflowForm.data
    } else {
      // 文件模式：设置dataFileUrl字段
      submitData.dataFileUrl = workflowForm.dataFileUrl
    }
    
    console.log('提交工作流数据:', submitData)
    
    // 提交工作流
    const workflowResponse = await submitWorkflow(submitData)
    
    if (workflowResponse.code === 200) {
      ElMessage.success('工作流提交成功！')
      // 显示提交成功结果，而不是立即重置表单
      showSubmitResult(workflowResponse.data)
      
      // 提交成功后跳转到作品管理页面
      setTimeout(() => {
        router.push('/personal-center/publish?tab=manage')
      }, 2000) // 延迟2秒跳转，让用户看到成功消息
    } else {
      errorMessage.value = workflowResponse.message || '提交失败'
      ElMessage.error(errorMessage.value)
    }
  } catch (error) {
    console.error('Submit error:', error)
    errorMessage.value = error.message || '提交失败，请检查表单信息'
    ElMessage.error(errorMessage.value)
  } finally {
    submitting.value = false
  }
}

// 初始化上传步骤
const initUploadSteps = () => {
  uploadSteps.value = []
  currentUploadStep.value = 0
  overallUploadProgress.value = 0
  
  // 添加需要上传的文件步骤
  if (coverFile.value) {
    uploadSteps.value.push({
      name: '封面图片',
      file: coverFile.value,
      type: 'cover'
    })
  }
  
  if (resourceFile.value) {
    uploadSteps.value.push({
      name: '资源包文件',
      file: resourceFile.value,
      type: 'resource'
    })
  }
  
  if (selectedVideoFile.value) {
    uploadSteps.value.push({
      name: '预览视频',
      file: selectedVideoFile.value,
      type: 'video'
    })
  }
  
}

// 上传所有文件
const uploadAllFiles = async () => {
  if (uploadSteps.value.length === 0) {
    return
  }
  
  let coverProgressInterval = null
  let resourceProgressInterval = null
  
  for (let i = 0; i < uploadSteps.value.length; i++) {
    const step = uploadSteps.value[i]
    currentUploadStep.value = i
    
    try {
      uploadStatus.value = `正在上传${step.name}...`
      
      let uploadResult
      switch (step.type) {
        case 'cover':
          isUploadingCover.value = true
          coverProgressInterval = startCoverUploadProgress()
          
          uploadResult = await uploadCoverImageToOSS(step.file)
          
          // 清除进度模拟并设置为100%
          if (coverProgressInterval) {
            clearInterval(coverProgressInterval)
            coverProgressInterval = null
          }
          coverUploadProgress.value = 100
          coverUploadedBytes.value = step.file.size
          
          if (uploadResult.success) {
            workflowForm.coverUrl = uploadResult.url
          }
          isUploadingCover.value = false
          break
          
        case 'resource':
          isUploadingResource.value = true
          resourceProgressInterval = startResourceUploadProgress()
          
          uploadResult = await uploadResourceToOSS(step.file)
          
          // 清除进度模拟并设置为100%
          if (resourceProgressInterval) {
            clearInterval(resourceProgressInterval)
            resourceProgressInterval = null
          }
          resourceUploadProgress.value = 100
          resourceUploadedBytes.value = step.file.size
          
          if (uploadResult.success) {
            workflowForm.dataFileUrl = uploadResult.url
          }
          isUploadingResource.value = false
          break
          
        case 'video':
          isUploadingVideo.value = true
          uploadResult = await uploadVideoToVOD(step.file)
          if (uploadResult.success) {
            workflowForm.videoId = uploadResult.videoId // 使用VOD返回的videoId
          }
          isUploadingVideo.value = false
          break
          
      }
      
      if (!uploadResult.success) {
        throw new Error(`${step.name}上传失败`)
      }
      
    } catch (error) {
      console.error(`${step.name}上传失败:`, error)
      
      // 清理进度模拟
      if (coverProgressInterval) {
        clearInterval(coverProgressInterval)
        coverProgressInterval = null
      }
      if (resourceProgressInterval) {
        clearInterval(resourceProgressInterval)
        resourceProgressInterval = null
      }
      
      // 重置上传状态
      if (step.type === 'cover') {
        isUploadingCover.value = false
      } else if (step.type === 'resource') {
        isUploadingResource.value = false
      } else if (step.type === 'video') {
        isUploadingVideo.value = false
      }
      
      throw new Error(`${step.name}上传失败: ${error.message}`)
    }
  }
  
  uploadStatus.value = '所有文件上传完成'
}

// 获取用户ID
const getUserId = () => {
  console.log('WorkflowUploadComponent: getUserId被调用，当前userInfo:', userInfo.value)
  
  if (!userInfo.value) {
    console.log('WorkflowUploadComponent: 用户信息为空，尝试更新用户信息')
    // 尝试更新用户信息
    updateUserInfo()
    return ''
  }
  
  const userId = userInfo.value.id || ''
  console.log('WorkflowUploadComponent: 获取到的用户ID:', userId)
  return userId
}

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

// 组件挂载后的初始化
onMounted(async () => {
  console.log('WorkflowUploadComponent: 组件挂载，开始初始化')
  
  // 检查用户信息是否存在
  if (!userInfo.value) {
    console.log('WorkflowUploadComponent: 用户信息不存在，开始获取')
    await updateUserInfo()
  } else {
    console.log('WorkflowUploadComponent: 用户信息已存在:', userInfo.value)
  }
  
  await loadCategories()
})

// 组件卸载时的清理
onUnmounted(() => {
  // 清理上传器实例
  if (uploader) {
    try {
      uploader.cancelUpload()
    } catch (error) {
      console.error('清理上传器失败:', error)
    }
    uploader = null
  }
  
  // 清理预览URL
  if (workflowForm.coverUrl) {
    URL.revokeObjectURL(workflowForm.coverUrl)
  }
  if (videoPreviewUrl.value) {
    URL.revokeObjectURL(videoPreviewUrl.value)
  }
})

// OSS上传进度模拟和状态更新
const startCoverUploadProgress = () => {
  coverUploadProgress.value = 0
  coverUploadSpeed.value = '0 KB/s'
  coverUploadTimeElapsed.value = 0
  coverUploadTimeRemaining.value = 0
  coverUploadedBytes.value = 0
  coverUploadStartTime.value = Date.now()
  coverLastUploadedBytes.value = 0
  
  // 模拟上传进度
  const progressInterval = setInterval(() => {
    if (coverUploadProgress.value < 90) {
      coverUploadProgress.value += Math.random() * 8 + 2
      coverUploadedBytes.value = Math.round((coverUploadProgress.value / 100) * (coverFile.value?.size || 0))
      updateCoverUploadSpeed()
      updateCoverUploadTime()
    }
  }, 200)
  
  return progressInterval
}

const startResourceUploadProgress = () => {
  resourceUploadProgress.value = 0
  resourceUploadSpeed.value = '0 KB/s'
  resourceUploadTimeElapsed.value = 0
  resourceUploadTimeRemaining.value = 0
  resourceUploadedBytes.value = 0
  resourceUploadStartTime.value = Date.now()
  resourceLastUploadedBytes.value = 0
  
  // 模拟上传进度
  const progressInterval = setInterval(() => {
    if (resourceUploadProgress.value < 90) {
      resourceUploadProgress.value += Math.random() * 6 + 1
      resourceUploadedBytes.value = Math.round((resourceUploadProgress.value / 100) * (resourceFile.value?.size || 0))
      updateResourceUploadSpeed()
      updateResourceUploadTime()
    }
  }, 300)
  
  return progressInterval
}

// 更新封面上传速度
const updateCoverUploadSpeed = () => {
  const now = Date.now()
  const timeDiff = (now - coverUploadStartTime.value) / 1000
  const bytesDiff = coverUploadedBytes.value - coverLastUploadedBytes.value
  
  if (timeDiff > 0) {
    const speed = bytesDiff / timeDiff
    coverUploadSpeed.value = formatFileSize(speed) + '/s'
  }
  
  coverLastUploadedBytes.value = coverUploadedBytes.value
}

// 更新封面上传时间
const updateCoverUploadTime = () => {
  coverUploadTimeElapsed.value = Math.floor((Date.now() - coverUploadStartTime.value) / 1000)
  
  if (coverUploadProgress.value > 0) {
    const totalTime = coverUploadTimeElapsed.value / (coverUploadProgress.value / 100)
    coverUploadTimeRemaining.value = Math.max(0, Math.floor(totalTime - coverUploadTimeElapsed.value))
  }
}

// 更新资源包上传速度
const updateResourceUploadSpeed = () => {
  const now = Date.now()
  const timeDiff = (now - resourceUploadStartTime.value) / 1000
  const bytesDiff = resourceUploadedBytes.value - resourceLastUploadedBytes.value
  
  if (timeDiff > 0) {
    const speed = bytesDiff / timeDiff
    resourceUploadSpeed.value = formatFileSize(speed) + '/s'
  }
  
  resourceLastUploadedBytes.value = resourceUploadedBytes.value
}

// 更新资源包上传时间
const updateResourceUploadTime = () => {
  resourceUploadTimeElapsed.value = Math.floor((Date.now() - resourceUploadStartTime.value) / 1000)
  
  if (resourceUploadProgress.value > 0) {
    const totalTime = resourceUploadTimeElapsed.value / (resourceUploadProgress.value / 100)
    resourceUploadTimeRemaining.value = Math.max(0, Math.floor(totalTime - resourceUploadTimeElapsed.value))
  }
}
</script>

<style scoped>
.workflow-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: 20px;
  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: 30px;
  padding: 0;
}

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

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

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

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

.form-group {
  margin-bottom: 0;
}

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

/* 工作流标签页 */
.workflow-tabs {
  margin-bottom: 20px;
}

.content-tabs {
  margin-bottom: 20px;
}

.form-tip {
  display: flex;
  align-items: center;
  margin-top: 8px;
  color: #909399;
  font-size: 12px;
}

.form-tip .el-icon {
  margin-right: 4px;
  font-size: 14px;
}

.form-warning {
  display: flex;
  align-items: center;
  margin-top: 8px;
  color: #e6a23c;
  font-size: 12px;
}

.form-warning .el-icon {
  margin-right: 4px;
  font-size: 14px;
}

.form-success {
  display: flex;
  align-items: center;
  margin-top: 8px;
  color: #67c23a;
  font-size: 12px;
}

.form-success .el-icon {
  margin-right: 4px;
  font-size: 14px;
}

.debug-info {
  margin-top: 8px;
  padding: 8px;
  background: #f5f7fa;
  border-radius: 4px;
  font-size: 11px;
  color: #909399;
}

.upload-demo {
  width: 100%;
}

/* 封面上传区域 */
.cover-upload-area {
  border: 2px dashed #ddd;
  border-radius: 8px;
  overflow: hidden;
  transition: all 0.3s;
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

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

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

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

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

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

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

.cover-preview {
  position: relative;
  text-align: center;
  width: 100%;
  height: 100%;
}

.cover-actions {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  gap: 8px;
  z-index: 10;
  
  padding: 4px;
  border-radius: 6px;

}

/* 视频上传区域 */
.video-upload-area {
  border: 2px dashed #ddd;
  border-radius: 8px;
  overflow: hidden;
  transition: all 0.3s;
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

.video-upload-area:hover {
  border-color: #409eff;
}

.video-upload-placeholder {
  padding: 40px 30px;
  text-align: center;
  cursor: pointer;
  background: #fafafa;
  width: 100%;
}

.video-upload-icon {
  font-size: 32px;
  color: #409eff;
  margin-bottom: 12px;
}

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

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

/* 视频预览容器 */
.video-preview-container {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 8px;
  overflow: hidden;
}

.video-preview-container .video-player {
  width: 100%;
  height: 100%;
  background: #000;
  object-fit: cover;
}

.video-overlay {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 10;
  pointer-events: none;
}

.video-actions {
  display: flex;
  gap: 8px;
  pointer-events: auto;
  
  padding: 4px;
  border-radius: 6px;

}

/* 步骤操作按钮 */
.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;
}

.step-actions {
  display: flex;
  justify-content: space-between;
  margin-top: 30px;
}

/* 公开状态样式 */
.public-status {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

.status-hint {
  color: #909399;
  font-size: 12px;
  font-style: italic;
}

/* 权限提示样式 */
.permission-hint {
  display: flex;
  align-items: center;
  margin-top: 8px;
  color: #909399;
  font-size: 12px;
}

.permission-hint .el-icon {
  margin-right: 4px;
  font-size: 14px;
}

/* 信息摘要 */
.summary-section {
  background: #f8f9fa;
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 30px;
}

.summary-section h4 {
  margin: 0 0 20px 0;
  color: #333;
  font-size: 18px;
  font-weight: 600;
}

.summary-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 15px;
}

.summary-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.summary-label {
  color: #666;
  font-size: 14px;
  min-width: 80px;
  font-weight: 500;
}

.summary-value {
  color: #333;
  font-size: 14px;
  flex: 1;
  word-break: break-word;
}

/* 富文本描述内容样式 */
.summary-item-description {
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  grid-column: 1 / -1; /* 占据整个网格宽度 */
}

.summary-description-content {
  width: 100%;
  max-height: 300px;
  overflow-y: auto;
  padding: 16px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  background: #fff;
  line-height: 1.7;
  font-size: 14px;
  color: #333;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* 自定义滚动条样式 */
.summary-description-content::-webkit-scrollbar {
  width: 6px;
}

.summary-description-content::-webkit-scrollbar-track {
  background: #f1f5f9;
  border-radius: 3px;
}

.summary-description-content::-webkit-scrollbar-thumb {
  background: #cbd5e1;
  border-radius: 3px;
  transition: background 0.2s ease;
}

.summary-description-content::-webkit-scrollbar-thumb:hover {
  background: #94a3b8;
}

/* 富文本内容样式 */
.summary-description-content :deep(h1),
.summary-description-content :deep(h2),
.summary-description-content :deep(h3),
.summary-description-content :deep(h4),
.summary-description-content :deep(h5),
.summary-description-content :deep(h6) {
  margin: 10px 0 8px 0;
  font-weight: 600;
  line-height: 1.4;
}

.summary-description-content :deep(h1) { font-size: 20px; color: #1f2937; }
.summary-description-content :deep(h2) { font-size: 18px; color: #1f2937; }
.summary-description-content :deep(h3) { font-size: 16px; color: #374151; }
.summary-description-content :deep(h4) { font-size: 15px; color: #374151; }
.summary-description-content :deep(h5) { font-size: 14px; color: #4b5563; }
.summary-description-content :deep(h6) { font-size: 13px; color: #4b5563; }

.summary-description-content :deep(p) {
  margin: 8px 0;
  line-height: 1.7;
  color: #374151;
}

.summary-description-content :deep(p:first-child) {
  margin-top: 0;
}

.summary-description-content :deep(p:last-child) {
  margin-bottom: 0;
}

.summary-description-content :deep(strong) {
  font-weight: 600;
  color: #1f2937;
}

.summary-description-content :deep(em) {
  font-style: italic;
  color: #4b5563;
}

.summary-description-content :deep(u) {
  text-decoration: underline;
  text-decoration-color: #6b7280;
}

.summary-description-content :deep(s) {
  text-decoration: line-through;
  color: #9ca3af;
}

.summary-description-content :deep(ul),
.summary-description-content :deep(ol) {
  margin: 12px 0;
  padding-left: 24px;
  color: #374151;
}

.summary-description-content :deep(li) {
  margin: 6px 0;
  line-height: 1.7;
}

.summary-description-content :deep(ul li) {
  list-style-type: disc;
}

.summary-description-content :deep(ol li) {
  list-style-type: decimal;
}

.summary-description-content :deep(blockquote) {
  margin: 16px 0;
  padding: 12px 16px;
  border-left: 4px solid #3b82f6;
  background: #f8fafc;
  font-style: italic;
  color: #475569;
  border-radius: 0 6px 6px 0;
}

.summary-description-content :deep(code) {
  padding: 3px 6px;
  background: #f1f5f9;
  border: 1px solid #e2e8f0;
  border-radius: 4px;
  font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
  font-size: 85%;
  color: #dc2626;
}

.summary-description-content :deep(pre) {
  margin: 16px 0;
  padding: 16px;
  background: #1f2937;
  color: #f9fafb;
  border-radius: 8px;
  overflow-x: auto;
  font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
  font-size: 13px;
  line-height: 1.5;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.summary-description-content :deep(pre code) {
  background: transparent;
  border: none;
  padding: 0;
  color: inherit;
  font-size: inherit;
}

.summary-description-content :deep(img) {
  max-width: 100%;
  height: auto;
  margin: 16px 0;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border: 1px solid #e5e7eb;
}

.summary-description-content :deep(a) {
  color: #3b82f6;
  text-decoration: none;
  font-weight: 500;
  transition: color 0.2s ease;
}

.summary-description-content :deep(a:hover) {
  color: #1d4ed8;
  text-decoration: underline;
}

/* 表格样式 */
.summary-description-content :deep(table) {
  width: 100%;
  border-collapse: collapse;
  margin: 16px 0;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  overflow: hidden;
}

.summary-description-content :deep(th),
.summary-description-content :deep(td) {
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid #e5e7eb;
}

.summary-description-content :deep(th) {
  background: #f9fafb;
  font-weight: 600;
  color: #374151;
}

.summary-description-content :deep(tr:last-child td) {
  border-bottom: none;
}

.summary-description-content :deep(tr:nth-child(even)) {
  background: #f9fafb;
}

/* 分割线样式 */
.summary-description-content :deep(hr) {
  margin: 20px 0;
  border: none;
  height: 1px;
  background: linear-gradient(to right, transparent, #d1d5db, transparent);
}

/* 错误提示 */
.error-alert {
  margin-top: 20px;
}

/* 文件选择状态提示 */
.file-selected-tip {
  margin-top: 15px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
  border: 1px solid #e9ecef;
}

.file-info {
  font-size: 13px;
  color: #666;
  margin-top: 4px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .workflow-upload-container {
    padding: 15px;
    margin: 10px;
  }
  
  .form-row {
    grid-template-columns: 1fr;
    gap: 0;
  }
  
  .step-indicator {
    flex-direction: column;
    gap: 10px;
  }
  
  .step-line {
    width: 60px;
    height: 2px;
    top: 0;
    transform: rotate(90deg);
  }
  
  .summary-grid {
    grid-template-columns: 1fr;
  }
  
  .step-content {
    padding: 15px;
  }

  .upload-info {
    flex-direction: column;
    gap: 8px;
    align-items: flex-start;
  }
  
  .file-url {
    font-size: 11px;
  }
}

@media (max-width: 480px) {
  .workflow-upload-container {
    padding: 10px;
    margin: 5px;
  }
  
  .step-indicator {
    padding: 15px 0;
  }
  
  .step-circle {
    width: 50px;
    height: 50px;
  }
  
  .step-number {
    font-size: 18px;
  }
  
  .step-content {
    padding: 10px;
  }
}

/* 上传进度显示 */
.upload-progress-section {
  margin-top: 20px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border: 1px solid #ebeef5;
}

.upload-progress-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.upload-progress-header h4 {
  margin: 0;
  color: #333;
  font-size: 18px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.upload-progress-header .el-icon {
  font-size: 20px;
  color: #409eff;
}

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

.overall-progress {
  margin-bottom: 15px;
}

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

.progress-info .progress-text {
  font-weight: 600;
  color: #409eff;
}

.progress-bar {
  height: 8px;
  border-radius: 4px;
  background-color: #ebeef5;
  overflow: hidden;
}

.progress-bar .el-progress-bar__outer {
  background-color: #409eff;
  border-radius: 4px;
  transition: width 0.6s ease;
}

.step-progress {
  margin-top: 15px;
}

.step-progress-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 14px;
  color: #666;
}

.step-progress-header .el-icon {
  font-size: 16px;
  color: #67c23a;
}

.step-progress-bar {
  height: 6px;
  border-radius: 3px;
  background-color: #ebeef5;
  overflow: hidden;
}

.step-progress-bar .el-progress-bar__outer {
  background-color: #67c23a;
  border-radius: 3px;
  transition: width 0.6s ease;
}

.upload-steps-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 15px;
}

.upload-step-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 15px;
  background: #f0f9eb;
  border-radius: 8px;
  border: 1px solid #e1f3d8;
}

.upload-step-item .step-icon {
  font-size: 20px;
  color: #67c23a;
}

.upload-step-item.completed .step-icon {
  color: #67c23a;
}

.upload-step-item.current .step-icon {
  color: #409eff;
}

.upload-step-item.pending .step-icon {
  color: #909399;
}

.step-name {
  font-size: 14px;
  color: #333;
  font-weight: 500;
  flex: 1;
}
/* 全屏上传遮罩层（参考课程组件样式） */
.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: #8cc5ff; 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; }


.step-status {
  font-size: 12px;
  color: #909399;
  font-weight: 400;
}

.upload-step-item.completed .step-status {
  color: #67c23a;
}

.upload-step-item.current .step-status {
  color: #409eff;
}

.upload-step-item.pending .step-status {
  color: #909399;
}

/* 视频上传进度条 */
.video-upload-progress {
  margin-top: 20px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border: 1px solid #ebeef5;
}

.video-upload-progress .progress-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.video-upload-progress .progress-header h4 {
  margin: 0;
  color: #333;
  font-size: 18px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.video-upload-progress .progress-header .el-icon {
  font-size: 20px;
  color: #409eff;
}

.video-upload-progress .upload-status {
  font-size: 14px;
  color: #666;
  font-weight: 500;
}

.video-upload-progress .progress-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 14px;
  color: #666;
}

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

.video-upload-progress .progress-text {
  font-weight: 600;
  color: #409eff;
  font-size: 16px;
}

.video-upload-progress .progress-speed {
  font-size: 14px;
  color: #909399;
}

.video-upload-progress .progress-time {
  font-size: 14px;
  color: #909399;
}

.video-upload-progress .progress-details {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 15px;
  padding-top: 10px;
  border-top: 1px solid #ebeef5;
}

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

.video-upload-progress .file-name {
  font-size: 14px;
  color: #333;
  font-weight: 500;
}

.video-upload-progress .upload-controls {
  display: flex;
  gap: 8px;
}

/* 提交结果显示 */
.submit-result-section {
  margin-top: 20px;
  padding: 25px;
  background: #f0f9ff;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border: 2px solid #67c23a;
}

.submit-result-section .result-header {
  text-align: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 2px solid #67c23a;
}

.submit-result-section .result-header h4 {
  margin: 0;
  color: #67c23a;
  font-size: 20px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.submit-result-section .result-header .el-icon {
  font-size: 24px;
  color: #67c23a;
}

.submit-result-section .result-content {
  margin-bottom: 25px;
}

.submit-result-section .result-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid #e1f3d8;
}

.submit-result-section .result-item:last-child {
  border-bottom: none;
}

.submit-result-section .result-label {
  font-weight: 600;
  color: #333;
  font-size: 16px;
}

.submit-result-section .result-value {
  color: #67c23a;
  font-size: 16px;
  font-weight: 500;
}

.submit-result-section .result-actions {
  display: flex;
  justify-content: center;
  gap: 15px;
}

/* 封面图片OSS上传进度条 */
.cover-upload-progress {
  margin-top: 20px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border: 1px solid #ebeef5;
}

.cover-upload-progress .progress-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.cover-upload-progress .progress-header h4 {
  margin: 0;
  color: #333;
  font-size: 18px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.cover-upload-progress .progress-header .el-icon {
  font-size: 20px;
  color: #409eff;
}

.cover-upload-progress .upload-status {
  font-size: 14px;
  color: #666;
  font-weight: 500;
}

.cover-upload-progress .progress-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 14px;
  color: #666;
}

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

.cover-upload-progress .progress-text {
  font-weight: 600;
  color: #409eff;
  font-size: 16px;
}

.cover-upload-progress .progress-speed {
  font-size: 14px;
  color: #909399;
}

.cover-upload-progress .progress-time {
  font-size: 14px;
  color: #909399;
}

.cover-upload-progress .progress-details {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 15px;
  padding-top: 10px;
  border-top: 1px solid #ebeef5;
}

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

.cover-upload-progress .file-name {
  font-size: 14px;
  color: #333;
  font-weight: 500;
}

/* 资源包OSS上传进度条 */
.resource-upload-progress {
  margin-top: 20px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border: 1px solid #ebeef5;
}

.resource-upload-progress .progress-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.resource-upload-progress .progress-header h4 {
  margin: 0;
  color: #333;
  font-size: 18px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.resource-upload-progress .progress-header .el-icon {
  font-size: 20px;
  color: #409eff;
}

.resource-upload-progress .upload-status {
  font-size: 14px;
  color: #666;
  font-weight: 500;
}

.resource-upload-progress .progress-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 14px;
  color: #666;
}

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

.resource-upload-progress .progress-text {
  font-weight: 600;
  color: #409eff;
  font-size: 16px;
}

.resource-upload-progress .progress-speed {
  font-size: 14px;
  color: #909399;
}

.resource-upload-progress .progress-time {
  font-size: 14px;
  color: #909399;
}

.resource-upload-progress .progress-details {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 15px;
  padding-top: 10px;
  border-top: 1px solid #ebeef5;
}

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

.resource-upload-progress .file-name {
  font-size: 14px;
  color: #333;
  font-weight: 500;
}

.leave-page-warning {
  margin-bottom: 20px;
}

.warning-alert {
  background-color: #fdf6ec;
  border-color: #fae3b0;
}

.warning-content {
  color: #63491e;
}

.warning-tips {
  color: #908e8c;
  font-size: 12px;
}


/* 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;
}

/* 响应式设计 */
</style>