<template>
  <!-- 课程详情滑块组件 -->
  <el-drawer
    v-model="visible"
    size="1200px"
    direction="rtl"
    :close-on-click-modal="true"
    :destroy-on-close="true"
    @closed="handleClose"
    class="course-detail-drawer"
  >
    <!-- 自定义头部：标题简洁明了 -->
    <template #header>
      <div class="ep-detail-header">
        <span>作品详情</span>
      </div>
    </template>

    <!-- 加载态：骨架屏 -->
    <div v-if="detailLoading">
      <el-skeleton animated :rows="6" />
    </div>

    <!-- 错误态：结果面板 + 重试按钮 -->
    <el-result
      v-else-if="detailError"
      icon="warning"
      title="加载失败"
      :sub-title="detailError"
    >
      <template #extra>
        <el-button type="primary" @click="retryLoadDetail">重试</el-button>
      </template>
    </el-result>

    <!-- 详情内容 -->
    <div v-else-if="workDetail" class="ep-detail-body">
      <!-- 编辑模式 -->
      <div v-if="isEditing" class="edit-mode">
        <el-form :model="editForm" label-width="100px" label-position="left">
          <!-- 基本信息编辑 -->
          <el-row :gutter="20">
            <el-col :span="16">
              <el-form-item label="课程标题" required>
                <el-input v-model="editForm.title" placeholder="请输入课程标题" maxlength="128" show-word-limit />
              </el-form-item>
              
              
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="分类">
                    <el-select 
                      v-model="editForm.category" 
                      placeholder="请选择分类" 
                      style="width: 100%"
                      :loading="categoriesLoading"
                      :disabled="categoriesLoading"
                    >
                      <el-option 
                        v-for="category in courseCategories" 
                        :key="category.value" 
                        :label="category.label" 
                        :value="category.value" 
                      />
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="是否免费">
                    <el-select v-model="editForm.isFree" placeholder="请选择" style="width: 100%">
                      <el-option label="免费" :value="true" />
                      <el-option label="付费" :value="false" />
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>
              
              <el-row :gutter="20" v-if="!editForm.isFree">
                <el-col :span="12">
                  <el-form-item label="价格">
                    <el-input-number v-model="editForm.price" :min="0" :precision="2" style="width: 100%" />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="用户级别">
                    <el-input-number v-model="editForm.level" :min="1" :max="10" style="width: 100%" />
                  </el-form-item>
                </el-col>
              </el-row>
            </el-col>
            
            <el-col :span="8">
              <el-form-item label="课程封面">
                <div class="edit-cover-upload">
                  <div v-if="!editCoverFile && !editCoverPreviewUrl" class="cover-upload-placeholder" @click="triggerEditCoverSelect">
                    <p>点击上传新封面</p>
                    <p class="cover-hint">支持 JPG、PNG</p>
                  </div>
                  <div v-else class="cover-preview">
                    <img :src="editCoverPreviewUrl || editForm.coverUrl" alt="封面预览" class="cover-image" />
                    <div class="cover-actions">
                      <el-button @click="triggerEditCoverSelect" size="small">更换</el-button>
                      <el-button @click="clearEditCover" size="small" type="danger">删除</el-button>
                    </div>
                  </div>
                  <input ref="editCoverInput" type="file" accept="image/*" @change="handleEditCoverSelect" style="display: none" />
                </div>
              </el-form-item>
            </el-col>
          </el-row>
          
          <!-- 章节编辑 -->
          <el-divider>章节管理</el-divider>
          <div class="chapter-edit-section">
            <div class="chapter-actions">
              <el-button type="primary" @click="addEditChapter">添加章节</el-button>
            </div>
            
            <div class="edit-chapters" v-if="editForm.chapters.length">
              <el-card v-for="(chapter, cIndex) in editForm.chapters" :key="chapter.tempId || chapter.id" class="chapter-edit-card">
                <template #header>
                  <div class="chapter-edit-header">
                    <span class="chapter-index">第 {{ cIndex + 1 }} 章</span>
                    <el-input v-model="chapter.title" placeholder="章节标题" style="margin: 0 10px; flex: 1" />
                    <el-button size="small" type="danger" @click="removeEditChapter(cIndex)">删除</el-button>
                  </div>
                </template>
                
                <div class="chapter-edit-content">
                  
                  
                  <!-- 视频管理 -->
                  <div class="videos-section">
                    <div class="videos-header">
                      <h4>视频列表</h4>
                      <el-button size="small" type="primary" @click="addEditVideo(cIndex)">添加视频</el-button>
                    </div>
                    
                    <div v-if="chapter.videos && chapter.videos.length" class="edit-videos">
                      <el-card v-for="(video, vIndex) in chapter.videos" :key="video.tempId || video.id" class="video-edit-card" shadow="never">
                        <div class="video-edit-content">
                          <div class="video-edit-header">
                            <span class="video-index">视频 {{ cIndex + 1 }}-{{ vIndex + 1 }}</span>
                            <el-button size="small" type="danger" @click="removeEditVideo(cIndex, vIndex)">删除</el-button>
                          </div>
                          
                          <el-form-item label="视频标题" required>
                            <el-input v-model="video.title" placeholder="请输入视频标题" maxlength="128" show-word-limit />
                          </el-form-item>
                          
                          <el-row :gutter="20">
                            <el-col :span="12">
                              <el-form-item label="新视频文件">
                                <div class="video-upload-area">
                                  <div v-if="!video.newFile" class="video-upload-placeholder" @click="() => triggerEditVideoSelect(cIndex, vIndex)">
                                    <p>点击上传新视频</p>
                                    <p class="upload-hint">支持 MP4、AVI、MOV</p>
                                  </div>
                                  <div v-else class="video-preview-container">
                                    <video 
                                      v-if="video.previewUrl" 
                                      :src="video.previewUrl" 
                                      class="video-preview-element"
                                      controls
                                      preload="metadata"
                                    >
                                      您的浏览器不支持视频预览
                                    </video>
                                    <div class="video-preview-overlay">
                                      <p class="video-name">{{ video.newFile.name }}</p>
                                      <div class="video-actions">
                                        <el-button @click="() => triggerEditVideoSelect(cIndex, vIndex)" size="small">更换</el-button>
                                        <el-button @click="() => clearEditVideo(cIndex, vIndex)" size="small" type="danger">删除</el-button>
                                      </div>
                                    </div>
                                  </div>
                                  <input :ref="el => setEditVideoInputRef(cIndex, vIndex, el)" type="file" accept="video/*" @change="(e) => handleEditVideoSelect(cIndex, vIndex, e)" style="display: none" />
                                </div>
                              </el-form-item>
                            </el-col>
                            <el-col :span="12">
                              <el-form-item label="视频时长">
                                <div class="duration-display">
                                  <span v-if="video.durationSec > 0" class="duration-value">
                                    {{ formatDuration(video.durationSec) }} ({{ video.durationSec }}秒)
                                  </span>
                                  <span v-else class="duration-placeholder">
                                    {{ video.newFile ? '正在分析视频时长...' : '请选择或更换视频' }}
                                  </span>
                                </div>
                              </el-form-item>
                            </el-col>
                          </el-row>
                        </div>
                      </el-card>
                    </div>
                  </div>
                </div>
              </el-card>
            </div>
          </div>
          
          <!-- 课程描述编辑 -->
          <el-divider>课程描述</el-divider>
          <div class="description-editor-container">
            <QuillEditor 
              v-model:content="editForm.description" 
              content-type="html"
              placeholder="请输入课程描述"
              :options="quillOptions"
              style="height: 400px;"
            />
          </div>

        </el-form>
      </div>
      
      <!-- 查看模式（原有内容） -->
      <div v-else class="view-mode">
        <!-- 顶部：封面 + 标题描述 -->
        <el-row :gutter="16">
          <el-col :span="8">
            <el-image
              v-if="workDetail.coverUrl"
              :src="workDetail.coverUrl"
              fit="cover"
              class="ep-cover"
              :preview-src-list="[workDetail.coverUrl]"
            />
          </el-col>
          <el-col :span="16">
            <div class="ep-title">{{ workDetail.title || '未命名作品' }}</div>

            <!-- 课程特有字段（费用使用 isFree：true=收费，false=免费） -->
            <el-card shadow="never" class="ep-section">
              <template #header>
                <div class="ep-section-title">课程信息</div>
              </template>
              <el-descriptions :column="3" border>
                <el-descriptions-item label="是否收益" v-if="workDetail.isFree !== undefined">
                  <el-tag :type="isPaid ? 'danger' : 'success'">
                    {{ isPaid ? '收费' : '免费' }}
                  </el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="时长" v-if="workDetail.duration">
                  {{ workDetail.duration }}
                </el-descriptions-item>
              </el-descriptions>
            </el-card>
          </el-col>
        </el-row>

        <!-- 基础元信息 -->
        <el-card shadow="never" class="ep-section">
          <el-descriptions :column="3" border>
            <el-descriptions-item label="分类">
              {{ workDetail.category || '-' }}
            </el-descriptions-item>
              <el-descriptions-item label="审核状态">
                {{ formatAuditStatus(detailAuditStatus) }}
              </el-descriptions-item>
              <el-descriptions-item label="拒绝原因" v-if="Number(detailAuditStatus) === 2 && detailRejectReason" :span="3">
                <span class="reject-reason">{{ detailRejectReason }}</span>
              </el-descriptions-item>
              <el-descriptions-item label="审核时间" v-if="detailReviewTime">
                {{ formatTime(detailReviewTime) }}
              </el-descriptions-item>
            <el-descriptions-item label="创建时间" v-if="workDetail.createTime">
              {{ formatTime(workDetail.createTime) }}
            </el-descriptions-item>
            <el-descriptions-item label="更新时间" v-if="workDetail.updateTime">
              {{ formatTime(workDetail.updateTime) }}
            </el-descriptions-item>
            <el-descriptions-item label="标签" v-if="workDetail.tags && workDetail.tags.length">
              <el-space wrap>
                <el-tag v-for="tag in workDetail.tags" :key="tag">{{ tag }}</el-tag>
              </el-space>
            </el-descriptions-item>
          </el-descriptions>
        </el-card>


        <!-- 课程目录与播放器：点击视频后，在所属章节下方出现播放器 -->
        <template v-if="normalizedChapters.length">
          <el-divider>课程目录</el-divider>
          <div class="chapters">
            <el-card
              v-for="(chapter, idx) in normalizedChapters"
              :key="chapter.id"
              class="chapter"
              shadow="never"
            >
              <template #header>
                <div class="chapter-header">
                  <span class="chapter-order">第{{ idx + 1 }}章</span>
                  <span class="chapter-title">{{ chapter.title || '未命名章节' }}</span>
                </div>
               
              </template>

              <!-- 视频列表（不展示任何 ID） -->
              <ul class="video-list">
                <li
                  class="video-item"
                  v-for="video in chapter.videos"
                  :key="video.id"
                  @click="selectVideo(video)"
                  :class="{ active: selectedVideo && selectedVideo.id === video.id }"
                >
                  <span class="video-order">{{ video.orderNum }}.</span>
                  <span class="video-title">{{ video.title || '未命名小节' }}</span>
                  
                </li>
              </ul>

              <!-- 播放器：仅在当前章节下展示（保持原有播放逻辑和 DOM ID） -->
              <div
                v-if="selectedVideo && chapter.videos.some(v => v.id === selectedVideo.id)"
                class="player-card"
              >
                <div class="player-header">
                  <div class="player-title">正在播放：{{ selectedVideo.title || '未命名小节' }}</div>
                  <button class="player-close" @click="closePlayer">关闭播放</button>
                </div>
                <div class="player-body">
                  <div v-if="playerError" class="player-error">{{ playerError }}</div>
                  <div v-else-if="playerLoading" class="player-loading">播放器加载中...</div>
                  <div v-show="!playerLoading && !playerError" :id="playerDomId" class="prism-player"></div>
                </div>
              </div>
            </el-card>
          </div>
        </template>

        <!-- 课程描述 -->
        <template v-if="workDetail.description">
          <el-divider>课程描述</el-divider>
          <el-card shadow="never" class="ep-section">
            <div class="ep-desc rich-text-content" v-html="formatRichTextContent(workDetail.description)"></div>
          </el-card>
        </template>
      </div>
    </div>

    <!-- 底部操作：课程添加修改按钮 -->
    <div class="drawer-footer">
      <el-button @click="visible = false">关闭</el-button>
      <template v-if="isEditing">
        <el-button @click="cancelEdit">取消</el-button>
        <el-button type="primary" :loading="editUploading" @click="saveEdit">保存修改</el-button>
      </template>
      <el-button v-else type="primary" @click="startEdit">修改课程</el-button>
    </div>
  </el-drawer>
