<template>
  <div class="image-to-video-create-page">
    <CreationHeader />

    <!-- 主内容区域 -->
    <div class="main-content">
      <!-- 左侧设置面板 -->
      <div class="left-panel">
        <!-- 左侧可滚动内容区域 -->
        <div class="left-panel-content">
          <CreationTabs active="image-to-video" />

          <!-- 图片输入区域 -->
          <div class="image-input-section">
          <div class="image-upload-area">
            <div 
              class="upload-box" 
              :class="{ 'drag-over': isDraggingFirstFrame }"
              @click="uploadFirstFrame"
              @dragover.prevent="isDraggingFirstFrame = true"
              @dragleave.prevent="isDraggingFirstFrame = false"
              @drop.prevent="handleDropFirstFrame"
            >
              <div v-if="!firstFrameImage" class="upload-placeholder">
                <div class="upload-icon">+</div>
                <div class="upload-text">{{ t('video.imageToVideo.firstFrame') }}</div>
              </div>
              <div v-else class="upload-preview">
                <img :src="firstFrameImage" :alt="t('video.imageToVideo.firstFrame')" />
                <button class="remove-btn" @click.stop="removeFirstFrame">×</button>
              </div>
            </div>
          </div>
        </div>

        <!-- 文本输入区域 -->
        <div class="text-input-section">
          <textarea
            v-model="inputText"
            :placeholder="t('video.imageToVideo.promptPlaceholder')"
            class="text-input"
            rows="6"
          ></textarea>
          <div class="input-tips">
            <div class="tip-item warning">{{ t('video.imageToVideo.tipWarning') }}</div>
            <div class="tip-item">{{ t('video.imageToVideo.tip1') }}</div>
          </div>
          <div class="optimize-btn">
            <button class="optimize-button" @click="optimizePromptHandler" :disabled="!inputText.trim() || optimizingPrompt">
              ✨ {{ optimizingPrompt ? t('video.imageToVideo.optimizing') : t('video.imageToVideo.optimizePrompt') }}
            </button>
          </div>
        </div>

        <!-- 视频设置 -->
        <div class="video-settings">
          <div class="setting-item">
            <label>{{ t('video.aspectRatio') }}</label>
            <select v-model="aspectRatio" class="setting-select">
              <option value="16:9">16:9</option>
              <option value="9:16">9:16</option>
            </select>
          </div>

          <div class="setting-item">
            <label>{{ t('video.duration') }}</label>
            <select v-model="duration" class="setting-select">
              <option value="10">10s</option>
              <option value="15">15s</option>
            </select>
          </div>

          <!-- 高清模式暂时屏蔽
          <div class="setting-item">
            <label>{{ t('video.imageToVideo.hdMode') }} (1080P)</label>
            <div class="hd-setting">
              <a-switch v-model:checked="hdMode" />
              <span class="cost-text">{{ t('video.imageToVideo.hdModeCost') }}</span>
            </div>
          </div>
          -->
        </div>

        <!-- 生成按钮 -->
        <CreationGenerateButton
          :button-text="isCreatingTask ? t('video.imageToVideo.creatingTask') : t('video.imageToVideo.startGenerate')"
          :points="30"
          :disabled="isCreatingTask"
          :is-authenticated="isAuthenticated"
          :login-prompt-text="t('video.imageToVideo.pleaseLogin')"
          :login-text="t('video.imageToVideo.loginRequired')"
          :login-button-text="t('video.imageToVideo.loginNow')"
          @click="startGenerate"
          @login="goToLogin"
        />
        </div>
      </div>

      <!-- 右侧预览区域 -->
      <div class="right-panel">
        <div class="preview-area">
          <!-- 任务状态显示 -->
          <div class="task-status" v-if="currentTask">
            <div class="status-header">
              <h3>{{ getStatusText(taskStatus) }}</h3>
              <div class="task-id">{{ t('home.imageToVideo') }} {{ formatDate(currentTask.createdAt) }}</div>
            </div>
            
            <!-- 任务描述 -->
            <div class="task-description">
              {{ inputText }}
            </div>
            
            <!-- 视频预览区域 -->
            <div class="video-preview-container">
              <!-- 生成中的状态 -->
              <div v-if="inProgress" class="generating-container">
                <div class="generating-placeholder">
                  <div class="generating-text">{{ taskStatus === 'PENDING' ? t('video.imageToVideo.statusPending') : t('video.generating') }}</div>
                  <!-- 排队中：不确定进度条 -->
                  <div v-if="taskStatus === 'PENDING'" class="progress-bar-large indeterminate">
                    <div class="progress-fill-indeterminate"></div>
                  </div>
                  <!-- 生成中：动态进度条（进度为0时也显示动画） -->
                  <div v-else class="progress-bar-large" :class="{ 'indeterminate': taskProgress === 0 }">
                    <div v-if="taskProgress === 0" class="progress-fill-indeterminate"></div>
                    <div v-else class="progress-fill-large animated" :style="{ width: taskProgress + '%' }"></div>
                  </div>
                  <div class="progress-percentage" v-if="taskStatus !== 'PENDING'">{{ taskProgress }}%</div>
                </div>
              </div>
              
              <!-- 完成状态 -->
              <div v-else-if="taskStatus === 'COMPLETED'" class="completed-container">
                <!-- 任务信息头部 -->
                <div class="task-info-header">
                  <div class="task-checkbox">
                    <input type="checkbox" id="inProgress" v-model="showInProgress">
                    <label for="inProgress">{{ t('video.imageToVideo.inProgress') }}</label>
                  </div>
                </div>
                
                <!-- 视频播放区域 -->
                <div class="video-player-container">
                  <div class="video-player" :style="getVideoPlayerStyle()">
                    <video 
                      v-if="currentTask.resultUrl" 
                      :src="currentTask.resultUrl" 
                      controls 
                      class="result-video"
                      poster=""
                    ></video>
                    <div v-else class="no-video-placeholder">
                      <div class="no-video-text">{{ t('video.imageToVideo.noVideoUrl') }}</div>
                    </div>
                  </div>
                </div>
                
                <!-- 操作按钮区域 -->
                <div class="result-actions">
                  <button class="action-btn primary" @click="createSimilar">{{ t('video.imageToVideo.createSimilar') }}</button>
                  <div class="action-icons">
                    <button class="icon-btn" @click="downloadVideo" :title="t('video.imageToVideo.downloadVideo')">
                      <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                        <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
                      </svg>
                    </button>
                    <button class="icon-btn" @click="deleteWork" :title="t('video.imageToVideo.deleteWork')">
                      <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                        <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/>
                      </svg>
                    </button>
                  </div>
                </div>
              </div>
              
              <!-- 失败状态 -->
              <div v-else-if="taskStatus === 'FAILED'" class="failed-container">
                <div class="failed-placeholder">
                  <div class="failed-icon">❌</div>
                  <div class="failed-text">{{ t('video.imageToVideo.generateFailed') }}</div>
                  <div class="failed-desc">{{ t('video.imageToVideo.generateFailedDesc') }}</div>
                  <div class="failed-reason" v-if="currentTask && currentTask.errorMessage">
                    <span class="reason-label">{{ t('video.failReason') }}：</span>
                    <span class="reason-text">{{ currentTask.errorMessage }}</span>
                  </div>
                </div>
                <div class="result-actions">
                  <button class="action-btn primary" @click="retryTask">{{ t('video.imageToVideo.retry') }}</button>
                </div>
              </div>
              
              <!-- 其他状态 -->
              <div v-else class="status-placeholder">
                <div class="status-text">{{ getStatusText(taskStatus) }}</div>
              </div>
            </div>
            
          </div>
          
          <!-- 初始状态 -->
          <div class="preview-content" v-else>
            <div class="preview-placeholder">
              <div class="placeholder-text">{{ t('video.imageToVideo.startCreating') }}</div>
            </div>
          </div>

          <!-- 历史记录区域 -->
          <div class="history-section" v-if="historyTasks.length > 0">
            <div class="history-list">
              <div 
                v-for="task in historyTasks" 
                :key="task.taskId" 
                class="history-item"
              >
                <!-- 顶部状态复选框 -->
                <div class="history-status-checkbox" v-if="task.status === 'PENDING' || task.status === 'PROCESSING'">
                  <input type="checkbox" :checked="true" disabled>
                  <label>{{ t('video.imageToVideo.inProgress') }}</label>
                </div>

                <!-- 头部信息 -->
                <div class="history-item-header">
                  <span class="history-type">{{ t('home.imageToVideo') }}</span>
                  <span class="history-date">{{ formatDate(task.createdAt) }}</span>
                </div>

                <!-- 描述文字 -->
                <div class="history-prompt">{{ task.prompt || t('video.imageToVideo.noDescription') }}</div>
                
                <!-- 预览区域 -->
                <div class="history-preview" :class="{ 'vertical': task.aspectRatio === '9:16' }">
                  <div v-if="task.status === 'PENDING' || task.status === 'PROCESSING'" class="history-placeholder">
                    <div class="queue-text">{{ task.status === 'PENDING' ? t('video.imageToVideo.queuing') : t('video.generating') }}</div>
                    <!-- 排队中：不确定进度条 -->
                    <div v-if="task.status === 'PENDING'" class="history-progress-bar indeterminate">
                      <div class="progress-fill-indeterminate"></div>
                    </div>
                    <!-- 生成中：动态进度条（进度为0时也显示动画） -->
                    <div v-else class="history-progress-bar" :class="{ 'indeterminate': (task.progress || 0) === 0 }">
                      <div v-if="(task.progress || 0) === 0" class="progress-fill-indeterminate"></div>
                      <div v-else class="progress-fill-large animated" :style="{ width: (task.progress || 0) + '%' }"></div>
                    </div>
                  </div>
                  <div v-else-if="task.status === 'COMPLETED' && task.resultUrl" class="history-video-thumbnail">
                    <video 
                      :ref="el => setVideoRef(task.taskId, el)"
                      :src="processHistoryUrl(task.resultUrl)" 
                      controls
                      preload="metadata"
                      @loadedmetadata="handleVideoLoaded"
                      @error="handleVideoError"
                    ></video>
                  </div>
                  <div v-else-if="task.firstFrameUrl" class="history-image-thumbnail">
                    <img v-lazy:loading="task.firstFrameUrl" :alt="t('video.imageToVideo.firstFrameImage')" />
                  </div>
                  <div v-else class="history-placeholder">
                    <div class="no-result-text">{{ t('video.imageToVideo.noResult') }}</div>
                  </div>
                </div>

                <!-- 操作按钮 -->
                <div class="history-actions">
                  <button class="similar-btn" @click="createSimilarFromHistory(task)">{{ t('video.imageToVideo.createSimilar') }}</button>
                  <button 
                    v-if="task.status === 'COMPLETED' && task.resultUrl" 
                    class="download-btn" 
                    @click="downloadHistoryVideo(task)"
                    :title="t('video.imageToVideo.downloadVideo')"
                  >
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
                      <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
                    </svg>
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    
  </div>