</template>

<script setup>
import { ref, reactive, computed, watch, nextTick, onUnmounted } from 'vue'
import { getCourseDetail, updateCourse, getCourseCategories } from '@/api/course.js'
import { getPlayAuth, createUploadAuth, refreshUploadAuth } from '@/api/vod.js'
import { uploadFileToOss } from '@/api/files.js'
import { getCurrentUser } from '@/api/user.js'
import { useUserStore } from '@/store/user.js'
import Aliplayer from 'aliyun-aliplayer'
import 'aliyun-aliplayer/build/skins/default/aliplayer-min.css'
import { getPlayerConfig, getLicenseConfig } from '@/config/aliplayer.js'
import { ElMessage } from 'element-plus'
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'

// Props
const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  workId: {
    type: String,
    default: ''
  },
  listItem: {
    type: Object,
    default: () => ({})
  }
})

// Emits
const emit = defineEmits(['update:modelValue', 'refresh'])

// Quill编辑器配置 - 使用默认图片处理，保存时统一上传到OSS
const quillOptions = {
  theme: 'snow',
  modules: {
    toolbar: [
      ['bold', 'italic', 'underline', 'strike'],
      ['blockquote', 'code-block'],
      [{ 'header': 1 }, { 'header': 2 }],
      [{ 'list': 'ordered'}, { 'list': 'bullet' }],
      [{ 'script': 'sub'}, { 'script': 'super' }],
      [{ 'indent': '-1'}, { 'indent': '+1' }],
      [{ 'direction': 'rtl' }],
      [{ 'size': ['small', false, 'large', 'huge'] }],
      [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
      [{ 'color': [] }, { 'background': [] }],
      [{ 'font': [] }],
      [{ 'align': [] }],
      ['clean'],
      ['link', 'image']
    ]
  }
}

// 弹窗显示状态
const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

// 详情相关状态
const workDetail = ref(null)
const detailLoading = ref(false)
const detailError = ref('')

// 播放器相关状态
const selectedVideo = ref(null)
const player = ref(null)
const playerLoading = ref(false)
const playerError = ref('')
const playerDomId = 'J_prismPlayer'

// 编辑状态
const isEditing = ref(false)
const editForm = reactive({
  title: '',
  description: '',
  coverUrl: '',
  category: '',
  isFree: true,
  price: 0,
  level: 1,
  chapters: []
})

// 保存原始数据用于比较
const originalData = ref(null)

// 编辑时的文件状态
const editCoverFile = ref(null)
const editCoverPreviewUrl = ref('')
const editUploading = ref(false)
const editCoverInput = ref(null)
const editVideoInputs = ref({})


// 分类数据状态
const courseCategories = ref([])
const categoriesLoading = ref(false)

// 用户相关
const userStore = useUserStore()
const userInfo = computed(() => userStore.getUserInfo)

// 获取用户ID
const getUserId = () => {
  return userInfo.value?.id || ''
}

// 处理富文本内容中的base64图片上传到OSS
const processDescriptionImages = async (description) => {
  if (!description) return description
  
  const base64Regex = /<img[^>]+src="data:image\/([^;]+);base64,([^"]+)"[^>]*>/g
  let processedDescription = description
  const uploadPromises = []
  
  let match
  while ((match = base64Regex.exec(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 = uploadFileToOss(file, getUserId()).then(uploadRes => {
      const ossUrl = uploadRes.url || uploadRes.data?.url || uploadRes
      // 替换原来的base64图片为OSS链接
      processedDescription = processedDescription.replace(fullMatch, fullMatch.replace(`data:image/${imageType};base64,${base64Data}`, ossUrl))
    }).catch(error => {
      console.warn('富文本图片上传失败:', error)
      // 如果上传失败，保留原始的base64图片
    })
    
    uploadPromises.push(uploadPromise)
  }
  
  // 等待所有图片上传完成
  await Promise.all(uploadPromises)
  return processedDescription
}


// 获取用户信息
const updateUserInfo = async () => {
  try {
    const response = await getCurrentUser()
    if (response.code === 200) {
      userStore.updateUserInfo(response.data)
    } else {
      console.error('获取用户信息失败:', response.message)
    }
  } catch (error) {
    console.error('更新用户信息失败:', error)
  }
}

// 组件卸载时清理资源
onUnmounted(() => {
  // 清理其他资源（如需要）
})

// 临时ID生成器
let tempIdCounter = 0
const generateTempId = () => `temp_${Date.now()}_${++tempIdCounter}`

// 统一费用判定：支持 isFree 为 number(0/1) 或 boolean
const isPaid = computed(() => {
  const value = workDetail.value?.isFree
  if (value === undefined || value === null) return false
  if (typeof value === 'number' || typeof value === 'string') {
    const num = Number(value)
    if (Number.isNaN(num)) return false
    // 接口约定：0 收费，1 免费
    return num === 0
  }
  if (typeof value === 'boolean') {
    // 历史约定：true 收费，false 免费
    return value === true
  }
  return false
})

// 统一审核信息：详情缺失时回退到列表项
const detailAuditStatus = computed(() => {
  const a = workDetail.value?.auditStatus
  return (a !== undefined && a !== null) ? a : props.listItem?.auditStatus
})
const detailRejectReason = computed(() => {
  return workDetail.value?.rejectReason ?? props.listItem?.rejectReason ?? ''
})
const detailReviewTime = computed(() => {
  return workDetail.value?.reviewTime ?? props.listItem?.reviewTime ?? ''
})

const formatAuditStatus = (val) => {
  if (val === 0 || val === '0') return '待审核'
  if (val === 1 || val === '1') return '已通过'
  if (val === 2 || val === '2') return '未通过'
  return '未知'
}

const formatTime = (timeStr) => {
  if (!timeStr) return '-'
  try {
    const date = new Date(timeStr)
    return date.toLocaleString('zh-CN')
  } catch (e) {
    return timeStr
  }
}

// 章节与视频：排序与格式化
const normalizedChapters = computed(() => {
  const chapters = Array.isArray(workDetail.value?.chapters) ? workDetail.value.chapters : []
  const sortedChapters = chapters
    .map((ch, index) => ({
      originalIndex: index,
      id: ch?.id ?? '',
      title: ch?.title ?? '',
      description: ch?.description ?? '',
      orderNum: Number(ch?.orderNum ?? 0),
      videos: Array.isArray(ch?.videos) ? ch.videos.slice() : []
    }))
    .sort((a, b) => (a.orderNum - b.orderNum) || (a.originalIndex - b.originalIndex))

  sortedChapters.forEach(ch => {
    ch.videos = ch.videos
      .map((v, index) => ({
        originalIndex: index,
        id: v?.id ?? '',
        title: v?.title ?? '',
        videoId: v?.videoId ?? '',
        orderNum: Number(v?.orderNum ?? 0),
        durationSec: Number(v?.durationSec ?? 0)
      }))
      .sort((a, b) => (a.orderNum - b.orderNum) || (a.originalIndex - b.originalIndex))
  })

  return sortedChapters
})

const formatDuration = (sec) => {
  const total = Number(sec || 0)
  const minutes = Math.floor(total / 60)
  const seconds = Math.floor(total % 60)
  const mm = String(minutes).padStart(2, '0')
  const ss = String(seconds).padStart(2, '0')
  return `${mm}:${ss}`
}

// 格式化富文本内容
const formatRichTextContent = (content) => {
  if (!content) return ''
  
  let formattedContent = content.toString()
  
  // 处理换行符 - 将 \n 转换为 <br>
  formattedContent = formattedContent.replace(/\n/g, '<br>')
  
  // 处理多个连续空格
  formattedContent = formattedContent.replace(/ {2,}/g, (match) => {
    return '&nbsp;'.repeat(match.length)
  })
  
  // 处理制表符
  formattedContent = formattedContent.replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;')
  
  // 确保HTML标签正常工作，不需要额外转义
  return formattedContent
}

// 从视频文件获取时长
const getVideoDuration = (file) => {
  return new Promise((resolve, reject) => {
    if (!file || !file.type.startsWith('video/')) {
      reject(new Error('无效的视频文件'))
      return
    }

    const video = document.createElement('video')
    video.preload = 'metadata'
    
    video.onloadedmetadata = () => {
      window.URL.revokeObjectURL(video.src)
      const duration = Math.round(video.duration)
      if (isNaN(duration) || duration <= 0) {
        reject(new Error('无法获取视频时长'))
      } else {
        resolve(duration)
      }
    }
    
    video.onerror = () => {
      window.URL.revokeObjectURL(video.src)
      reject(new Error('视频文件格式不支持或已损坏'))
    }
    
    video.src = window.URL.createObjectURL(file)
  })
}

// 检测数据是否有变更
const hasDataChanged = () => {
  if (!originalData.value) return false
  
  const original = originalData.value
  
  // 检查基本信息
  if (editForm.title !== (original.title || '')) return true
  if (editForm.description !== (original.description || '')) return true
  if (editForm.category !== (original.category || '')) return true
  if (editForm.isFree !== (original.isFree !== false)) return true
  if (editForm.price !== (original.price || 0)) return true
  if (editForm.level !== (original.level || 1)) return true
  
  // 检查是否有新的封面文件
  if (editCoverFile.value) return true
  
  // 检查章节数量
  const originalChapters = Array.isArray(original.chapters) ? original.chapters : []
  if (editForm.chapters.length !== originalChapters.length) return true
  
  // 检查章节内容
  for (let i = 0; i < editForm.chapters.length; i++) {
    const editChapter = editForm.chapters[i]
    const originalChapter = originalChapters[i]
    
    if (!originalChapter) return true
    if (editChapter.title !== (originalChapter.title || '')) return true
    if (editChapter.description !== (originalChapter.description || '')) return true
    
    // 检查视频
    const originalVideos = Array.isArray(originalChapter.videos) ? originalChapter.videos : []
    if (editChapter.videos.length !== originalVideos.length) return true
    
    for (let j = 0; j < editChapter.videos.length; j++) {
      const editVideo = editChapter.videos[j]
      const originalVideo = originalVideos[j]
      
      // 有新上传的视频文件
      if (editVideo.newFile) return true
      
      if (!originalVideo) return true
      if (editVideo.title !== (originalVideo.title || '')) return true
      if (editVideo.durationSec !== (originalVideo.durationSec || 0)) return true
    }
  }
  
  return false
}

// 加载课程分类
const loadCourseCategories = async () => {
  if (courseCategories.value.length > 0) {
    // 如果已经有数据，则不重复请求
    return
  }
  
  try {
    categoriesLoading.value = true
    const response = await getCourseCategories()
    
    // 统一解包，兼容不同的响应格式
    const categoriesData = response?.data || response || []
    
    // 如果后端返回的是对象数组，转换为选项格式
    if (Array.isArray(categoriesData)) {
      courseCategories.value = categoriesData.map(item => {
        if (typeof item === 'string') {
          return { label: item, value: item }
        } else if (item && typeof item === 'object') {
          return {
            label: item.label || item.name || item.categoryName || item.category || item.value,
            value: item.value || item.name || item.categoryName || item.category || item.label
          }
        }
        return { label: '其他', value: '其他' }
      })
    } else {
      // 如果接口返回格式异常，使用默认分类
      console.warn('课程分类数据格式异常，使用默认分类:', categoriesData)
      courseCategories.value = [
      
      ]
    }
    
    console.log('[CourseDetailModal] 加载课程分类成功:', courseCategories.value)
  } catch (e) {
    console.error('获取课程分类失败:', e)
    // 使用默认分类作为后备
    courseCategories.value = [
      { label: '技术教程', value: '技术教程' },
      { label: '娱乐视频', value: '娱乐视频' },
      { label: '教育内容', value: '教育内容' },
      { label: '其他', value: '其他' }
    ]
    ElMessage.warning('获取分类数据失败，使用默认分类')
  } finally {
    categoriesLoading.value = false
  }
}

// 监听弹窗显示状态
watch(visible, async (newVal) => {
  if (newVal && props.workId) {
    await updateUserInfo()
    await loadWorkDetail(props.workId)
  }
})

// 加载作品详情
const loadWorkDetail = async (id) => {
  detailLoading.value = true
  detailError.value = ''
  workDetail.value = null
  // 清理播放器状态
  disposePlayer()
  selectedVideo.value = null
  
  try {
    const detailData = await getCourseDetail(id)
    
    if (detailData) {
      // 统一解包，兼容 { code, message, data } 与直接对象两种返回
      workDetail.value = detailData?.data ?? detailData
    } else {
      detailError.value = '未找到作品详情信息'
    }
  } catch (e) {
    console.error('获取作品详情失败', e)
    detailError.value = '获取作品详情失败，请稍后重试'
  } finally {
    detailLoading.value = false
  }
}

const retryLoadDetail = () => {
  if (props.workId) {
    loadWorkDetail(props.workId)
  }
}

// 弹窗关闭处理
const handleClose = () => {
  workDetail.value = null
  detailError.value = ''
  isEditing.value = false
  clearEditState()
  disposePlayer()
}

// 清理编辑状态
const clearEditState = () => {
  editForm.title = ''
  editForm.description = ''
  editForm.coverUrl = ''
  editForm.category = ''
  editForm.isFree = true
  editForm.price = 0
  editForm.level = 1
  editForm.chapters = []
  
  editCoverFile.value = null
  if (editCoverPreviewUrl.value) {
    try { URL.revokeObjectURL(editCoverPreviewUrl.value) } catch (e) {}
  }
  editCoverPreviewUrl.value = ''
  editVideoInputs.value = {}
  
  
  originalData.value = null
}

// 开始编辑
const startEdit = async () => {
  if (!workDetail.value) return
  
  // 加载分类数据（如果还没有加载）
  await loadCourseCategories()
  
  // 保存原始数据用于比较
  originalData.value = JSON.parse(JSON.stringify(workDetail.value))
  
  // 初始化编辑表单
  editForm.title = workDetail.value.title || ''
  editForm.description = workDetail.value.description || ''
  editForm.coverUrl = workDetail.value.coverUrl || ''
  editForm.category = workDetail.value.category || ''
  editForm.isFree = workDetail.value.isFree !== false
  editForm.price = workDetail.value.price || 0
  editForm.level = workDetail.value.level || 1
  
  // 复制章节数据
  const chapters = Array.isArray(workDetail.value.chapters) ? workDetail.value.chapters : []
  editForm.chapters = chapters.map(ch => ({
    id: ch.id,
    tempId: generateTempId(),
    title: ch.title || '',
    description: ch.description || '',
    orderNum: ch.orderNum || 0,
    videos: Array.isArray(ch.videos) ? ch.videos.map(v => ({
      id: v.id,
      tempId: generateTempId(),
      title: v.title || '',
      orderNum: v.orderNum || 0,
      durationSec: v.durationSec || 0,
      videoId: v.videoId || '',
      newFile: null, // 新上传的视频文件
      previewUrl: null // 视频预览URL
    })) : []
  }))
  
  
  isEditing.value = true
}

// 取消编辑
const cancelEdit = () => {
  clearEditState()
  isEditing.value = false
}

// 封面上传相关
const triggerEditCoverSelect = () => {
  editCoverInput.value?.click()
}

const handleEditCoverSelect = (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
  }
  
  if (editCoverPreviewUrl.value) {
    try { URL.revokeObjectURL(editCoverPreviewUrl.value) } catch (e) {}
  }
  
  editCoverFile.value = file
  editCoverPreviewUrl.value = URL.createObjectURL(file)
}