</template>

<script setup>
import { ref, reactive, onUnmounted, computed, onMounted, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { message, Modal } from 'ant-design-vue'
import { useUserStore } from '@/stores/user'
import { StarOutlined } from '@ant-design/icons-vue'
import { imageToVideoApi } from '@/api/imageToVideo'
import { optimizePrompt } from '@/api/promptOptimizer'
import { getProcessingWorks, getMyWorksByType } from '@/api/userWorks'
import CreationHeader from '@/components/CreationHeader.vue'
import CreationTabs from '@/components/CreationTabs.vue'
import CreationGenerateButton from '@/components/CreationGenerateButton.vue'

const router = useRouter()
const route = useRoute()
const userStore = useUserStore()
const { t } = useI18n()

// 计算是否已登录
const isAuthenticated = computed(() => userStore.isAuthenticated)

// 表单数据
const inputText = ref('')
const aspectRatio = ref('9:16')
const duration = ref('15')
const hdMode = ref(false)
const inProgress = ref(false)

// 图片上传
const firstFrameImage = ref('')
const lastFrameImage = ref('')
const firstFrameFile = ref(null)
const lastFrameFile = ref(null)
const isDraggingFirstFrame = ref(false)

// 任务状态
const currentTask = ref(null)
const taskProgress = ref(0)
const taskStatus = ref('')
const stopPolling = ref(null)
const showInProgress = ref(false)
const optimizingPrompt = ref(false) // 优化提示词状态
const historyTasks = ref([]) // 历史记录
const playingVideos = ref({}) // 正在播放的视频
const videoRefs = ref({}) // 视频元素引用
const isCreatingTask = ref(false) // 标记是否正在创建任务，避免重复恢复
const hasRestoredTask = ref(false) // 标记是否已经恢复过任务

// 跳转到登录页面
const goToLogin = () => {
  router.push({
    path: '/login',
    query: { redirect: router.currentRoute.value.fullPath }
  })
}

// 图片上传处理
const uploadFirstFrame = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = 'image/*'
  input.onchange = (e) => {
    const file = e.target.files[0]
    if (file) {
      // 验证文件大小（最大100MB，与后端配置保持一致）
      const maxFileSize = 100 * 1024 * 1024 // 100MB
      if (file.size > maxFileSize) {
        message.error(t('video.imageToVideo.fileSizeLimit'))
        return
      }

      // 验证文件类型
      if (!file.type.startsWith('image/')) {
        message.error(t('video.imageToVideo.invalidImageFile'))
        return
      }
      
      firstFrameFile.value = file
      console.log('[Upload] 文件已设置:', file.name, file.size, 'bytes')
      const reader = new FileReader()
      reader.onload = (e) => {
        firstFrameImage.value = e.target.result
        console.log('[Upload] 图片预览已设置，base64长度:', e.target.result.length)
      }
      reader.readAsDataURL(file)
    }
  }
  input.click()
}

// 处理拖拽上传首帧图片
const handleDropFirstFrame = (e) => {
  isDraggingFirstFrame.value = false
  const files = e.dataTransfer.files
  if (files.length === 0) return
  
  const file = files[0]
  if (!file.type.startsWith('image/')) {
    message.error(t('video.imageToVideo.invalidImageFile'))
    return
  }
  
  const maxFileSize = 100 * 1024 * 1024 // 100MB
  if (file.size > maxFileSize) {
    message.error(t('video.imageToVideo.fileSizeLimit'))
    return
  }
  
  firstFrameFile.value = file
  console.log('[Drop] 文件已设置:', file.name, file.size, 'bytes')
  const reader = new FileReader()
  reader.onload = (e) => {
    firstFrameImage.value = e.target.result
    console.log('[Drop] 图片预览已设置，base64长度:', e.target.result.length)
  }
  reader.readAsDataURL(file)
}

const uploadLastFrame = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = 'image/*'
  input.onchange = (e) => {
    const file = e.target.files[0]
    if (file) {
      // 验证文件大小（最大100MB，与后端配置保持一致）
      const maxFileSize = 100 * 1024 * 1024 // 100MB
      if (file.size > maxFileSize) {
        message.error(t('video.imageToVideo.fileSizeLimit'))
        return
      }

      // 验证文件类型
      if (!file.type.startsWith('image/')) {
        message.error(t('video.imageToVideo.invalidImageFile'))
        return
      }
      
      lastFrameFile.value = file
      const reader = new FileReader()
      reader.onload = (e) => {
        lastFrameImage.value = e.target.result
      }
      reader.readAsDataURL(file)
    }
  }
  input.click()
}

const removeFirstFrame = () => {
  firstFrameImage.value = ''
  firstFrameFile.value = null
}

const removeLastFrame = () => {
  lastFrameImage.value = ''
  lastFrameFile.value = null
}

// 处理创建任务错误的辅助函数
const handleCreateError = (errorMsg) => {
  const msg = errorMsg || t('video.imageToVideo.createTaskFailed')
  
  // 检测积分不足
  if (msg.includes('积分不足') || msg.includes('insufficient') || msg.includes('points')) {
    Modal.confirm({
      title: t('common.insufficientPoints'),
      content: t('common.insufficientPointsMessage'),
      okText: t('common.goRecharge'),
      cancelText: t('common.cancel'),
      onOk() { router.push('/subscription') }
    })
  } else {
    message.error(msg)
  }
  
  inProgress.value = false
  isCreatingTask.value = false
  currentTask.value = null
  taskStatus.value = ''
  taskProgress.value = 0
}