const clearEditCover = () => {
  if (editCoverPreviewUrl.value) {
    try { URL.revokeObjectURL(editCoverPreviewUrl.value) } catch (e) {}
  }
  editCoverFile.value = null
  editCoverPreviewUrl.value = ''
  if (editCoverInput.value) {
    editCoverInput.value.value = ''
  }
}

// 章节管理
const addEditChapter = () => {
  editForm.chapters.push({
    tempId: generateTempId(),
    title: '',
    description: '',
    orderNum: editForm.chapters.length + 1,
    videos: []
  })
}

const removeEditChapter = (cIndex) => {
  const chapter = editForm.chapters[cIndex]
  if (chapter?.videos) {
    // 清理视频文件
    chapter.videos.forEach(video => {
      if (video.newFile) {
        try { URL.revokeObjectURL(video.newFile) } catch (e) {}
      }
    })
  }
  editForm.chapters.splice(cIndex, 1)
}

// 视频管理
const addEditVideo = (cIndex) => {
  const chapter = editForm.chapters[cIndex]
  if (!chapter) return
  
  chapter.videos.push({
    tempId: generateTempId(),
    title: '',
    orderNum: chapter.videos.length + 1,
    durationSec: 60,
    newFile: null,
    previewUrl: null
  })
}

const removeEditVideo = (cIndex, vIndex) => {
  const chapter = editForm.chapters[cIndex]
  if (!chapter) return
  
  const video = chapter.videos[vIndex]
  if (video?.newFile) {
    try { URL.revokeObjectURL(video.newFile) } catch (e) {}
  }
  
  chapter.videos.splice(vIndex, 1)
}