// 开始生成视频
const startGenerate = async () => {
  console.log('[StartGenerate] 开始，firstFrameFile:', firstFrameFile.value ? `File(${firstFrameFile.value.name})` : 'null', 
    'firstFrameImage:', firstFrameImage.value ? firstFrameImage.value.substring(0, 30) + '...' : 'null')
  
  // 检查登录状态
  if (!userStore.isAuthenticated) {
    message.warning(t('video.imageToVideo.pleaseLoginFirst'))
    goToLogin()
    return
  }

  // 注：允许多任务并发，后端会检查最大任务数限制（最多3个）

  // 如果 firstFrameFile 为空但 firstFrameImage 有值（比如从失败任务恢复），尝试从图片重新加载
  if (!firstFrameFile.value && firstFrameImage.value) {
    console.log('[StartGenerate] firstFrameFile 为空，firstFrameImage:', firstFrameImage.value.substring(0, 50))
    const imageUrl = firstFrameImage.value
    
    // 检查是否是 base64 数据 URL（用户手动上传的图片）
    if (imageUrl.startsWith('data:')) {
      try {
        // base64 数据 URL，可以直接 fetch
        const response = await fetch(imageUrl)
        const blob = await response.blob()
        const fileName = `first_frame_${Date.now()}.${blob.type.split('/')[1] || 'png'}`
        firstFrameFile.value = new File([blob], fileName, { type: blob.type })
        console.log('[StartGenerate] Base64图片已成功转换为文件对象:', fileName)
      } catch (error) {
        console.error('[StartGenerate] 无法从base64加载图片:', error)
        // 清空图片显示，让用户重新上传
        firstFrameImage.value = ''
        message.error(t('video.imageToVideo.imageLoadFailed'))
        return
      }
    } else {
      // 外部 URL（如 COS），直接使用 URL 创建任务，无需下载
      console.log('[StartGenerate] 图片是外部URL，直接使用URL创建任务:', imageUrl.substring(0, 100))
      
      // 验证描述文字
      if (!inputText.value.trim()) {
        message.error(t('video.imageToVideo.enterDescriptionRequired'))
        return
      }
      
      // 标记正在创建任务
      isCreatingTask.value = true
      
      // 显示加载状态
      const LoadingOutlined = ElLoading.service({
        lock: true,
        text: t('video.imageToVideo.creatingTask'),
        background: 'rgba(0, 0, 0, 0.7)'
      })
      
      try {
        // 直接调用通过URL创建任务的API
        const response = await imageToVideoApi.createTaskByUrl({
          imageUrl: imageUrl,
          prompt: inputText.value.trim(),
          aspectRatio: aspectRatio.value,
          duration: parseInt(duration.value),
          hdMode: hdMode.value
        })
        
        loading.close()
        
        if (response.data && response.data.success) {
          currentTask.value = response.data.data
          inProgress.value = true
          taskProgress.value = 0
          taskStatus.value = 'PROCESSING'  // 直接显示生成中
          message.success(t('video.imageToVideo.taskCreatedSuccess'))
          setTimeout(() => userStore.fetchCurrentUser(), 0)
          startPollingTask()
          setTimeout(() => { isCreatingTask.value = false }, 2000)
        } else {
          handleCreateError(response.data?.message)
        }
        return
      } catch (error) {
        loading.close()
        console.error('[StartGenerate] 通过URL创建任务失败:', error)
        handleCreateError(error.response?.data?.message || error.message)
        return
      }
    }
  }

  // 验证表单（有 File 对象的情况）
  if (!firstFrameFile.value) {
    message.error(t('video.imageToVideo.uploadFirstFrameRequired'))
    return
  }

  if (!inputText.value.trim()) {
    message.error(t('video.imageToVideo.enterDescriptionRequired'))
    return
  }

  // 标记正在创建任务
  isCreatingTask.value = true

  // 显示加载状态
  const LoadingOutlined = ElLoading.service({
    lock: true,
    text: t('video.imageToVideo.creatingTask'),
    background: 'rgba(0, 0, 0, 0.7)'
  })
  
  try {
    // 准备请求参数（使用 File 对象）
    const params = {
      firstFrame: firstFrameFile.value,
      prompt: inputText.value.trim(),
      aspectRatio: aspectRatio.value,
      duration: parseInt(duration.value),
      hdMode: hdMode.value
    }
    
    // 调用API创建任务
    const response = await imageToVideoApi.createTask(params)
    
    if (response.data && response.data.success) {
      currentTask.value = response.data.data
      inProgress.value = true
      taskProgress.value = 0
      taskStatus.value = 'PROCESSING'  // 直接显示生成中

      message.success(t('video.imageToVideo.taskCreatedSuccess'))

      // 更新用户积分信息（任务创建后积分已被扣除）
      // 使用 setTimeout 确保不阻塞任务流程
      setTimeout(async () => {
        try {
          await userStore.fetchCurrentUser()
          console.log('用户积分已更新')
        } catch (error) {
          console.error('更新用户积分失败:', error)
          // 积分更新失败不影响任务流程
        }
      }, 0)

      // 开始轮询任务状态
      startPollingTask()
      
      // 延迟重置创建标志，避免立即触发恢复逻辑
      setTimeout(() => {
        isCreatingTask.value = false
      }, 2000)

    } else {
      // 任务创建失败，重置所有状态
      const errorMsg = response.data?.message || t('video.imageToVideo.createTaskFailed')
      
      // 检测积分不足
      if (errorMsg.includes('积分不足') || errorMsg.includes('insufficient') || errorMsg.includes('points')) {
        Modal.confirm({
          title: t('common.insufficientPoints'),
          content: t('common.insufficientPointsMessage'),
          okText: t('common.goRecharge'),
          cancelText: t('common.cancel'),
          onOk() { router.push('/subscription') }
        })
      } else {
        message.error(errorMsg)
      }
      
      inProgress.value = false
      isCreatingTask.value = false
      currentTask.value = null
      taskStatus.value = ''
      taskProgress.value = 0
    }

  } catch (error) {
    console.error('创建任务失败:', error)
    const errorMsg = error.response?.data?.message || error.message || ''
    
    // 检测积分不足
    if (errorMsg.includes('积分不足') || errorMsg.includes('insufficient') || errorMsg.includes('points')) {
      Modal.confirm({
        title: t('common.insufficientPoints'),
        content: t('common.insufficientPointsMessage'),
        okText: t('common.goRecharge'),
        cancelText: t('common.cancel'),
        onOk() { router.push('/subscription') }
      })
    } else {
      message.error(t('video.imageToVideo.createTaskFailedRetry'))
    }
    
    // 异常情况，重置所有状态
    inProgress.value = false
    isCreatingTask.value = false
    currentTask.value = null
    taskStatus.value = ''
    taskProgress.value = 0
  } finally {
    loading.close()
  }
}

// 开始轮询任务状态
const startPollingTask = () => {
  if (!currentTask.value) return
  
  stopPolling.value = imageToVideoApi.pollTaskStatus(
    currentTask.value.taskId,
    // 进度回调
    (progressData) => {
      if (progressData && typeof progressData.progress === 'number') {
        taskProgress.value = progressData.progress
      }
      if (progressData && progressData.status) {
        taskStatus.value = progressData.status
      }
      // 更新resultUrl（如果API返回了且不为空）
      if (progressData && progressData.resultUrl && progressData.resultUrl.trim()) {
        if (currentTask.value) {
          currentTask.value.resultUrl = progressData.resultUrl
          console.log('更新resultUrl:', progressData.resultUrl.substring(0, 50) + '...')
        }
      }
      console.log('任务进度:', progressData)
    },
    // 完成回调
    async (taskData) => {
      inProgress.value = false
      taskProgress.value = 100
      taskStatus.value = 'COMPLETED'
      // 更新currentTask的resultUrl
      if (taskData && taskData.resultUrl && taskData.resultUrl.trim()) {
        if (currentTask.value) {
          currentTask.value.resultUrl = taskData.resultUrl
          console.log('任务完成，resultUrl已更新:', taskData.resultUrl.substring(0, 50) + '...')
        }
      } else if (currentTask.value && !currentTask.value.resultUrl) {
        console.warn('任务完成但未获取到resultUrl')
      }
      message.success(t('video.imageToVideo.videoGenerateCompleted'))

      // 更新用户积分信息（使用 setTimeout 确保不阻塞）
      setTimeout(async () => {
        try {
          await userStore.fetchCurrentUser()
          console.log('用户积分已更新')
        } catch (error) {
          console.error('更新用户积分失败:', error)
          // 积分更新失败不影响任务流程
        }
      }, 0)

      // 可以在这里跳转到结果页面或显示结果
      console.log('任务完成:', taskData)
    },
    // 错误回调 - 静默处理，只在页面上显示失败状态，不弹窗
    (error) => {
      inProgress.value = false
      taskStatus.value = 'FAILED'
      console.error('任务失败:', error)
    }
  )
}


// 获取状态文本
const getStatusText = (status) => {
  const statusMap = {
    'PENDING': t('video.imageToVideo.statusPending'),
    'PROCESSING': t('video.imageToVideo.statusProcessing'),
    'COMPLETED': t('video.imageToVideo.statusCompleted'),
    'FAILED': t('video.imageToVideo.statusFailed'),
    'CANCELLED': t('video.imageToVideo.statusCancelled')
  }
  return statusMap[status] || t('profile.unknown')
}

// 获取状态样式类
const getStatusClass = (status) => {
  const classMap = {
    'PENDING': 'status-pending',
    'PROCESSING': 'status-processing',
    'COMPLETED': 'status-completed',
    'FAILED': 'status-failed',
    'CANCELLED': 'status-cancelled'
  }
  return classMap[status] || ''
}

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return ''
  const date = new Date(dateString)
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  return `${year}${t('video.imageToVideo.year')}${month}${t('video.imageToVideo.month')}${day}${t('video.imageToVideo.day')} ${hours}:${minutes}`
}

// 根据aspectRatio获取视频播放器样式
const getVideoPlayerStyle = () => {
  // 获取当前任务的aspectRatio，如果没有则使用默认值
  const ratio = currentTask.value?.aspectRatio || aspectRatio.value || '16:9'
  
  // 将比例字符串转换为数字（如 "16:9" -> 16/9 = 1.777...）
  const [width, height] = ratio.split(':').map(Number)
  const aspectRatioValue = width / height
  
  return {
    aspectRatio: `${width} / ${height}`,
    maxHeight: '70vh' // 限制最大高度，避免视频过大
  }
}

// 优化提示词
const optimizePromptHandler = async () => {
  if (!inputText.value.trim()) {
    message.warning(t('video.imageToVideo.enterPromptFirst'))
    return
  }

  // 长度检查
  if (inputText.value.length > 2000) {
    message.warning(t('video.imageToVideo.promptTooLong'))
    return
  }

  try {
    optimizingPrompt.value = true
    const LoadingOutlined = ElLoading.service({
      lock: false,
      text: t('video.imageToVideo.optimizingPrompt'),
      background: 'rgba(0, 0, 0, 0.3)'
    })
    
    const response = await optimizePrompt(inputText.value.trim(), 'image-to-video')
    
    loading.close()

    if (response.data && response.data.success) {
      const data = response.data.data
      const optimized = data.optimizedPrompt

      // 检查是否真正优化了
      if (data.optimized && optimized !== inputText.value.trim()) {
        inputText.value = optimized
        message.success(t('video.imageToVideo.promptOptimizedSuccess'))
      } else {
        message.warning(t('video.imageToVideo.promptAlreadyOptimized'))
      }
    } else {
      message.error(response.data?.message || t('video.imageToVideo.optimizeFailed'))
    }
  } catch (error) {
    console.error('优化提示词失败:', error)

    let errorMessage = t('video.imageToVideo.optimizePromptFailed')
    if (error.response) {
      const status = error.response.status
      if (status === 400) {
        errorMessage = error.response.data?.message || t('video.imageToVideo.requestParameterError')
      } else if (status === 408 || error.code === 'ECONNABORTED') {
        errorMessage = t('video.imageToVideo.requestTimeout')
      } else if (status >= 500) {
        errorMessage = t('video.imageToVideo.serverError')
      } else {
        errorMessage = error.response.data?.message || t('video.imageToVideo.optimizeFailed')
      }
    } else if (error.request) {
      errorMessage = t('video.imageToVideo.networkError')
    } else if (error.code === 'ERR_NETWORK') {
      errorMessage = t('video.imageToVideo.networkConnectionError')
    } else {
      errorMessage = error.message || t('video.imageToVideo.optimizeFailed')
    }

    message.error(errorMessage)
  } finally {
    optimizingPrompt.value = false
  }
}

// 创建同款
const createSimilar = () => {
  // 保持当前设置，重新生成
  startGenerate()
}

// 下载视频
const downloadVideo = async () => {
  if (!currentTask.value || !currentTask.value.resultUrl) {
    message.error(t('video.imageToVideo.videoUrlNotAvailable'))
    return
  }
  
  try {
    message.info(t('common.preparingDownload'))
    const { downloadVideo: downloadVideoUtil } = await import('@/utils/download')
    const success = await downloadVideoUtil(currentTask.value.resultUrl, currentTask.value.taskId || Date.now())
    if (success) {
      message.success(t('video.imageToVideo.startDownload'))
    }
  } catch (error) {
    console.error('下载失败:', error)
    window.open(currentTask.value.resultUrl, '_blank')
  }
}

// 下载历史记录中的视频
const downloadHistoryVideo = async (task) => {
  if (!task || !task.resultUrl) {
    message.error(t('video.imageToVideo.videoUrlNotAvailable'))
    return
  }
  
  try {
    message.info(t('common.preparingDownload'))
    const videoUrl = processHistoryUrl(task.resultUrl)
    const { downloadVideo: downloadVideoUtil } = await import('@/utils/download')
    const success = await downloadVideoUtil(videoUrl, task.taskId || Date.now())
    if (success) {
      message.success(t('video.imageToVideo.startDownload'))
    }
  } catch (error) {
    console.error('下载失败:', error)
    window.open(processHistoryUrl(task.resultUrl), '_blank')
  }
}

// 重新生成（复用原task_id和已上传的图片）
const retryTask = async () => {
  // 检查是否有失败的任务可以重试
  if (!currentTask.value || !currentTask.value.taskId) {
    message.error(t('common.noRetryableTask'))
    return
  }
  
  const taskId = currentTask.value.taskId
  console.log('[Retry] 开始重试任务:', taskId)
  
  // 显示加载状态
  const LoadingOutlined = ElLoading.service({
    lock: true,
    text: t('common.regenerating'),
    background: 'rgba(0, 0, 0, 0.7)'
  })
  
  try {
    // 调用后端重试API，复用原task_id和已上传的图片
    const response = await imageToVideoApi.retryTask(taskId)
    
    if (response.data && response.data.success) {
      // 更新任务状态
      currentTask.value = response.data.data
      inProgress.value = true
      taskProgress.value = 0
      taskStatus.value = 'PROCESSING'  // 直接显示生成中
      
      message.success(t('common.retrySubmitted'))
      
      // 开始轮询任务状态
      startPollingTask()
    } else {
      const errorMsg = response.data?.message || t('common.retryFailed')
      message.error(errorMsg)
    }
  } catch (error) {
    console.error('[Retry] 重试任务失败:', error)
    message.error(error.response?.data?.message || error.message || t('common.retryFailed'))
  } finally {
    loading.close()
  }
}

// 投稿功能（已移除按钮，保留函数已删除）