// 视频文件上传
const setEditVideoInputRef = (cIndex, vIndex, el) => {
  const key = `${cIndex}-${vIndex}`
  if (el) editVideoInputs.value[key] = el
}

const triggerEditVideoSelect = (cIndex, vIndex) => {
  const key = `${cIndex}-${vIndex}`
  editVideoInputs.value[key]?.click()
}

const handleEditVideoSelect = async (cIndex, vIndex, event) => {
  const file = event.target.files?.[0]
  if (!file) return
  
  if (!file.type.startsWith('video/')) {
    ElMessage.error('请选择有效的视频文件')
    return
  }
  
  if (file.size > 1024 * 1024 * 1024) {
    ElMessage.error('视频文件大小不能超过 1GB')
    return
  }
  
  const chapter = editForm.chapters[cIndex]
  const video = chapter?.videos?.[vIndex]
  if (!video) return
  
  if (video.newFile && video.newFile !== file) {
    try { URL.revokeObjectURL(video.newFile) } catch (e) {}
  }
  
  video.newFile = file
  
  // 生成预览URL
  if (video.previewUrl) {
    try { URL.revokeObjectURL(video.previewUrl) } catch (e) {}
  }
  video.previewUrl = URL.createObjectURL(file)
  
  // 自动获取视频时长
  try {
    video.durationSec = 0 // 重置时长，显示加载状态
    const duration = await getVideoDuration(file)
    video.durationSec = duration
    ElMessage.success(`视频时长：${formatDuration(duration)}`)
  } catch (error) {
    console.warn('获取视频时长失败:', error)
    video.durationSec = 60 // 默认值
    ElMessage.warning('无法自动获取视频时长，已设置为默认值60秒')
  }
}

const clearEditVideo = (cIndex, vIndex) => {
  const chapter = editForm.chapters[cIndex]
  const video = chapter?.videos?.[vIndex]
  if (!video) return
  
  if (video.newFile) {
    try { URL.revokeObjectURL(video.newFile) } catch (e) {}
  }
  if (video.previewUrl) {
    try { URL.revokeObjectURL(video.previewUrl) } catch (e) {}
  }
  video.newFile = null
  video.previewUrl = null
  video.durationSec = video.id ? video.durationSec : 60 // 如果是新视频，重置为默认值
  
  const key = `${cIndex}-${vIndex}`
  const input = editVideoInputs.value[key]
  if (input) input.value = ''
}


// 上传视频到VOD
const uploadVideoToVod = async (videoFile, meta) => {
  if (typeof window.AliyunUpload === 'undefined') {
    throw new Error('阿里云上传SDK未加载，请刷新页面重试')
  }
  if (typeof window.AliyunUpload.Vod !== 'function') {
    throw new Error('阿里云上传SDK初始化失败，请刷新页面重试')
  }

  return new Promise((resolve, reject) => {
    let uploader = null
    try {
      uploader = new window.AliyunUpload.Vod({
        userId: getUserId(),
        region: 'cn-shanghai',
        partSize: 1024 * 1024,
        parallel: 5,
        retryCount: 3,
        retryDuration: 2,
        onUploadstarted: async (uploadInfo) => {
          try {
            const auth = await createUploadAuth({
              userId: getUserId(),
              title: meta.title || videoFile.name,
              description: meta.description || '',
              tags: meta.tags || '',
              cateId: meta.cateId || '',
              fileName: videoFile.name,
              fileSize: videoFile.size
            })
            const { uploadAuth, uploadAddress, videoId } = auth || {}
            if (!uploadAuth || !uploadAddress || !videoId) {
              throw new Error('上传凭证缺少必要字段')
            }
            uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
          } catch (e) {
            reject(e)
          }
        },
        onUploadProgress: (uploadInfo, totalSize, progress) => {
          // 这里可以添加进度回调
        },
        onUploadSucceed: (uploadInfo) => {
          resolve(uploadInfo.videoId)
        },
        onUploadFailed: (uploadInfo, code, message) => {
          reject(new Error(message || '上传失败'))
        },
        onUploadTokenExpired: async (uploadInfo) => {
          try {
            const refreshed = await refreshUploadAuth({ videoId: uploadInfo.videoId })
            const { uploadAuth } = refreshed || {}
            if (!uploadAuth) throw new Error('刷新上传凭证失败')
            uploader.resumeUploadWithAuth(uploadAuth)
          } catch (e) {
            reject(e)
          }
        },
        onUploadCanceled: () => {
          reject(new Error('上传已取消'))
        }
      })
      uploader.addFile(videoFile, null, null, null, null)
      uploader.startUpload()
    } catch (e) {
      reject(e)
    }
  })
}

// 保存编辑
const saveEdit = async () => {
  try {
    // 基础验证
    if (!editForm.title.trim()) {
      ElMessage.error('请填写课程标题')
      return
    }

    // 检查数据是否有变更
    if (!hasDataChanged()) {
      ElMessage.info('数据未发生变更，无需保存')
      return
    }

    editUploading.value = true
    
   
    const processedDescription = await processDescriptionImages(editForm.description)
    editForm.description = processedDescription
    
    // 上传封面
    let coverUrl = editForm.coverUrl
    if (editCoverFile.value) {
      try {
        const uploadRes = await uploadFileToOss(editCoverFile.value, getUserId())
        coverUrl = uploadRes.url || uploadRes.data?.url || uploadRes
      } catch (e) {
        console.warn('封面上传失败:', e)
      }
    }

    // 处理章节和视频数据
    const chaptersData = []
    for (const [cIndex, chapter] of editForm.chapters.entries()) {
      const videosData = []
      
      for (const [vIndex, video] of (chapter.videos || []).entries()) {
        const videoData = {
          title: video.title || `视频 ${cIndex + 1}-${vIndex + 1}`,
          orderNum: video.orderNum || (vIndex + 1),
          durationSec: video.durationSec || 60
        }

        // 如果有新视频文件，需要先上传到阿里云VOD
        if (video.newFile) {
          try {
            const meta = {
              title: video.title || `视频 ${cIndex + 1}-${vIndex + 1}`,
              description: editForm.description || '',
              cateId: editForm.category || ''
            }
            const vodVideoId = await uploadVideoToVod(video.newFile, meta)
            videoData.vodVideoId = vodVideoId
          } catch (e) {
            console.error(`视频 ${cIndex + 1}-${vIndex + 1} 上传失败:`, e)
            throw new Error(`视频 ${cIndex + 1}-${vIndex + 1} 上传失败`)
          }
        } else if (video.id) {
          // 保留原有视频
          videoData.id = video.id
          if (video.videoId) videoData.videoId = video.videoId
        }

        videosData.push(videoData)
      }

      const chapterData = {
        title: chapter.title || `第 ${cIndex + 1} 章`,
        description: chapter.description || '',
        orderNum: chapter.orderNum || (cIndex + 1),
        videos: videosData
      }

      if (chapter.id) {
        chapterData.id = chapter.id
      }

      chaptersData.push(chapterData)
    }

    // 构建更新数据
    const updateData = {
      title: editForm.title,
      description: editForm.description,
      category: editForm.category,
      isFree: editForm.isFree,
      submitForAudit: false, // 不自动提交审核
      deleteMissing: true, // 删除未包含的章节和视频
      chapters: chaptersData
    }

    if (coverUrl) {
      updateData.coverUrl = coverUrl
    }

    if (!editForm.isFree) {
      updateData.price = editForm.price || 0
      updateData.level = editForm.level || 1
    }

    // 调用更新接口
    await updateCourse(props.workId, updateData)
    
    ElMessage.success('课程更新成功')
    
    // 重新加载详情
    await loadWorkDetail(props.workId)
    
    // 退出编辑模式
    isEditing.value = false
    clearEditState()
    
    // 通知父组件刷新列表
    emit('refresh')

  } catch (e) {
    console.error('保存失败:', e)
    ElMessage.error(e.message || '保存失败，请稍后重试')
  } finally {
    editUploading.value = false
  }
}