// 删除作品
const deleteWork = async () => {
  if (!currentTask.value) {
    message.error(t('video.imageToVideo.noWorkToDelete'))
    return
  }

  try {
    // 确认删除
    await new Promise((resolve, reject) => {
      Modal.confirm({
        title: t('video.imageToVideo.confirmDelete'),
        content: t('video.imageToVideo.confirmDeleteWork'),
        okText: t('common.delete'),
        cancelText: t('common.cancel'),
        onOk() { resolve() },
        onCancel() { reject('cancel') }
      })
    })
    
    // 调用删除 API
    const taskId = currentTask.value.taskId
    const response = await imageToVideoApi.deleteTask(taskId)
    
    if (response.data && response.data.success) {
      // 重置状态
      currentTask.value = null
      taskStatus.value = ''
      inProgress.value = false
      taskProgress.value = 0
      message.success(t('video.imageToVideo.workDeleted'))
      
      // 刷新历史记录
      loadHistory()
    } else {
      throw new Error(response.data?.message || t('video.imageToVideo.deleteFailed'))
    }
  } catch (error) {
    if (error !== 'cancel' && error !== 'close') {
      console.error('删除作品失败:', error)
      message.error(error.message || t('video.imageToVideo.deleteFailed'))
    }
  }
}

// 处理历史记录URL
const processHistoryUrl = (url) => {
  if (!url) return ''
  // data: 协议（Base64 图片等）直接返回，避免被当成相对路径错误加前缀
  if (url.startsWith('data:')) {
    return url
  }
  // 如果是相对路径，确保格式正确
  if (url.startsWith('/') || !url.startsWith('http')) {
    if (!url.startsWith('/uploads/') && !url.startsWith('/api/')) {
      return url.startsWith('/') ? url : `/${url}`
    }
  }
  return url
}

// 加载历史记录（从user_works表获取IMAGE_TO_VIDEO类型的作品）
const loadHistory = async () => {
  // 只有登录用户才能查看历史记录
  if (!userStore.isAuthenticated) {
    historyTasks.value = []
    return
  }

  try {
    // 从user_works表获取IMAGE_TO_VIDEO类型的作品
    const response = await getMyWorksByType('IMAGE_TO_VIDEO', { page: 0, size: 1000 })
    console.log('历史记录API响应:', response.data)
    if (response.data && response.data.success) {
      // 转换数据格式，适配历史记录展示
      const works = response.data.data || []
      
      historyTasks.value = works.map(work => ({
        taskId: work.taskId,
        prompt: work.prompt,
        aspectRatio: work.aspectRatio,
        duration: work.duration ? parseInt(work.duration) : 5,
        hdMode: work.quality === 'HD',
        status: work.status,
        resultUrl: work.resultUrl ? processHistoryUrl(work.resultUrl) : null,
        firstFrameUrl: work.thumbnailUrl ? processHistoryUrl(work.thumbnailUrl) : null,
        createdAt: work.createdAt,
        progress: work.status === 'PROCESSING' ? 50 : (work.status === 'COMPLETED' ? 100 : 0)
      }))

      console.log('历史记录加载成功:', historyTasks.value.length, '条')
    }
  } catch (error) {
    console.error('加载历史记录失败:', error)
    historyTasks.value = []
  }
}

// 从历史记录创建同款
const createSimilarFromHistory = async (task) => {
  if (task.prompt) {
    inputText.value = task.prompt
  }
  if (task.aspectRatio) {
    aspectRatio.value = task.aspectRatio
  }
  if (task.duration) {
    duration.value = String(task.duration)
  }
  if (task.hdMode !== undefined) {
    hdMode.value = task.hdMode
  }
  // 如果有首帧图片URL，加载并转换为文件对象
  if (task.firstFrameUrl) {
    firstFrameImage.value = task.firstFrameUrl
    // 尝试从URL加载图片并转换为File对象
    try {
      const response = await fetch(task.firstFrameUrl)
      const blob = await response.blob()
      const fileName = `first_frame_${task.taskId || Date.now()}.${blob.type.split('/')[1] || 'png'}`
      firstFrameFile.value = new File([blob], fileName, { type: blob.type })
      console.log('首帧图片已转换为文件对象:', fileName)
    } catch (error) {
      console.warn('无法从URL加载首帧图片:', error)
      // 即使转换失败，也保留预览图片
    }
  }
  // 滚动到顶部
  window.scrollTo({ top: 0, behavior: 'smooth' })
  message.success(t('video.imageToVideo.historyParamsFilled'))
}

// 取消任务
const cancelTask = async (taskId) => {
  try {
    message.info(t('video.imageToVideo.cancelFeatureTodo'))
    // TODO: 实现取消任务API
  } catch (error) {
    console.error('取消任务失败:', error)
  }
}

// 处理视频加载
const handleVideoLoaded = (event) => {
  // 视频元数据加载完成，可以显示缩略图
  const video = event.target
  video.currentTime = 1 // 跳转到第1秒作为缩略图
  // 监听播放状态
  video.addEventListener('play', () => {
    const taskId = Object.keys(videoRefs.value).find(id => videoRefs.value[id] === video)
    if (taskId) {
      playingVideos.value[taskId] = true
    }
  })
  video.addEventListener('pause', () => {
    const taskId = Object.keys(videoRefs.value).find(id => videoRefs.value[id] === video)
    if (taskId) {
      playingVideos.value[taskId] = false
    }
  })
  video.addEventListener('ended', () => {
    const taskId = Object.keys(videoRefs.value).find(id => videoRefs.value[id] === video)
    if (taskId) {
      playingVideos.value[taskId] = false
      video.currentTime = 1 // 播放结束后回到第1秒作为缩略图
    }
  })
}

// 处理视频加载错误
const handleVideoError = (event) => {
  console.error('历史记录视频加载失败:', event.target.src)
  // 可以在这里添加错误处理逻辑，比如显示占位图
}

// 设置视频引用
const setVideoRef = (taskId, el) => {
  if (el) {
    videoRefs.value[taskId] = el
  }
}

// 切换历史记录视频播放
const toggleHistoryVideo = (task) => {
  const video = videoRefs.value[task.taskId]
  if (!video) return
  
  if (playingVideos.value[task.taskId]) {
    video.pause()
    playingVideos.value[task.taskId] = false
  } else {
    // 解除静音并设置音量，确保有声音
    try {
      video.muted = false
      video.volume = 1
      video.play()
    } catch (_) {
      video.play()
    }
    playingVideos.value[task.taskId] = true
  }
}

// 监听登录状态变化，登录后自动加载历史记录
watch(() => userStore.isAuthenticated, (isAuth) => {
  if (isAuth) {
    loadHistory()
    // 延迟恢复任务，避免与创建任务冲突
    setTimeout(() => {
      if (!isCreatingTask.value) {
        restoreProcessingTask()
      }
    }, 500)
  } else {
    historyTasks.value = []
    hasRestoredTask.value = false
  }
})

// 恢复正在进行中的任务
const restoreProcessingTask = async () => {
  if (!userStore.isAuthenticated) {
    return false
  }
  
  // 如果正在创建任务，跳过恢复逻辑
  if (isCreatingTask.value) {
    console.log('[Task Restore] 跳过恢复：正在创建新任务')
    return false
  }
  
  // 如果已经恢复过任务且当前有任务在进行中，跳过
  if (hasRestoredTask.value && currentTask.value) {
    console.log('[Task Restore] 跳过恢复：已有任务在进行中')
    return true
  }

  try {
    const response = await getProcessingWorks()
    if (response.data && response.data.success && response.data.data) {
      const works = response.data.data
      // 只恢复图生视频类型的任务（包括 PROCESSING 和 PENDING 状态）
      const imageToVideoWorks = works.filter(work => work.workType === 'IMAGE_TO_VIDEO')

      if (imageToVideoWorks.length > 0) {
        // 取最新的一个任务
        const work = imageToVideoWorks[0]

        // 只有真正在进行中的任务才恢复
        const workStatus = work.status || 'PROCESSING'
        if (workStatus === 'PROCESSING' || workStatus === 'PENDING') {
          // 恢复任务状态
          currentTask.value = {
            taskId: work.taskId,
            prompt: work.prompt,
            aspectRatio: work.aspectRatio,
            duration: work.duration,
            resultUrl: work.resultUrl,
            createdAt: work.createdAt
          }

          // 恢复输入参数
          if (work.prompt) {
            inputText.value = work.prompt
          }
          if (work.aspectRatio) {
            aspectRatio.value = work.aspectRatio
          }
          if (work.duration) {
            duration.value = String(work.duration)
          }
          
          // 恢复首帧图片（从 thumbnailUrl 或结果中获取）
          if (work.thumbnailUrl) {
            const imageUrl = processHistoryUrl(work.thumbnailUrl)
            firstFrameImage.value = imageUrl
            console.log('[Task Restore] 已恢复首帧图片:', work.thumbnailUrl)
            // 尝试从URL加载图片并转换为File对象，以便重新生成时可以提交
            try {
              const imgResponse = await fetch(imageUrl)
              const blob = await imgResponse.blob()
              const fileName = `first_frame_${work.taskId || Date.now()}.${blob.type.split('/')[1] || 'png'}`
              firstFrameFile.value = new File([blob], fileName, { type: blob.type })
              console.log('[Task Restore] 首帧图片已转换为文件对象:', fileName)
            } catch (error) {
              console.warn('[Task Restore] 无法从URL加载首帧图片:', error)
            }
          }

          inProgress.value = true
          taskStatus.value = workStatus
          taskProgress.value = 50 // 初始进度设为50%

          console.log('[Task Restored]', work.taskId, 'Status:', workStatus)
          // 静默恢复，不显示弹窗
          
          // 标记已恢复任务
          hasRestoredTask.value = true

          // 开始轮询任务状态
          startPollingTask()
          return true
        } else {
          // 如果任务已完成、失败或取消，不恢复任何参数
          console.log('[Task Skip]', work.taskId, 'Status:', workStatus, '- 不是进行中状态')
          return false
        }
      }
    }
  } catch (error) {
    console.error('[Task Restore Error]', error)
  }
  return false
}

// 检查最近一条任务的状态（如果失败则显示失败状态和参考图）
const checkLastTaskStatus = async () => {
  if (!userStore.isAuthenticated) return

  try {
    const response = await imageToVideoApi.getTasks(0, 1)
    if (response.data && response.data.success && response.data.data && response.data.data.length > 0) {
      const lastTask = response.data.data[0]
      
      // 只关注 FAILED 状态，显示失败UI和参考图
      if (lastTask.status === 'FAILED') {
        console.log('[Last Task Failed]', lastTask)
        
        currentTask.value = lastTask
        taskStatus.value = 'FAILED'
        
        // 恢复提示词，让用户看到失败任务的内容
        if (lastTask.prompt) {
          inputText.value = lastTask.prompt
        }
        // 恢复首帧图片（参考图）
        if (lastTask.firstFrameUrl) {
          const imageUrl = processHistoryUrl(lastTask.firstFrameUrl)
          firstFrameImage.value = imageUrl
          // 尝试从URL加载图片并转换为File对象，以便重试时可以提交
          try {
            const response = await fetch(imageUrl)
            const blob = await response.blob()
            const fileName = `first_frame_${lastTask.taskId || Date.now()}.${blob.type.split('/')[1] || 'png'}`
            firstFrameFile.value = new File([blob], fileName, { type: blob.type })
            console.log('[Last Task] 首帧图片已转换为文件对象:', fileName)
          } catch (error) {
            console.warn('[Last Task] 无法从URL加载首帧图片:', error)
          }
        }
        // 恢复其他参数
        if (lastTask.aspectRatio) {
          aspectRatio.value = lastTask.aspectRatio
        }
        if (lastTask.duration) {
          duration.value = String(lastTask.duration)
        }
      }
      // 如果最近一条任务是成功的，不需要处理
    }
  } catch (error) {
    console.error('CheckOutlined last task status error', error)
  }
}

// 标记是否已完成首次加载（用于 watch 判断）
const isInitialized = ref(false)

// 处理全局点击事件，关闭用户菜单
const handleClickOutside = (event) => {
  if (!showUserMenu.value) return
  
  // 检查点击是否在用户头像或菜单内
  const menuElement = document.querySelector('.user-menu-teleport')
  const avatarElement = userAvatarRef.value
  
  if (menuElement && menuElement.contains(event.target)) {
    // 点击在菜单内，不关闭
    return
  }
  
  if (avatarElement && avatarElement.contains(event.target)) {
    // 点击在头像上，不关闭（由 toggleUserMenu 处理）
    return
  }
  
  // 点击在外部，关闭菜单
  showUserMenu.value = false
}

onMounted(async () => {
  // 只有已登录用户才刷新用户信息
  if (userStore.isAuthenticated) {
    await userStore.fetchCurrentUser()
  }
  
  // 标记是否从"做同款"或"生视频"进入（有路由参数）
  const isFromExternalEntry = !!(route.query.prompt || route.query.referenceImage)
  
  // 处理"做同款"传递的路由参数
  if (isFromExternalEntry) {
    console.log('[做同款/生视频] 接收参数:', route.query)
    
    if (route.query.prompt) {
      inputText.value = route.query.prompt
    }
    if (route.query.aspectRatio) {
      aspectRatio.value = route.query.aspectRatio
    }
    if (route.query.duration) {
      duration.value = route.query.duration
    }
    
    // 处理参考图
    if (route.query.referenceImage) {
      firstFrameImage.value = route.query.referenceImage
      console.log('[做同款/生视频] 设置参考图:', route.query.referenceImage)
      // 注意：firstFrameFile 为 null，用户需要重新上传或点击生成时会提示
    }
    
    // 静默填充，不显示弹窗提示（减少干扰）
    // 清除URL中的query参数，避免刷新页面重复填充
    router.replace({ path: route.path })
  }
  
  loadHistory()
  // 延迟恢复任务，避免与创建任务冲突
  // 注意：如果是从"做同款"或"生视频"进入，不恢复正在进行的任务，让用户开始新任务
  setTimeout(async () => {
    if (!isCreatingTask.value && !isFromExternalEntry) {
      const restored = await restoreProcessingTask()
      // 如果没有恢复进行中的任务，则检查最近一条是否失败
      if (!restored) {
        checkLastTaskStatus()
      }
    }
    // 标记初始化完成
    isInitialized.value = true
  }, 500)
  
  // 添加全局点击监听器
  document.addEventListener('click', handleClickOutside)
})

// 监听路由参数变化（同一页面内跳转时触发）
watch(() => route.query._t, (newT, oldT) => {
  // 只在初始化完成后且有新的时间戳时触发
  if (!isInitialized.value || !newT || newT === oldT) {
    return
  }
  
  console.log('[路由参数变化] 检测到新参数:', route.query)
  
  // 停止当前轮询（如果有）
  if (stopPolling.value) {
    stopPolling.value()
    stopPolling.value = null
  }
  
  // 重置状态
  inProgress.value = false
  taskId.value = ''
  taskStatus.value = ''
  resultUrl.value = ''
  
  // 应用新参数
  if (route.query.prompt) {
    inputText.value = route.query.prompt
  }
  if (route.query.aspectRatio) {
    aspectRatio.value = route.query.aspectRatio
  }
  if (route.query.duration) {
    duration.value = route.query.duration
  }
  if (route.query.referenceImage) {
    firstFrameImage.value = route.query.referenceImage
    console.log('[路由参数变化] 设置参考图')
  }
  
  // 清除URL中的query参数
  router.replace({ path: route.path })
  
  message.success(t('works.readyToGenerateVideo'))
})

// 组件卸载时清理资源
onUnmounted(() => {
  // 停止轮询
  if (stopPolling.value) {
    stopPolling.value()
    stopPolling.value = null
  }
  
  // 移除全局点击监听器
  document.removeEventListener('click', handleClickOutside)
})
</script>

<style scoped>
/* 图片懒加载样式 */
.lazy-LoadingOutlined {
  background: linear-gradient(90deg, var(--bg-surface) 25%, var(--bg-elevated) 50%, var(--bg-surface) 75%);
  background-size: 200% 100%;
  animation: lazy-shimmer 1.5s infinite;
}

.lazy-loaded {
  animation: lazy-fade-in 0.3s ease-in;
}

.lazy-error {
  background: var(--bg-surface);
}

@keyframes lazy-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@keyframes lazy-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.image-to-video-create-page {
  height: 100vh;
  background: var(--bg-base);
  color: var(--text-primary);
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  font-family: var(--font-sans);
}

/* 主内容区域 */
.main-content {
  flex: 1;
  display: grid;
  grid-template-columns: 520px 1fr;
  gap: 0;
  height: calc(100vh - 100px);
}