// 选择视频并初始化播放器
const selectVideo = async (video) => {
  try {
    if (!video?.videoId) return
    selectedVideo.value = video
    playerLoading.value = true
    playerError.value = ''
    disposePlayer()

    // 获取播放凭证
    const authRes = await getPlayAuth({ videoId: video.videoId })
    const playAuth = authRes?.playAuth || authRes?.PlayAuth || authRes
    if (!playAuth) {
      throw new Error('未获取到播放凭证')
    }

    // 等待DOM更新
    await nextTick()

    // 初始化播放器（合并默认配置 + 传入VID/PlayAuth + License）
    const baseConfig = getPlayerConfig({
      id: playerDomId,
      vid: video.videoId,
      playauth: playAuth
    })
    const license = getLicenseConfig()
    player.value = new Aliplayer(
      { ...baseConfig, license },
      () => { console.log('Aliplayer created') }
    )
  } catch (err) {
    console.error('初始化播放器失败:', err)
    playerError.value = err?.message || '播放器初始化失败'
  } finally {
    playerLoading.value = false
  }
}

const disposePlayer = () => {
  try {
    if (player.value && typeof player.value.dispose === 'function') {
      player.value.dispose()
    }
  } catch (_) {}
  player.value = null
}

const closePlayer = () => {
  disposePlayer()
  selectedVideo.value = null
}
</script>

<style scoped>
/* 课程详情滑块样式 */
:deep(.course-detail-drawer .el-drawer__header) {
  padding: 16px 24px;
  border-bottom: 1px solid #ebeef5;
  margin-bottom: 0;
}

:deep(.course-detail-drawer .el-drawer__body) {
  padding: 0;
  height: calc(100vh - 120px);
  overflow-y: auto;
}

/* 详情内容区域 */
.ep-detail-header {
  text-align: left;
  font-size: 18px;
  font-weight: 600;
  color: #333;
}

.ep-detail-body {
  text-align: left;
  padding: 20px 24px;
  height: calc(100vh - 180px);
  overflow-y: auto;
}

/* 底部操作按钮样式 */
.drawer-footer {
  position: sticky;
  bottom: 0;
  background: #fff;
  padding: 16px 24px;
  border-top: 1px solid #ebeef5;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
  z-index: 10;
}

/* 编辑模式样式 */
.edit-mode {
  max-height: calc(100vh - 220px);
  overflow-y: auto;
  padding-bottom: 20px;
}

.edit-cover-upload {
  width: 100%;
  height: 200px;
  border: 2px dashed #d9d9d9;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: border-color 0.3s ease;
  cursor: pointer;
}

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

.cover-upload-placeholder {
  text-align: center;
  color: #999;
}



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

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

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

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

/* 章节编辑样式 */
.chapter-edit-section {
  margin-top: 20px;
}

.chapter-actions {
  margin-bottom: 16px;
}