/* 左侧面板 */
.left-panel {
  background: var(--bg-surface);
  border-right: 1px solid var(--border-subtle);
  padding: 32px;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  overflow: hidden;
}

/* 左侧面板内容区域（可滚动） */
.left-panel-content {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding-right: 8px;
}

/* 优化滚动条样式 */
.left-panel-content::-webkit-scrollbar {
  width: 8px;
}

.left-panel-content::-webkit-scrollbar-track {
  background: var(--bg-base);
  border-radius: var(--radius-xs);
}

.left-panel-content::-webkit-scrollbar-thumb {
  background: var(--bg-overlay);
  border-radius: var(--radius-xs);
}

.left-panel-content::-webkit-scrollbar-thumb:hover {
  background: var(--bg-overlay);
}

/* 图片输入区域 */
.image-input-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.image-upload-area {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
}

.upload-box {
  flex: none;
  width: 240px;
  max-width: 100%;
  aspect-ratio: 1;
  background: var(--bg-base);
  border: 2px dashed var(--border-subtle);
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: var(--transition-all);
  position: relative;
  overflow: hidden;
}

.upload-box:hover {
  border-color: var(--primary-500);
  background: var(--bg-surface);
}

.upload-box.drag-over {
  border-color: var(--primary-500);
  background: var(--primary-glow-light);
  border-style: solid;
}

.upload-box.optional {
  opacity: 0.7;
}

.upload-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

.upload-icon {
  font-size: var(--text-3xl);
  color: var(--text-muted);
  font-weight: 300;
  margin-bottom: 8px;
}

.upload-text {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  font-weight: var(--font-medium);
}

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

.upload-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 10px;
}

.arrow-icon {
  font-size: var(--text-xl);
  color: var(--text-muted);
  font-weight: var(--font-bold);
}


.remove-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.8);
  color: var(--text-primary);
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-lg);
  font-weight: var(--font-bold);
  z-index: 10;
  transition: var(--transition-all);
}

.remove-btn:hover {
  background: rgba(239, 68, 68, 0.9);
  transform: scale(1.1);
}

/* 文本输入区域 */
.text-input-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.text-input {
  width: 100%;
  min-height: 120px;
  padding: 16px;
  background: var(--bg-base);
  border: 2px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  color: var(--text-primary);
  font-size: var(--text-sm);
  line-height: 1.6;
  resize: vertical;
  outline: none;
  transition: var(--transition-all);
  font-family: inherit;
}

.text-input:focus {
  border-color: var(--primary-500);
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.text-input::placeholder {
  color: var(--text-muted);
}

.input-tips {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: 12px;
  background: rgba(59, 130, 246, 0.05);
  border-radius: var(--radius-md);
  border: 1px solid rgba(59, 130, 246, 0.2);
}

.tip-item {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  line-height: 1.5;
}

.tip-item:first-child {
  color: var(--primary-400);
  font-weight: var(--font-medium);
}

.optimize-btn {
  display: flex;
  justify-content: flex-end;
}

.optimize-button {
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: var(--text-primary);
  border: none;
  padding: 10px 20px;
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  transition: var(--transition-all);
  box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
}

.optimize-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

/* 视频设置 */
.video-settings {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.setting-item {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.setting-item label {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-weight: var(--font-semibold);
}

.setting-select {
  padding: 12px 16px;
  background: var(--bg-base);
  border: 2px solid var(--border-subtle);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-size: var(--text-sm);
  outline: none;
  cursor: pointer;
  transition: var(--transition-all);
  font-family: inherit;
}

.setting-select:focus {
  border-color: var(--primary-500);
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.setting-select:hover {
  border-color: var(--border-strong);
}

.hd-SettingOutlined {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.cost-text {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  font-weight: var(--font-medium);
}


/* 右侧面板 */
.right-panel {
  background: var(--bg-base);
  padding: 32px;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
}

/* 自定义右侧面板滚动条样式 */
.right-panel::-webkit-scrollbar {
  width: 8px;
}

.right-panel::-webkit-scrollbar-track {
  background: var(--bg-surface);
  border-radius: var(--radius-xs);
}

.right-panel::-webkit-scrollbar-thumb {
  background: var(--primary-500);
  border-radius: var(--radius-xs);
}

.right-panel::-webkit-scrollbar-thumb:hover {
  background: var(--primary-600);
}

.preview-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-height: min-content;
}

.status-checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: 8px;
}

.status-checkbox input[type="checkbox"] {
  width: 18px;
  height: 18px;
  cursor: pointer;
  accent-color: var(--primary-500);
}

.status-checkbox label {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  cursor: pointer;
  font-weight: var(--font-medium);
}

.preview-content {
  background: var(--bg-surface);
  border: 2px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--transition-all);
  padding: 24px;
  margin-bottom: 20px;
  width: 80%;
  max-width: 1000px;
  min-height: 300px;
}

.preview-content:hover {
  border-color: var(--border-strong);
}

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

.placeholder-text {
  font-size: var(--text-xl);
  color: var(--text-tertiary);
  font-weight: var(--font-medium);
  line-height: 1.6;
}


/* 任务状态样式 */
.task-status {
  background: var(--bg-surface);
  border: 2px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 24px;
  margin-bottom: 20px;
  width: 80%;
  max-width: 1000px;
  min-height: 300px;
  box-sizing: border-box;
}

.status-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border-subtle);
}

.status-header h3 {
  color: var(--text-primary);
  font-size: var(--text-lg);
  font-weight: var(--font-semibold);
  margin: 0;
}

.task-id {
  color: var(--text-tertiary);
  font-size: var(--text-xs);
  font-family: monospace;
}

.status-info {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: 20px;
}

.status-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.status-item .label {
  color: var(--text-tertiary);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
}

.status-item .value {
  color: var(--text-primary);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
}

/* 状态颜色 */
.status-pending {
  color: var(--warning-500) !important;
}

.status-processing {
  color: var(--primary-500) !important;
}

.status-completed {
  color: var(--accent-500) !important;
}

.status-failed {
  color: var(--error-500) !important;
}

.status-cancelled {
  color: var(--text-muted) !important;
}

/* 进度条 */
.progress-bar {
  width: 100%;
  height: 8px;
  background: var(--bg-hover);
  border-radius: var(--radius-xs);
  overflow: hidden;
  margin-bottom: 20px;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #3b82f6, #1d4ed8);
  border-radius: var(--radius-xs);
  transition: width 0.3s ease;
  position: relative;
}

.progress-fill::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
  animation: progress-shine 2s infinite;
}

@keyframes progress-shine {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}

/* 任务操作按钮 */
.task-actions {
  display: flex;
  gap: var(--space-3);
}