.edit-chapters {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.chapter-edit-card {
  border: 1px solid #e4e7ed;
}

.chapter-edit-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

.chapter-index {
  color: #409eff;
  font-weight: 600;
  min-width: 80px;
}

.chapter-edit-content {
  padding: 16px 0;
}

.videos-section {
  margin-top: 16px;
}

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

.videos-header h4 {
  margin: 0;
  color: #333;
  font-size: 16px;
}

.edit-videos {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.video-edit-card {
  border: 1px solid #ebeef5;
  background: #fafbfc;
}

.video-edit-content {
  padding: 12px;
}

.video-edit-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

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

/* 视频时长显示 */
.duration-display {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background-color: #f5f7fa;
  min-height: 32px;
  display: flex;
  align-items: center;
}

.duration-value {
  color: #409eff;
  font-weight: 500;
  font-size: 14px;
}

.duration-placeholder {
  color: #909399;
  font-size: 14px;
  font-style: italic;
}

/* 视频上传区域 */
.video-upload-area {
  width: 100%;
  height: 120px;
  border: 2px dashed #d9d9d9;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.3s ease;
  cursor: pointer;
}

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

.video-upload-placeholder {
  text-align: center;
  color: #999;
}



.upload-hint {
  font-size: 12px;
  color: #999;
  margin-top: 4px;
}

.video-preview-container {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 6px;
  overflow: hidden;
}

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

.video-preview-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
  color: white;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.video-preview-overlay .video-name {
  font-size: 12px;
  margin: 0;
  word-break: break-all;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.video-preview-overlay .video-actions {
  display: flex;
  gap: 4px;
}

.video-preview-overlay .video-actions .el-button {
  opacity: 0.9;
}

.video-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.video-name {
  font-size: 14px;
  color: #333;
  text-align: center;
  word-break: break-all;
}

.video-actions {
  display: flex;
  gap: 8px;
}



/* 查看模式样式 */
.view-mode {
  padding-bottom: 20px;
}

.ep-cover {
  width: 100%;
  height: 200px;
  border-radius: 8px;
}

.ep-title {
  font-size: 24px;
  font-weight: 600;
  margin-bottom: 12px;
  color: #333;
}

.ep-desc {
  font-size: 16px;
  color: #666;
  line-height: 1.6;
  margin-bottom: 20px;
}

/* 富文本内容样式 */
.rich-text-content {
  word-break: break-word;
  word-wrap: break-word;
  overflow-wrap: break-word;
  white-space: pre-wrap; /* 保留换行和空格 */
}

.rich-text-content :deep(h1),
.rich-text-content :deep(h2),
.rich-text-content :deep(h3),
.rich-text-content :deep(h4),
.rich-text-content :deep(h5),
.rich-text-content :deep(h6) {
  margin: 16px 0 8px 0 !important;
  font-weight: 600 !important;
  color: #333 !important;
  line-height: 1.4 !important;
}

.rich-text-content h1 { font-size: 24px; }
.rich-text-content h2 { font-size: 20px; }
.rich-text-content h3 { font-size: 18px; }
.rich-text-content h4 { font-size: 16px; }
.rich-text-content h5 { font-size: 14px; }
.rich-text-content h6 { font-size: 12px; }

.rich-text-content :deep(p) {
  margin: 8px 0 !important;
  line-height: 1.6 !important;
  color: #666 !important;
  /* 不强制设置 text-align，保留原有的对齐样式 */
}

.rich-text-content :deep(div) {
  margin: 4px 0 !important;
  line-height: 1.6 !important;
  color: #666 !important;
  /* 不强制设置 text-align，保留原有的对齐样式 */
}

.rich-text-content :deep(span) {
  line-height: 1.6 !important;
  color: #666 !important;
  /* 不强制设置 text-align，保留原有的对齐样式 */
}

.rich-text-content strong,
.rich-text-content b {
  font-weight: 600;
  color: #333;
}

.rich-text-content em,
.rich-text-content i {
  font-style: italic;
  color: #666;
}

.rich-text-content u {
  text-decoration: underline;
}

.rich-text-content s,
.rich-text-content del {
  text-decoration: line-through;
  color: #999;
}

.rich-text-content mark {
  background-color: #fff3cd;
  padding: 2px 4px;
  border-radius: 2px;
}

.rich-text-content ul,
.rich-text-content ol {
  margin: 8px 0;
  padding-left: 20px;
}

.rich-text-content li {
  margin: 4px 0;
  line-height: 1.5;
  color: #666;
}

.rich-text-content dl {
  margin: 8px 0;
}

.rich-text-content dt {
  font-weight: 600;
  color: #333;
  margin: 8px 0 4px 0;
}

.rich-text-content dd {
  margin: 0 0 8px 20px;
  color: #666;
}

.rich-text-content blockquote {
  margin: 12px 0;
  padding: 8px 16px;
  border-left: 4px solid #409eff;
  background-color: #f8f9fa;
  color: #666;
  font-style: italic;
}

.rich-text-content code {
  background-color: #f5f5f5;
  padding: 2px 6px;
  border-radius: 4px;
  font-family: 'Courier New', 'Monaco', 'Menlo', monospace;
  font-size: 14px;
  color: #e96900;
}

.rich-text-content pre {
  background-color: #f5f5f5;
  padding: 12px;
  border-radius: 6px;
  overflow-x: auto;
  margin: 12px 0;
  font-family: 'Courier New', 'Monaco', 'Menlo', monospace;
  font-size: 13px;
  line-height: 1.4;
}

.rich-text-content pre code {
  background: none;
  padding: 0;
  color: #333;
  font-size: inherit;
}

.rich-text-content a {
  color: #409eff;
  text-decoration: none;
  transition: color 0.2s ease;
}

.rich-text-content a:hover {
  color: #337ecc;
  text-decoration: underline;
}

.rich-text-content :deep(img) {
  height: 460px !important;
  width: auto !important;
  max-width: 100% !important;
  border-radius: 6px !important;
  margin: 8px 0 !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important;
  display: block !important;
  object-fit: contain !important;
}

.rich-text-content video {
  max-width: 100%;
  height: auto;
  border-radius: 6px;
  margin: 8px 0;
}

.rich-text-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 12px 0;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  border-radius: 6px;
  overflow: hidden;
}

.rich-text-content table th,
.rich-text-content table td {
  border: 1px solid #e0e0e0;
  padding: 8px 12px;
  text-align: left;
  vertical-align: top;
}

.rich-text-content table th {
  background-color: #f8f9fa;
  font-weight: 600;
  color: #333;
}

.rich-text-content table tr:nth-child(even) {
  background-color: #f9f9f9;
}

.rich-text-content table tr:hover {
  background-color: #f0f8ff;
}

.rich-text-content hr {
  border: none;
  border-top: 1px solid #eee;
  margin: 16px 0;
}

.rich-text-content sub {
  font-size: 0.8em;
  vertical-align: sub;
}

.rich-text-content sup {
  font-size: 0.8em;
  vertical-align: super;
}

.rich-text-content small {
  font-size: 0.9em;
  color: #999;
}

/* 文本颜色样式 */
.rich-text-content :deep(.text-red) { color: #f56c6c !important; }
.rich-text-content :deep(.text-orange) { color: #e6a23c !important; }
.rich-text-content :deep(.text-yellow) { color: #f7ba2a !important; }
.rich-text-content :deep(.text-green) { color: #67c23a !important; }
.rich-text-content :deep(.text-blue) { color: #409eff !important; }
.rich-text-content :deep(.text-purple) { color: #9c27b0 !important; }
.rich-text-content :deep(.text-gray) { color: #909399 !important; }

/* 文本大小样式 */
.rich-text-content :deep(.text-xs) { font-size: 12px !important; }
.rich-text-content :deep(.text-sm) { font-size: 14px !important; }
.rich-text-content :deep(.text-base) { font-size: 16px !important; }
.rich-text-content :deep(.text-lg) { font-size: 18px !important; }
.rich-text-content :deep(.text-xl) { font-size: 20px !important; }
.rich-text-content :deep(.text-2xl) { font-size: 24px !important; }

/* 文本对齐样式 */
.rich-text-content :deep(.text-left) { text-align: left !important; }
.rich-text-content :deep(.text-center) { text-align: center !important; }
.rich-text-content :deep(.text-right) { text-align: right !important; }
.rich-text-content :deep(.text-justify) { text-align: justify !important; }

/* 支持行内样式的对齐 */
.rich-text-content :deep(p[style*="text-align: left"]),
.rich-text-content :deep(div[style*="text-align: left"]),
.rich-text-content :deep(span[style*="text-align: left"]) {
  text-align: left !important;
}

.rich-text-content :deep(p[style*="text-align: center"]),
.rich-text-content :deep(div[style*="text-align: center"]),
.rich-text-content :deep(span[style*="text-align: center"]) {
  text-align: center !important;
}

.rich-text-content :deep(p[style*="text-align: right"]),
.rich-text-content :deep(div[style*="text-align: right"]),
.rich-text-content :deep(span[style*="text-align: right"]) {
  text-align: right !important;
}

.rich-text-content :deep(p[style*="text-align: justify"]),
.rich-text-content :deep(div[style*="text-align: justify"]),
.rich-text-content :deep(span[style*="text-align: justify"]) {
  text-align: justify !important;
}

/* Quill编辑器的对齐类 */
.rich-text-content :deep(.ql-align-left) {
  text-align: left !important;
}

.rich-text-content :deep(.ql-align-center) {
  text-align: center !important;
}

.rich-text-content :deep(.ql-align-right) {
  text-align: right !important;
}

.rich-text-content :deep(.ql-align-justify) {
  text-align: justify !important;
}

/* 背景色样式 */
.rich-text-content :deep(.bg-highlight) { background-color: #fff3cd !important; padding: 2px 4px; border-radius: 2px; }
.rich-text-content :deep(.bg-info) { background-color: #d1ecf1 !important; padding: 2px 4px; border-radius: 2px; }
.rich-text-content :deep(.bg-success) { background-color: #d4edda !important; padding: 2px 4px; border-radius: 2px; }
.rich-text-content :deep(.bg-warning) { background-color: #fff3cd !important; padding: 2px 4px; border-radius: 2px; }
.rich-text-content :deep(.bg-danger) { background-color: #f8d7da !important; padding: 2px 4px; border-radius: 2px; }

/* 特殊样式框 */
.rich-text-content :deep(.callout) {
  padding: 12px 16px !important;
  margin: 12px 0 !important;
  border-radius: 6px !important;
  border-left: 4px solid #409eff !important;
}

.rich-text-content :deep(.callout.info) {
  background-color: #f0f9ff !important;
  border-color: #409eff !important;
  color: #0369a1 !important;
}

.rich-text-content :deep(.callout.success) {
  background-color: #f0fdf4 !important;
  border-color: #67c23a !important;
  color: #166534 !important;
}

.rich-text-content :deep(.callout.warning) {
  background-color: #fffbeb !important;
  border-color: #e6a23c !important;
  color: #92400e !important;
}

.rich-text-content :deep(.callout.danger) {
  background-color: #fef2f2 !important;
  border-color: #f56c6c !important;
  color: #dc2626 !important;
}

/* Quill编辑器样式 */
.ql-editor {
  min-height: 150px !important;
  line-height: 1.6 !important;
}

.ql-container.ql-snow {
  border: 1px solid #dcdfe6 !important;
  border-radius: 4px !important;
}

.ql-toolbar.ql-snow {
  border: 1px solid #dcdfe6 !important;
  border-bottom: none !important;
  border-radius: 4px 4px 0 0 !important;
}

/* 确保富文本编辑器在表单中正确对齐 */
.el-form-item .ql-container {
  width: 100% !important;
  box-sizing: border-box !important;
}

.el-form-item .ql-toolbar {
  width: 100% !important;
  box-sizing: border-box !important;
}

/* 富文本描述编辑器容器 - 完全脱离表单系统 */
.description-editor-container {
  width: 100%;
  margin: 20px 0;
  padding: 0;
  box-sizing: border-box;
}

.description-editor-container .vue-quill-editor {
  width: 100%;
  margin: 0;
  padding: 0;
}

/* 黑白ins风格按钮样式 */
.el-button {
  border-radius: 6px !important;
  font-weight: 500 !important;
  transition: all 0.3s ease !important;
  border: 1.5px solid !important;
}

/* 主要按钮 - 黑色风格 */
.el-button--primary {
  background-color: #000000 !important;
  border-color: #000000 !important;
  color: #ffffff !important;
}

.el-button--primary:hover {
  background-color: #333333 !important;
  border-color: #333333 !important;
  color: #ffffff !important;
}

.el-button--primary:active {
  background-color: #000000 !important;
  border-color: #000000 !important;
}

/* 默认按钮 - 白色风格 */
.el-button--default {
  background-color: #ffffff !important;
  border-color: #000000 !important;
  color: #000000 !important;
}

.el-button--default:hover {
  background-color: #f5f5f5 !important;
  border-color: #000000 !important;
  color: #000000 !important;
}

/* 危险按钮 - 深色风格 */
.el-button--danger {
  background-color: #2d2d2d !important;
  border-color: #2d2d2d !important;
  color: #ffffff !important;
}

.el-button--danger:hover {
  background-color: #1a1a1a !important;
  border-color: #1a1a1a !important;
  color: #ffffff !important;
}

/* 警告按钮 - 灰色风格 */
.el-button--warning {
  background-color: #666666 !important;
  border-color: #666666 !important;
  color: #ffffff !important;
}

.el-button--warning:hover {
  background-color: #4d4d4d !important;
  border-color: #4d4d4d !important;
  color: #ffffff !important;
}

/* 成功按钮 - 深灰色风格 */
.el-button--success {
  background-color: #333333 !important;
  border-color: #333333 !important;
  color: #ffffff !important;
}

.el-button--success:hover {
  background-color: #1a1a1a !important;
  border-color: #1a1a1a !important;
  color: #ffffff !important;
}

/* 信息按钮 - 浅灰色风格 */
.el-button--info {
  background-color: #f0f0f0 !important;
  border-color: #999999 !important;
  color: #333333 !important;
}

.el-button--info:hover {
  background-color: #e0e0e0 !important;
  border-color: #666666 !important;
  color: #000000 !important;
}

/* 小按钮 */
.el-button--small {
  padding: 6px 12px !important;
  font-size: 12px !important;
}

/* 加载状态 */
.el-button.is-loading {
  opacity: 0.7 !important;
}

/* 禁用状态 */
.el-button.is-disabled {
  background-color: #f5f5f5 !important;
  border-color: #d9d9d9 !important;
  color: #b3b3b3 !important;
}

.el-button.is-disabled:hover {
  background-color: #f5f5f5 !important;
  border-color: #d9d9d9 !important;
  color: #b3b3b3 !important;
}

/* 文本按钮 */
.el-button--text {
  background-color: transparent !important;
  border-color: transparent !important;
  color: #000000 !important;
}

.el-button--text:hover {
  background-color: #f5f5f5 !important;
  color: #000000 !important;
}

/* 链接按钮 */
.el-button.is-link {
  color: #000000 !important;
  text-decoration: underline !important;
}

.el-button.is-link:hover {
  color: #333333 !important;
}

.ep-section {
  margin-bottom: 16px;
}

.ep-section-title {
  font-weight: 600;
  color: #333;
}

/* 章节目录样式 */
.chapters {
  margin-top: 16px;
}

.chapter {
  margin-bottom: 14px;
}

.chapter-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}

.chapter-order {
  color: #1e80ff;
}

.chapter-desc {
  margin: 6px 0 8px 0;
  color: #666;
}

.video-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.video-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid #f0f0f0;
  border-radius: 6px;
  background: #fafafa;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}

.video-order {
  color: #888;
}

.video-title {
  flex: 1;
  color: #333;
}

.video-duration {
  color: #666;
}

.video-item:hover {
  background: #f5faff;
  border-color: #e6f0ff;
}

.video-item.active {
  background: #eef6ff;
  border-color: #cfe3ff;
}

/* 播放器卡片样式 */
.player-card {
  margin-top: 16px;
  border: 1px solid #eee;
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 4px 16px rgba(0,0,0,.06);
}

.player-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  background: #f7f9fc;
  border-bottom: 1px solid #eee;
}

.player-title {
  font-weight: 600;
  color: #333;
}

.player-close {
  background: #fff;
  border: 1px solid #ddd;
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
}

.player-body {
  padding: 10px;
}

.player-loading, .player-error {
  text-align: center;
  color: #666;
  padding: 20px 0;
}

.prism-player {
  width: 100%;
  height: 300px;
}


/* 拒绝原因样式 */
.reject-reason {
  color: #f56c6c;
  font-weight: 500;
  word-break: break-all;
  line-height: 1.5;
}

/* 图片预览器简化样式 */
:deep(.el-image-viewer__wrapper) {
  z-index: 3000 !important;
}

/* 隐藏预览器中的部分功能按钮，保持简洁 */
:deep(.el-image-viewer__actions) {
  background: rgba(0, 0, 0, 0.5) !important;
  padding: 8px !important;
  border-radius: 6px !important;
}

/* 保留基本的导航和关闭按钮，隐藏其他功能 */
:deep(.el-image-viewer__actions .el-image-viewer__actions__inner) {
  display: flex !important;
  justify-content: center !important;
  gap: 8px !important;
}

/* 隐藏不常用的功能按钮 */
:deep(.el-image-viewer__actions .el-image-viewer__actions__inner > :not(:first-child):not(:nth-child(2)):not(:last-child)) {
  display: none !important;
}

/* 简化切换按钮样式 */
:deep(.el-image-viewer__btn) {
  background: rgba(0, 0, 0, 0.5) !important;
  border: none !important;
  border-radius: 50% !important;
  width: 40px !important;
  height: 40px !important;
  font-size: 18px !important;
}

:deep(.el-image-viewer__btn:hover) {
  background: rgba(0, 0, 0, 0.7) !important;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  :deep(.course-detail-drawer) {
    width: 100% !important;
  }
}

@media (max-width: 768px) {
  .ep-detail-body {
    padding: 16px;
  }
  
  .drawer-footer {
    padding: 12px 16px;
  }
  
  .prism-player {
    height: 250px;
  }
  
}
</style>