/* 任务描述样式 - 和历史记录提示词一致 */
.task-description {
  color: var(--text-secondary);
  font-size: var(--text-sm);
  line-height: 1.6;
  margin-bottom: 16px;
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* 视频预览容器 */
.video-preview-container {
  background: var(--bg-surface);
  border: 2px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  min-height: 200px;
  max-height: 50vh;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 15px 0;
  overflow: hidden;
  width: 80%;
  max-width: 1000px;
  margin-left: 0;
  margin-right: auto;
}

/* 生成中状态 */
.generating-container {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.generating-placeholder {
  text-align: center;
  padding: 40px;
}

.generating-text {
  font-size: var(--text-lg);
  color: var(--primary-500);
  font-weight: var(--font-semibold);
  margin-bottom: 20px;
}

.progress-bar-large {
  width: 200px;
  height: 8px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-xs);
  overflow: hidden;
}

.progress-fill-large {
  height: 100%;
  background: linear-gradient(90deg, #3b82f6, #1d4ed8);
  border-radius: var(--radius-xs);
  transition: width 0.3s ease;
  position: relative;
}

/* 生成中进度条动态动画 - 使用蓝绿渐变风格 */
.progress-fill-large.animated {
  background: linear-gradient(90deg, #409eff, #67c23a, #409eff);
  background-size: 200% 100%;
  animation: progress-move 1.5s ease-in-out infinite, progress-gradient 2s linear infinite;
}

/* 不确定进度条（排队中） */
.progress-bar-large.indeterminate {
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}

.progress-fill-indeterminate {
  width: 30%;
  height: 100%;
  background: linear-gradient(90deg, transparent, #409eff, #67c23a, #409eff, transparent);
  border-radius: var(--radius-xs);
  animation: progress-move 1.5s ease-in-out infinite;
}

/* 进度百分比文字 */
.progress-percentage {
  font-size: var(--text-sm);
  color: var(--primary-400);
  font-weight: var(--font-semibold);
  margin-top: 12px;
  text-align: center;
}

/* 历史记录进度条 */
.history-progress-bar {
  width: 80%;
  max-width: 200px;
  height: 6px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 3px;
  overflow: hidden;
  margin: 12px 0;
}

.history-progress-bar.indeterminate .progress-fill-indeterminate {
  width: 30%;
  height: 100%;
  background: linear-gradient(90deg, transparent, #409eff, #67c23a, #409eff, transparent);
  border-radius: 3px;
  animation: progress-move 1.5s ease-in-out infinite;
}

.history-progress-bar .progress-fill-large {
  height: 100%;
  background: linear-gradient(90deg, #409eff, #67c23a, #409eff);
  background-size: 200% 100%;
  border-radius: 3px;
  animation: progress-move 1.5s ease-in-out infinite, progress-gradient 2s linear infinite;
}

/* 完成状态 */
.completed-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 0;
}

/* 任务信息头部 */
.task-info-header {
  margin-bottom: 15px;
}

.task-checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.task-checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--primary-500);
}

.task-checkbox label {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  cursor: pointer;
  font-weight: var(--font-medium);
}

/* 视频播放容器 */
.video-player-container {
  flex: 1;
  position: relative;
  margin-bottom: 20px;
}

.video-player {
  position: relative;
  width: 80%;
  max-width: 1000px;
  aspect-ratio: 16/9;
  background: var(--bg-base);
  border-radius: var(--radius-md);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.result-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.no-video-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-tertiary);
}

.no-video-text {
  font-size: var(--text-base);
  font-weight: var(--font-medium);
}

/* 操作按钮区域 */
.result-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.action-buttons {
  display: flex;
  gap: var(--space-3);
}

.action-btn {
  padding: 10px 20px;
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  cursor: pointer;
  transition: var(--transition-all);
  border: none;
}

.action-btn.primary {
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: var(--text-primary);
}

.action-btn.primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

.action-icons {
  display: flex;
  gap: var(--space-2);
}

.icon-btn {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: var(--text-secondary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--transition-all);
}

.icon-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-1px);
}

.icon-btn svg {
  width: 16px;
  height: 16px;
}

/* 失败状态 */
.failed-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px;
}

.failed-placeholder {
  text-align: center;
  margin-bottom: 20px;
}

.failed-icon {
  font-size: var(--text-5xl);
  margin-bottom: 16px;
}

.failed-text {
  font-size: var(--text-xl);
  color: var(--error-500);
  font-weight: var(--font-semibold);
  margin-bottom: 8px;
}

.failed-desc {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
}

.failed-reason {
  margin-top: 16px;
  padding: 12px 16px;
  background: rgba(239, 68, 68, 0.1);
  border-radius: var(--radius-md);
  border: 1px solid rgba(239, 68, 68, 0.2);
  text-align: left;
  max-width: 400px;
  margin-left: auto;
  margin-right: auto;
}

.failed-reason .reason-label {
  color: var(--error-500);
  font-weight: var(--font-medium);
  font-size: var(--text-xs);
}

.failed-reason .reason-text {
  color: var(--error-400);
  font-size: var(--text-xs);
  word-break: break-word;
}

/* 其他状态 */
.status-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.status-text {
  font-size: var(--text-lg);
  color: var(--text-tertiary);
  font-weight: var(--font-medium);
}

/* 任务控制 */
.task-controls {
  margin-top: 15px;
  text-align: center;
}

/* 历史记录区域 */
.history-section {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--border-subtle);
}

.history-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.history-item {
  background: transparent;
  border: none;
  padding: 0;
  transition: var(--transition-all);
  width: 100%;
  max-width: none;
}

.history-status-checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: 12px;
}

.history-status-checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: default;
  accent-color: var(--primary-500);
}

.history-status-checkbox label {
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  cursor: default;
}

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

.history-type {
  color: var(--primary-500);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
}

.history-date {
  color: var(--text-tertiary);
  font-size: var(--text-xs);
}

.history-prompt {
  color: var(--text-secondary);
  font-size: var(--text-sm);
  line-height: 1.6;
  margin-bottom: 16px;
  white-space: pre-wrap;
  word-wrap: break-word;
  width: 80%;
  max-width: 1000px;
}

.history-preview {
  width: 80%;
  max-width: 1000px;
  aspect-ratio: 16/9;
  background: var(--bg-base);
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: 16px;
  position: relative;
}


.history-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--bg-base);
  color: var(--text-primary);
  gap: var(--space-3);
}

.queue-text {
  font-size: var(--text-lg);
  font-weight: var(--font-semibold);
  color: var(--text-primary);
}

.queue-link {
  font-size: var(--text-sm);
  color: var(--primary-500);
  cursor: pointer;
  text-decoration: none;
}

.queue-link:hover {
  color: var(--primary-400);
  text-decoration: underline;
}

.cancel-btn {
  padding: 8px 24px;
  background: transparent;
  color: var(--text-primary);
  border: 1px solid #fff;
  border-radius: var(--radius-xs);
  font-size: var(--text-sm);
  cursor: pointer;
  margin-top: 8px;
  transition: var(--transition-all);
}

.cancel-btn:hover {
  background: rgba(255, 255, 255, 0.1);
}

.no-result-text {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.history-video-thumbnail {
  width: 100%;
  height: 100%;
  position: relative;
  cursor: pointer;
  overflow: hidden;
}

.history-video-thumbnail video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  cursor: pointer;
  display: block;
}

.history-image-thumbnail {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}

.history-image-thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.play-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity var(--duration-normal) var(--ease-default);
}

.history-video-thumbnail:hover .play-overlay {
  opacity: 1;
}

.play-icon {
  width: 48px;
  height: 48px;
  background: rgba(59, 130, 246, 0.9);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-primary);
  font-size: var(--text-xl);
  padding-left: 4px;
}

.history-actions {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  gap: var(--space-2);
  margin-top: 0;
}

.similar-btn {
  padding: 10px 20px;
  background: var(--bg-hover);
  color: var(--text-secondary);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  cursor: pointer;
  transition: var(--transition-all);
}

.similar-btn:hover {
  background: var(--bg-overlay);
  border-color: var(--border-strong);
}

.download-btn {
  width: 36px;
  height: 36px;
  background: var(--text-primary);
  color: var(--text-inverse);
  border: none;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: var(--transition-all);
  box-shadow: var(--shadow-sm);
}

.download-btn:hover {
  background: var(--text-secondary);
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .main-content {
    grid-template-columns: 420px 1fr;
  }
  
  .left-panel {
    padding: 24px;
  }
  
  .right-panel {
    padding: 24px;
  }
}

@media (max-width: 1024px) {
  .main-content {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }
  
  .left-panel {
    border-right: none;
    border-bottom: 1px solid var(--border-subtle);
    padding: 20px;
  }
  
  .right-panel {
    padding: 20px;
  }
}

@media (max-width: 768px) {
  .top-header {
    padding: 16px 20px;
  }
  
  .header-right {
    gap: var(--space-4);
  }
  
  .left-panel {
    padding: 16px;
    gap: var(--space-6);
  }
  
  .right-panel {
    padding: 16px;
  }
  
  .creation-tabs {
    flex-direction: column;
    gap: var(--space-2);
  }
  
  .tab {
    text-align: left;
  }
  
  .image-upload-area {
    flex-direction: column;
    gap: var(--space-3);
  }
  
  .arrow-icon {
    transform: rotate(90deg);
  }
}
</style>

<!-- 非 scoped 样式用于 @keyframes 动画 -->
<style>
@keyframes progress-move {
  0% { transform: translateX(-100%); }
  50% { transform: translateX(233%); }
  100% { transform: translateX(-100%); }
}

@keyframes progress-gradient {
  0% { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}
</style>
