<template>
  <div class="profile-page">
    <SidebarNav active="profile" />
    
    <!-- 主内容区域 -->
    <main class="main-content">
      <!-- 顶部栏 -->
      <TopHeader ref="topHeaderRef" @avatar-click="showUserMenu = !showUserMenu" />
      
      <!-- 用户资料区域 -->
      <section class="profile-section">
        <div class="profile-info">
          <div class="avatar">
            <img src="/images/backgrounds/avatar-default.svg" :alt="t('dashboard.userAvatar')" class="avatar-image" />
          </div>
          <div class="user-details">
            <h2 class="username">{{ userInfo.email || t('profile.noUsername') }}</h2>
            <p class="profile-status" v-if="userInfo.bio">{{ userInfo.bio }}</p>
          </div>
        </div>
      </section>

      <!-- 已发布内容 -->
      <section class="published-section">
        <div class="section-header">
          <h3 class="section-title">{{ t('profile.published') }}</h3>
          <div class="section-actions" v-if="videos.length > 0">
            <a-button v-if="!batchSelectMode" size="small" @click="toggleBatchMode">
              <CheckOutlined /> 管理
            </a-button>
            <template v-else>
              <a-button size="small" @click="selectAllWorks">
                {{ isAllSelected ? '取消全选' : '全选' }}
              </a-button>
              <a-button size="small" @click="toggleBatchMode">
                <CloseOutlined /> 取消
              </a-button>
            </template>
          </div>
        </div>
        <div class="video-grid">
          <div
            class="video-item"
            :class="{ 'is-selected': batchSelectMode && selectedWorkIds.has(video.id) }"
            v-for="(video, index) in videos"
            :key="video.id || index"
            :spinning="loading"
            @click="batchSelectMode ? toggleSelectWork(video.id) : null"
          >
            <div class="video-thumbnail" @click="batchSelectMode ? null : openDetail(video)">
              <!-- 批量选择复选框 -->
              <div v-if="batchSelectMode" class="batch-checkbox" @click.stop="toggleSelectWork(video.id)">
                <div class="checkbox-inner" :class="{ checked: selectedWorkIds.has(video.id) }">
                  <CheckOutlined v-if="selectedWorkIds.has(video.id)" />
                </div>
              </div>
              <div class="thumbnail-image">
                <!-- 失败状态显示 -->
                <div v-if="video.status === 'FAILED'" class="failed-overlay">
                  <div class="failed-icon">❌</div>
                  <div class="failed-text">生成失败</div>
                </div>
                <!-- 处理中状态显示 -->
                <div v-else-if="video.status === 'PROCESSING' || video.status === 'PENDING'" class="processing-overlay">
                  <div class="processing-icon">⏳</div>
                  <div class="processing-text">{{ video.status === 'PENDING' ? '排队中' : '生成中' }}</div>
                  <!-- 动态进度条 -->
                  <div class="progress-bar-container">
                    <div class="progress-bar-animated"></div>
                  </div>
                </div>
                <!-- 缩略图：统一使用 <img> 加载，避免 <video> 加载完整视频文件 -->
                <img 
                  v-else-if="video.thumbnailCover" 
                  :src="video.thumbnailCover"
                  :alt="video.title"
                  class="video-cover-img"
                  loading="lazy"
                  @error="onImageError"
                />
                <!-- 无可用缩略图时显示占位符 -->
                <div v-else class="video-placeholder">
                  <svg width="48" height="48" viewBox="0 0 24 24" fill="rgba(255,255,255,0.5)">
                    <path d="M8 5v14l11-7z"/>
                  </svg>
                </div>
              </div>
              <div class="video-action" v-if="video.status === 'COMPLETED'">
                <!-- 左侧按钮组：做同款 + 下载 + 删除 -->
                <div class="action-left">
                  <a-button type="primary" size="small" @click.stop="createSimilar(video)">{{ t('profile.createSimilar') }}</a-button>
                  <a-button text size="small" @click.stop="downloadWork(video)">{{ t('video.download') }}</a-button>
                  <a-button text size="small" type="danger" @click.stop="handleDeleteWork(video)"><DeleteOutlined /> {{ t('common.delete') }}</a-button>
                </div>
                <!-- 生视频按钮 - 右侧（仅分镜图显示） -->
                <a-button v-if="video.category === '分镜图' || video.workType === 'STORYBOARD_IMAGE'" type="success" size="small" @click.stop="goToGenerateVideo(video)">{{ t('video.storyboard.generateVideo') }}</a-button>
              </div>
              <div class="video-action" v-else-if="video.status === 'FAILED'">
                <span class="status-text failed">生成失败</span>
                <a-button text size="small" type="danger" @click.stop="handleDeleteWork(video)"><DeleteOutlined /> {{ t('common.delete') }}</a-button>
              </div>
              <div class="video-action" v-else>
                <span class="status-text processing">{{ video.status === 'PENDING' ? '排队中...' : '生成中...' }}</span>
                <a-button text size="small" type="danger" @click.stop="handleDeleteWork(video)"><DeleteOutlined /> {{ t('common.delete') }}</a-button>
              </div>
            </div>
          </div>
          <div v-if="!LoadingOutlined && videos.length === 0" class="empty-works">
            <div class="empty-text">{{ t('profile.noWorksYet') }}</div>
          </div>
        </div>
      </section>

      <!-- 批量删除底部操作栏 -->
      <Transition name="slide-up">
        <div v-if="batchSelectMode && selectedWorkIds.size > 0" class="batch-toolbar">
          <span class="batch-info">已选择 <strong>{{ selectedWorkIds.size }}</strong> 个作品</span>
          <a-button type="primary" danger size="small" @click="handleBatchDelete">
            <DeleteOutlined /> 批量删除
          </a-button>
        </div>
      </Transition>
    </main>

    <!-- 作品详情弹窗（与“我的作品”一致风格的精简版） -->
    <a-modal
      v-model:open="detailDialogVisible"
      :title="selectedItem?.title"
      width="60%"
      class="detail-dialog"
      :mask-closable="true"
      :keyboard="true"
      :footer="null"
    >
    <div class="detail-content" v-if="selectedItem">
      <div class="detail-left">
        <video 
          v-if="selectedItem.type === 'video'"
          class="detail-video"
          :src="selectedItem.resultUrl || selectedItem.cover"
          :poster="selectedItem.cover"
          controls
        >
          {{ t('profile.browserNotSupport') }}
        </video>
        <img 
          v-else
          class="detail-image"
          :src="selectedItem.cover" 
          :alt="selectedItem.title"
        />
      </div>
      
      <div class="detail-right">
        <div class="detail-header">
          <div class="user-info">
            <div class="avatar">
              <img src="/images/backgrounds/avatar-default.svg" :alt="t('dashboard.userAvatar')" class="avatar-image" />
            </div>
            <div class="username">{{ (selectedItem && selectedItem.username) || t('profile.anonymousUser') }}</div>
          </div>
        </div>

        <div class="tabs">
          <div class="tab active">{{ t('profile.workDetail') }}</div>
          <span class="category-label">{{ selectedItem.category }}</span>
        </div>

        <div class="description-section">
          <h3 class="section-title">{{ t('video.prompt') }}</h3>
          <p class="description-text">{{ getDescription(selectedItem) }}</p>
        </div>

        <div class="metadata-section">
          <div class="metadata-item">
            <span class="label">{{ t('profile.createTime') }}</span>
            <span class="value">{{ selectedItem.createTime }}</span>
          </div>
          <div class="metadata-item">
            <span class="label">{{ t('profile.workId') }}</span>
            <span class="value">{{ selectedItem.id }}</span>
          </div>
          <div class="metadata-item">
            <span class="label">{{ t('profile.date') }}</span>
            <span class="value">{{ selectedItem.date }}</span>
          </div>
          <div class="metadata-item">
            <span class="label">{{ t('profile.category') }}</span>
            <span class="value">{{ selectedItem.category }}</span>
          </div>
          <div class="metadata-item" v-if="selectedItem.type === 'video'">
            <span class="label">{{ t('profile.duration') }}</span>
            <span class="value">{{ formatDuration(selectedItem.duration) || t('profile.unknown') }}</span>
          </div>
          <div class="metadata-item" v-if="selectedItem.type === 'video'">
            <span class="label">{{ t('profile.quality') }}</span>
            <span class="value">{{ selectedItem.quality || t('profile.unknown') }}</span>
          </div>
          <div class="metadata-item" v-if="selectedItem.type === 'video'">
             <span class="label">{{ t('profile.aspectRatio') }}</span>
             <span class="value">{{ selectedItem.aspectRatio || t('profile.unknown') }}</span>
           </div>
        </div>
      </div>
    </div>
    </a-modal>
  
    <!-- 用户菜单下拉 - 使用Teleport渲染到body -->
    <Teleport to="body">
    <div v-if="showUserMenu" class="user-menu-teleport" :style="menuStyle">
      <!-- 管理员功能 -->
      <template v-if="userStore.isAdmin">
        <div class="menu-item" @click.stop="goToDashboard">
          <UserOutlined />
          <span>{{ t('profile.dashboard') }}</span>
        </div>
        <div class="menu-item" @click.stop="goToOrders">
          <FileOutlined />
          <span>{{ t('profile.orderManagement') }}</span>
        </div>
        <div class="menu-item" @click.stop="goToMembers">
          <UserOutlined />
          <span>{{ t('profile.memberManagement') }}</span>
        </div>
        <div class="menu-item" @click.stop="goToSettings">
          <SettingOutlined />
          <span>{{ t('profile.systemSettings') }}</span>
        </div>
        <div class="menu-item" @click.stop="goToErrorStats">
          <WarningOutlined />
          <span>{{ $t('nav.errorStats') }}</span>
        </div>
        <div class="menu-item" @click.stop="goToApiManagement">
          <FileOutlined />
          <span>{{ t('nav.apiManagement') }}</span>
        </div>
        <div class="menu-item" @click.stop="goToTaskRecord">
          <FileOutlined />
          <span>{{ t('nav.tasks') }}</span>
        </div>
        <div class="menu-item" @click.stop="goToWorkflowVideos">
          <VideoCameraOutlined />
          <span>{{ t('nav.workflowVideos') }}</span>
        </div>
      </template>
      <!-- 修改密码（所有登录用户可见） -->
      <div class="menu-item" @click.stop="goToChangePassword" style="cursor: pointer; pointer-events: auto;">
        <LockOutlined />
        <span>{{ t('profile.changePassword') }}</span>
      </div>
      <!-- 退出登录 -->
      <div class="menu-item" @click.stop="logout">
        <UserOutlined />
        <span>{{ t('common.logout') }}</span>
      </div>
    </div>
    </Teleport>
  </div>

</template>

<script setup>
import { ref, onMounted, onUnmounted, computed, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores/user'
import { message, Modal } from 'ant-design-vue'
import {
  UserOutlined,
  FileOutlined,
  SettingOutlined,
  LockOutlined,
  CompassOutlined,
  PlayCircleOutlined,
  PictureOutlined,
  VideoCameraOutlined,
  WarningOutlined,
  DeleteOutlined,
  CheckOutlined,
  CloseOutlined
} from '@ant-design/icons-vue'
import { getMyWorks, deleteWork, batchDeleteWorks } from '@/api/userWorks'
import TopHeader from '@/components/TopHeader.vue'
import SidebarNav from '@/components/SidebarNav.vue'
import { getCurrentUser, changePassword } from '@/api/auth'
import { getWorkDetail } from '@/api/userWorks'
import { useI18n } from 'vue-i18n'
import { downloadVideo, downloadImage } from '@/utils/download'

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

// 控制用户菜单显示
const showUserMenu = ref(false)
const topHeaderRef = ref(null)

// 用户信息
const userInfo = ref({
  username: '',
  nickname: '',
  email: '',
  bio: '',
  avatar: '',
  id: '',
  points: 0,
  frozenPoints: 0
})

// 跳转到修改密码页面
const goToChangePassword = () => {
  showUserMenu.value = false
  console.log('准备跳转到 /change-password')
  router.push('/change-password').then(() => {
    console.log('跳转成功')
  }).catch(err => {
    console.error('跳转失败:', err)
    message.error(t('common.redirectFailed') + ': ' + err.message)
  })
}
const userLoading = ref(false)

// 视频数据
const videos = ref([])
const loading = ref(false)
const pollingIntervalId = ref(null) // 轮询定时器ID
const POLLING_INTERVAL = 120000 // 2分钟轮询间隔

// 详情弹窗
const detailDialogVisible = ref(false)
const selectedItem = ref(null)
const activeDetailTab = ref('detail')

// 计算菜单位置
const menuStyle = computed(() => {
  const avatarEl = topHeaderRef.value?.avatarRef
  if (!avatarEl || !showUserMenu.value) return {}
  
  const rect = avatarEl.getBoundingClientRect()
  return {
    position: 'fixed',
    top: `${rect.bottom + 8}px`,
    right: `${window.innerWidth - rect.right}px`,
    zIndex: 99999
  }
})

// 跳转到会员订阅页面
const goToSubscription = () => {
  router.push('/subscription')
}

const goToMyWorks = () => {
  router.push('/works')
}

const goToTextToVideo = () => {
  router.push('/text-to-video/create')
}

const goToImageToVideo = () => {
  router.push('/image-to-video/create')
}

const goToStoryboardVideo = () => {
  router.push('/storyboard-video/create')
}

// 跳转到数据仪表盘
const goToDashboard = () => {
  showUserMenu.value = false
  // 检查用户权限，只有管理员才能访问数据仪表盘
  if (userStore.isAdmin) {
    router.push('/admin/dashboard')
  } else {
    message.warning(t('profile.insufficientPermission'))
  }
}

// 跳转到订单管理
const goToOrders = () => {
  showUserMenu.value = false
  router.push('/admin/orders')
}

// 跳转到会员管理
const goToMembers = () => {
  showUserMenu.value = false
  // 检查用户权限，只有管理员才能访问会员管理
  if (userStore.isAdmin) {
    router.push('/member-management')
  } else {
    message.warning(t('profile.insufficientPermission'))
  }
}

// 跳转到错误统计
const goToErrorStats = () => {
  showUserMenu.value = false
  if (userStore.isAdmin) {
    router.push('/admin/error-statistics')
  }
}

// 跳转到系统设置
const goToSettings = () => {
  showUserMenu.value = false
  // 检查用户权限，只有管理员才能访问系统设置
  if (userStore.isAdmin) {
    router.push('/system-settings')
  } else {
    message.warning(t('profile.insufficientPermission'))
  }
}

// 跳转到API管理
const goToApiManagement = () => {
  showUserMenu.value = false
  // 检查用户权限，只有管理员才能访问API管理
  if (userStore.isAdmin) {
    router.push('/api-management')
  } else {
    message.warning(t('profile.insufficientPermission'))
  }
}

// 跳转到生成任务管理
const goToTaskRecord = () => {
  showUserMenu.value = false
  // 检查用户权限，只有管理员才能访问生成任务管理
  if (userStore.isAdmin) {
    router.push('/generate-task-record')
  } else {
    message.warning(t('profile.insufficientPermission'))
  }
}

// 跳转到视频管理
const goToWorkflowVideos = () => {
  showUserMenu.value = false
  if (userStore.isAdmin) {
    router.push('/admin/workflow-videos')
  } else {
    message.warning(t('profile.insufficientPermission'))
  }
}

// 退出登录
const logout = async () => {
  try {
    showUserMenu.value = false

    // 清除用户数据
    await userStore.logoutUser()

    // 清除其他可能的本地存储
    localStorage.removeItem('user')
    localStorage.removeItem('token')

    message.success(t('profile.logoutSuccess'))

    // 跳转到登录页
    router.push('/login')
  } catch (error) {
    console.error('退出登录失败:', error)
    message.error(t('profile.logoutFailed'))
  }
}

// 打开作品详情
const openDetail = async (item) => {
  selectedItem.value = item
  activeDetailTab.value = 'detail'
  detailDialogVisible.value = true

  try {
    const response = await getWorkDetail(item.id)
    if (response && response.data && response.data.success && response.data.data) {
      const work = response.data.data
      selectedItem.value = transformWorkData(work)
    } else {
      // 如果API返回失败但item已有数据，只记录日志不显示错误
      console.warn('获取作品详情API返回异常，使用列表数据:', response?.data?.message || '未知错误')
    }
  } catch (error) {
    // 如果API调用失败但item已有数据，只记录日志不显示错误
    console.warn('加载作品详情API失败，使用列表数据:', error)
  }
}

// 关闭详情
const handleClose = () => {
  detailDialogVisible.value = false
  selectedItem.value = null
  activeDetailTab.value = 'detail'
}

// 获取作品提示词（优先使用 prompt，其次使用后台 description，最后回退默认文案）
const getDescription = (item) => {
  if (!item) return ''
  const desc = (item.prompt && item.prompt.trim()) ? item.prompt : (item.description && item.description.trim() ? item.description : '')
  if (desc) return desc
  // 回退文案
  if (item.type === 'video') {
    return t('profile.noPrompt')
  }
  return t('profile.noPrompt')
}

// 格式化时长
const formatDuration = (dur) => {
  if (dur === null || dur === undefined || dur === '') return ''
  if (typeof dur === 'number') return `${dur}s`
  if (typeof dur === 'string') {
    const trimmed = dur.trim()
    if (/^\d+$/.test(trimmed)) return `${trimmed}s`
    return trimmed
  }
  return String(dur)
}

// 做同款
const createSimilar = (item) => {
  if (!item) return
  
  // 构建查询参数
  const query = {
    prompt: item.prompt || '',
    aspectRatio: item.aspectRatio || '',
    duration: item.duration || ''
  }
  
  // 添加参考图（分镜图的 cover 是生成结果，不是原始参考图，不传递）
  if (item.category !== '分镜图' && item.category !== '分镜视频' && item.cover && item.cover !== '/images/backgrounds/welcome.jpg') {
    query.referenceImage = item.cover
  }
  
  console.log('[做同款] 跳转参数:', query, 'category:', item.category, 'workType:', item.workType)
  
  // 根据作品类型跳转
  if (item.category === '文生视频') {
    router.push({ path: '/text-to-video/create', query })
  } else if (item.category === '图生视频') {
    router.push({ path: '/image-to-video/create', query })
  } else if (item.category === '分镜图' || item.workType === 'STORYBOARD_IMAGE') {
    // 分镜图做同款：进入 Step 1（生成分镜图），使用 imagePrompt
    query.step = 'image'
    if (item.imagePrompt) {
      query.imagePrompt = item.imagePrompt
    }
    // 传递分镜图阶段的参考图
    if (item.uploadedImages) {
      query.uploadedImages = item.uploadedImages
    }
    router.push({ path: '/storyboard-video/create', query })
  } else if (item.category === '分镜视频') {
    // 分镜视频做同款：进入 Step 2（生成视频），携带已生成的分镜图和视频参考图
    query.step = 'video'
    // cover 是分镜图（thumbnailUrl），传递给 Step 2 作为分镜图
    if (item.cover && item.cover !== '/images/backgrounds/welcome.jpg') {
      query.storyboardImage = item.cover
    }
    // 传递视频提示词（videoPrompt）
    if (item.videoPrompt) {
      query.prompt = item.videoPrompt
    } else if (item.imagePrompt) {
      query.prompt = item.imagePrompt
    } else if (item.prompt) {
      query.prompt = item.prompt
    }
    // 传递视频阶段的参考图（videoReferenceImages），不是分镜图阶段的参考图
    if (item.videoReferenceImages) {
      query.videoReferenceImages = item.videoReferenceImages
    }
    router.push({ path: '/storyboard-video/create', query })
  } else {
    // 默认根据类型跳转
    if (item.type === 'video') {
      router.push({ path: '/text-to-video/create', query })
    } else {
      router.push({ path: '/image-to-video/create', query })
    }
  }
}

// 下载作品
const downloadWork = async (item) => {
  if (!item) return
  
  try {
    // 判断是视频还是图片
    const isVideo = item.type === 'video' || item.category === '文生视频' || item.category === '图生视频' || item.category === '分镜视频'
    const url = item.resultUrl || item.cover
    
    if (!url || url === '/images/backgrounds/welcome.jpg') {
      message.warning(t('works.noDownloadUrl'))
      return
    }
    
    message.info(t('common.preparingDownload'))
    
    if (isVideo) {
      await downloadVideo(url, item.id || item.taskId)
    } else {
      await downloadImage(url, item.id || item.taskId, 'work')
    }
    
    message.success(t('common.downloadSuccess'))
  } catch (error) {
    console.error('下载失败:', error)
    message.error(t('common.downloadFailed') || '下载失败')
  }
}

// ========== 批量选择与删除 ==========
const batchSelectMode = ref(false)
const selectedWorkIds = ref(new Set())

const toggleBatchMode = () => {
  batchSelectMode.value = !batchSelectMode.value
  if (!batchSelectMode.value) {
    selectedWorkIds.value = new Set() // 退出选择模式时清空
  }
}

const toggleSelectWork = (workId) => {
  const newSet = new Set(selectedWorkIds.value)
  if (newSet.has(workId)) {
    newSet.delete(workId)
  } else {
    newSet.add(workId)
  }
  selectedWorkIds.value = newSet
}

const selectAllWorks = () => {
  if (selectedWorkIds.value.size === videos.value.length) {
    selectedWorkIds.value = new Set()
  } else {
    selectedWorkIds.value = new Set(videos.value.map(v => v.id))
  }
}

const isAllSelected = computed(() => {
  return videos.value.length > 0 && selectedWorkIds.value.size === videos.value.length
})

const handleBatchDelete = async () => {
  const ids = Array.from(selectedWorkIds.value)
  if (ids.length === 0) {
    message.warning('请先选择要删除的作品')
    return
  }
  try {
    await new Promise((resolve, reject) => {
      Modal.confirm({
        title: '批量删除',
        content: `确定要删除选中的 ${ids.length} 个作品吗？删除后无法恢复。`,
        okText: '删除',
        cancelText: '取消',
        okType: 'danger',
        onOk: () => resolve(),
        onCancel: () => reject('cancel'),
      })
    })

    const response = await batchDeleteWorks(ids)
    if (response.data && response.data.success) {
      message.success(response.data.message || `成功删除 ${ids.length} 个作品`)
      // 从列表中移除已删除的作品（包括可能被关联删除的分镜作品）
      videos.value = videos.value.filter(v => !selectedWorkIds.value.has(v.id))
      selectedWorkIds.value = new Set()
      batchSelectMode.value = false
      // 重新加载以获取最新数据（关联删除可能影响额外作品）
      loadWorks()
    } else {
      message.error(response.data?.message || '批量删除失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('批量删除失败:', error)
      message.error(error.message || '批量删除失败')
    }
  }
}

// 删除作品
const handleDeleteWork = async (item) => {
  if (!item) return
  try {
    await new Promise((resolve, reject) => {
      Modal.confirm({
        title: t('common.confirmDelete') || '确认删除',
        content: t('works.deleteWorkConfirm') || '确定要删除这个作品吗？删除后无法恢复。',
        okText: t('common.delete') || '删除',
        cancelText: t('common.cancel') || '取消',
        okType: 'danger',
        onOk: () => resolve(),
        onCancel: () => reject('cancel'),
      })
    })

    const response = await deleteWork(item.id)
    if (response.data && response.data.success) {
      message.success(t('works.deleteSuccess') || '删除成功')
      // 从列表中移除
      videos.value = videos.value.filter(v => v.id !== item.id)
    } else {
      message.error(response.data?.message || t('works.deleteFailed') || '删除失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除作品失败:', error)
      message.error(error.message || t('works.deleteFailed') || '删除失败')
    }
  }
}

// 生视频 - 使用分镜图直接生成视频（跳转到图生视频页面）
const goToGenerateVideo = (item) => {
  if (!item) return
  
  // 跳转到图生视频创作页面，传递分镜图作为参考图
  const query = {
    aspectRatio: item.aspectRatio || '',
    duration: item.duration || '',
    hdMode: item.quality === 'HD' ? 'true' : 'false',
    _t: Date.now() // 添加时间戳确保路由参数变化被检测到
  }
  
  // 使用分镜图作为参考图
  if (item.cover && item.cover !== '/images/backgrounds/welcome.jpg') {
    query.referenceImage = item.cover
  } else if (item.resultUrl) {
    query.referenceImage = item.resultUrl
  }
  
  // 传递视频提示词：优先使用 videoPrompt，其次 imagePrompt，最后 prompt
  if (item.videoPrompt) {
    query.prompt = item.videoPrompt
  } else if (item.imagePrompt) {
    query.prompt = item.imagePrompt
  } else if (item.prompt) {
    query.prompt = item.prompt
  }
  
  console.log('[生视频] 跳转到图生视频页面，参数:', query)
  router.push({ path: '/image-to-video/create', query })
  message.success(t('works.readyToGenerateVideo'))
}

// 处理URL，确保相对路径正确
const processUrl = (url) => {
  if (!url) return null
  // data: 协议（Base64 图片等）直接返回
  if (url.startsWith('data:')) {
    return url
  }
  // 如果已经是完整URL（http/https），直接返回
  if (url.startsWith('http://') || url.startsWith('https://')) {
    return url
  }
  // 如果是相对路径（以/开头），确保以/开头
  if (url.startsWith('/')) {
    return url
  }
  // 否则添加/前缀
  return '/' + url
}

// 将后端返回的UserWork数据转换为前端需要的格式
const transformWorkData = (work) => {
  const resultUrl = processUrl(work.resultUrl)
  const thumbnailUrl = processUrl(work.thumbnailUrl)
  const isVideoType = work.workType === 'TEXT_TO_VIDEO' || work.workType === 'IMAGE_TO_VIDEO' || work.workType === 'STORYBOARD_VIDEO'
  const cover = thumbnailUrl || resultUrl || '/images/backgrounds/welcome.jpg'
  // thumbnailCover: 视频类型只用 thumbnailUrl，不回退到 resultUrl（视频文件）
  const thumbnailCover = thumbnailUrl || (isVideoType ? null : resultUrl) || null

  return {
    id: work.taskId || work.id?.toString() || '',
    title: work.title || work.prompt || t('common.untitledWork'),
    cover: cover,
    thumbnailCover: thumbnailCover,
    resultUrl: resultUrl || '',
    type: isVideoType ? 'video' : 'image',
    category: work.workType === 'TEXT_TO_VIDEO' ? t('common.textToVideoCategory') : work.workType === 'IMAGE_TO_VIDEO' ? t('common.imageToVideoCategory') : work.workType === 'STORYBOARD_VIDEO' ? t('common.storyboardVideoCategory') : work.workType === 'STORYBOARD_IMAGE' ? t('common.storyboardImageCategory') : t('common.unknownCategory'),
    sizeText: work.fileSize || t('common.unknownSize'),
    createTime: work.createdAt ? new Date(work.createdAt).toLocaleString('zh-CN') : '',
    date: work.createdAt ? new Date(work.createdAt).toLocaleDateString('zh-CN') : '',
    description: work.description || work.prompt || '',
    prompt: work.prompt || '',
    duration: work.duration || work.videoDuration || work.length || '',
    aspectRatio: work.aspectRatio || work.ratio || work.aspect || '',
    quality: work.quality || work.resolution || '',
    username: work.username || work.user?.username || work.creator || work.author || work.owner || t('common.unknownUser'),
    status: work.status || 'COMPLETED',
    uploadedImages: work.uploadedImages || null, // 分镜图阶段用户上传的参考图
    videoReferenceImages: work.videoReferenceImages || null, // 视频阶段用户上传的参考图（分镜视频做同款需要）
    imagePrompt: work.imagePrompt || null, // 分镜图优化后的提示词
    workType: work.workType || '', // 原始作品类型
  }
}

// 加载用户信息
const loadUserInfo = async () => {
  userLoading.value = true
  try {
    const response = await getCurrentUser()
    console.log('获取用户信息响应:', response)
    if (response && response.data && response.data.success && response.data.data) {
      const user = response.data.data
      console.log('用户数据:', user)
      userInfo.value = {
        username: user.username || '',
        nickname: user.nickname || '',
        email: user.email || '',
        bio: user.bio || '',
        avatar: user.avatar || '',
        id: user.id ? String(user.id) : '',
        points: user.points || 0,
        frozenPoints: user.frozenPoints || 0
      }
      console.log('设置后的用户信息:', userInfo.value)

      // 检查用户是否需要设置密码（只有数据库中真正没有密码时才弹窗，且只弹一次）
      const needSetPasswordFlag = localStorage.getItem('needSetPassword') === '1'
      const hasShownPasswordDialog = localStorage.getItem('hasShownPasswordDialog') === '1'
      
      // 检查后端返回的用户密码状态
      const hasNoPassword = !user.passwordHash || String(user.passwordHash).trim() === ''
      
      // 只有在以下情况下才弹出修改密码弹窗：
      // 1. 用户数据库中确实没有密码（hasNoPassword = true）
      // 2. 有 needSetPassword 标记（来自登录流程）
      // 3. 还没有显示过弹窗（避免重复显示）
      if (hasNoPassword && needSetPasswordFlag && !hasShownPasswordDialog) {
        console.log('检测到用户没有设置密码，弹出修改密码弹窗')
        openChangePasswordDialog()
        // 清除标记，确保只弹一次
        localStorage.removeItem('needSetPassword')
        localStorage.setItem('hasShownPasswordDialog', '1')
      } else if (needSetPasswordFlag && !hasNoPassword) {
        // 如果有标记但用户已经有密码了，清除标记
        console.log('用户已有密码，清除 needSetPassword 标记')
        localStorage.removeItem('needSetPassword')
      }
    } else {
      console.error('获取用户信息失败:', response?.data?.message || '未知错误')
      message.error(t('profile.loadUserInfoFailed'))
    }
  } catch (error) {
    // 401错误由axios拦截器处理，不重复提示
    if (error.response?.status === 401) {
      return
    }
    console.error('加载用户信息失败:', error)
    message.error(t('profile.loadUserInfoFailed') + ': ' + (error.message || t('common.unknownError')))
  } finally {
    userLoading.value = false
  }
}

// 加载用户作品列表
const loadVideos = async () => {
  loading.value = true
  try {
    const response = await getMyWorks({
      page: 0,
      size: 10 // 只加载最近10个作品
    })
    console.log('获取作品列表响应:', response)
    
    if (response && response.data && response.data.success) {
      const data = response.data.data || []
      console.log('作品数据:', data)
      // 转换数据格式，并过滤掉失败和删除的作品
      videos.value = data
        .map(transformWorkData)
        .filter(work => work.status !== 'FAILED' && work.status !== 'DELETED')
      console.log('转换后的作品列表:', videos.value)
      
      // 检查是否有处理中的任务，如果有则启动轮询
      checkAndStartPolling()
    } else {
      console.error('获取作品列表失败:', response?.data?.message || '未知错误')
    }
  } catch (error) {
    console.error('加载作品列表失败:', error)
    message.error(t('profile.loadWorksFailed') + ': ' + (error.message || t('common.unknownError')))
  } finally {
    loading.value = false
  }
}

// 检查是否有处理中的任务，如果有则启动轮询
const checkAndStartPolling = () => {
  const hasProcessingTasks = videos.value.some(
    item => item.status === 'PROCESSING' || item.status === 'PENDING'
  )
  
  if (hasProcessingTasks && !pollingIntervalId.value) {
    console.log('[Profile] 检测到处理中的任务，启动2分钟轮询')
    startPolling()
  } else if (!hasProcessingTasks && pollingIntervalId.value) {
    console.log('[Profile] 没有处理中的任务，停止轮询')
    stopPolling()
  }
}

// 启动轮询
const startPolling = () => {
  if (pollingIntervalId.value) return // 避免重复启动
  
  pollingIntervalId.value = setInterval(async () => {
    console.log('[Profile] 执行轮询刷新...')
    try {
      const response = await getMyWorks({
        page: 0,
        size: 10
      })
      
      if (response && response.data && response.data.success) {
        const data = response.data.data || []
        videos.value = data
          .map(transformWorkData)
          .filter(work => work.status !== 'FAILED' && work.status !== 'DELETED')
        
        // 检查是否还需要继续轮询
        const hasProcessingTasks = videos.value.some(
          item => item.status === 'PROCESSING' || item.status === 'PENDING'
        )
        
        if (!hasProcessingTasks) {
          console.log('[Profile] 所有任务已完成，停止轮询')
          stopPolling()
          // 刷新用户积分
          await userStore.fetchCurrentUser()
        }
      }
    } catch (error) {
      console.error('[Profile] 轮询刷新失败:', error)
    }
  }, POLLING_INTERVAL)
}

// 停止轮询
const stopPolling = () => {
  if (pollingIntervalId.value) {
    clearInterval(pollingIntervalId.value)
    pollingIntervalId.value = null
    console.log('[Profile] 轮询已停止')
  }
}

// 编辑个人资料
const editProfile = () => {
  // TODO: 可以跳转到编辑页面或打开编辑对话框
  message.info(t('profile.profileEditDevMsg'))
}

// 点击外部关闭菜单
const handleClickOutside = (event) => {
  const userAvatar = event.target.closest('.user-avatar')
  const userMenu = event.target.closest('.user-menu-teleport')
  // 点击头像或菜单本身不关闭
  if (!userAvatar && !userMenu) {
    showUserMenu.value = false
  }
}

// 个人主页“已发布”区不跳转，保持静态展示，与“我的作品”点击打开详情逻辑不同

// 视频加载元数据后，跳转到第一帧（但不播放）
const onVideoLoaded = (event) => {
  const video = event.target
  if (video && video.duration) {
    // 跳转到第一帧（0秒）
    video.currentTime = 0.1
    // 确保视频不播放
    video.pause()
  }
}

// 视频加载失败处理
const onVideoError = (event, video) => {
  console.warn('视频加载失败:', video.resultUrl)
  // 隐藏video元素，显示占位符
  event.target.style.display = 'none'
}

// 图片加载失败处理
const onImageError = (event) => {
  console.warn('图片加载失败:', event.target.src)
  event.target.style.display = 'none'
}

onMounted(async () => {
  document.addEventListener('click', handleClickOutside)
  // 强制刷新用户信息，确保获取管理员修改后的最新数据
  await userStore.fetchCurrentUser()
  loadUserInfo()
  loadVideos()
})

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside)
  // 清理轮询定时器
  stopPolling()
})
</script>

<style scoped>
.profile-page {
  width: 100vw;
  height: 100vh;
  background: var(--bg-base);
  color: var(--text-primary);
  display: flex;
  font-family: var(--font-sans);
  overflow: hidden;
  position: relative;
}

/* Main Content */
.main-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
}


/* User Menu (Teleport) */
:global(.user-menu-teleport) {
  background: var(--bg-overlay);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  min-width: 180px;
  overflow: hidden;
}

:global(.user-menu-teleport .menu-item) {
  display: flex;
  align-items: center;
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  transition: var(--transition-colors);
  color: var(--text-secondary);
  font-size: var(--text-sm);
}

:global(.user-menu-teleport .menu-item:hover) {
  background: var(--bg-hover);
  color: var(--text-primary);
}

:global(.user-menu-teleport .menu-item .anticon) {
  margin-right: var(--space-3);
  font-size: 16px;
}

:global(.user-menu-teleport .menu-item:not(:last-child)) {
  border-bottom: 1px solid var(--border-subtle);
}

/* Profile Section — Bold Gradient Card */
.profile-section {
  padding: var(--space-8) var(--space-8);
  background: var(--gradient-brand);
  margin: var(--space-5) var(--space-8);
  border-radius: 24px;
  border: none;
  position: relative;
  overflow: hidden;
  box-shadow: 0 8px 32px rgba(124, 58, 237, 0.25), 0 2px 8px rgba(236, 72, 153, 0.15);
}

.profile-section::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.18) 0%, transparent 50%),
    radial-gradient(circle at 20% 80%, rgba(6, 182, 212, 0.25) 0%, transparent 50%);
  pointer-events: none;
}

.profile-section::after {
  content: '';
  position: absolute;
  top: -40%;
  right: -10%;
  width: 300px;
  height: 300px;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.12) 0%, transparent 70%);
  border-radius: 50%;
  pointer-events: none;
}

.profile-info {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  position: relative;
  z-index: 1;
}

.avatar {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  flex-shrink: 0;
  border: 3px solid rgba(255, 255, 255, 0.6);
  overflow: hidden;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

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

.user-details {
  flex: 1;
}

.username {
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0 0 var(--space-1) 0;
  color: #FFFFFF;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.profile-status {
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, 0.85);
  margin: 0;
}

/* Published Section */
.published-section {
  padding: 0 var(--space-8) var(--space-8);
}

.published-section .section-header .section-title,
.published-section > .section-title {
  font-size: var(--text-lg);
  font-weight: var(--font-semibold);
  margin: 0 !important;
  color: var(--text-primary);
  position: relative;
  padding-bottom: var(--space-3);
}

.published-section .section-header .section-title::after,
.published-section > .section-title::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 48px;
  height: 3px;
  background: var(--gradient-brand);
  border-radius: var(--radius-full);
}

.video-grid {
  column-count: 4;
  column-gap: var(--space-4);
}

.video-item {
  background: var(--bg-surface);
  border-radius: 16px;
  overflow: hidden;
  border: 2px solid transparent;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  break-inside: avoid;
  margin-bottom: var(--space-4);
  display: inline-block;
  width: 100%;
  box-shadow: 0 2px 12px rgba(124, 58, 237, 0.06);
}

.video-item:hover {
  transform: translateY(-6px) scale(1.01);
  border-color: var(--primary-300);
  box-shadow: 0 12px 40px rgba(124, 58, 237, 0.18), 0 4px 12px rgba(236, 72, 153, 0.1);
}

/* ---- 批量选择模式 ---- */
.video-item.is-selected {
  border-color: var(--primary-500);
  box-shadow: 0 0 0 2px rgba(var(--primary-rgb, 22, 119, 255), 0.25);
}

.batch-checkbox {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 10;
  cursor: pointer;
}

.checkbox-inner {
  width: 22px;
  height: 22px;
  border-radius: 6px;
  border: 2px solid var(--border-strong);
  background: var(--bg-glass);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
  color: var(--text-inverse);
  font-size: 12px;
}

.checkbox-inner.checked {
  background: var(--primary-500);
  border-color: var(--primary-500);
}

.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-3);
}

.section-header .section-title {
  margin-bottom: 0;
}

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

/* 批量删除底部操作栏 */
.batch-toolbar {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 28px;
  background: var(--bg-surface);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-radius: 16px;
  border: 2px solid var(--primary-200);
  box-shadow: 0 8px 32px rgba(124, 58, 237, 0.2);
  z-index: 100;
}

.batch-info {
  font-size: 13px;
  color: var(--text-secondary);
}
.batch-info strong {
  color: var(--text-primary);
  font-weight: 600;
}

/* 底部栏入场动画 */
.slide-up-enter-active,
.slide-up-leave-active {
  transition: all 0.25s ease;
}
.slide-up-enter-from,
.slide-up-leave-to {
  opacity: 0;
  transform: translateX(-50%) translateY(20px);
}

.video-thumbnail {
  position: relative;
  cursor: pointer;
}

.thumbnail-image {
  background: var(--bg-elevated);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  min-height: 120px;
}

.video-cover-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.video-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-elevated);
  min-height: 120px;
}

/* Status Overlays */
.failed-overlay,
.processing-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 10;
  border-radius: inherit;
}

.failed-overlay {
  background: rgba(239, 68, 68, 0.75);
  backdrop-filter: blur(4px);
}

.processing-overlay {
  background: rgba(124, 58, 237, 0.75);
  backdrop-filter: blur(4px);
}

.failed-icon,
.processing-icon {
  font-size: 32px;
  margin-bottom: var(--space-2);
}

.processing-icon {
  animation: breathe 1.5s ease-in-out infinite;
}

.failed-text {
  color: var(--error-400);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
}

.processing-text {
  color: var(--primary-400);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
}

.status-text {
  font-size: var(--text-xs);
  font-weight: var(--font-medium);
}

.status-text.failed { color: var(--error-400); }
.status-text.processing { color: var(--primary-400); }

.empty-works {
  column-span: all;
  text-align: center;
  padding: 48px 24px;
  color: var(--text-tertiary);
  background: linear-gradient(135deg, var(--primary-50), rgba(236, 72, 153, 0.04));
  border-radius: 20px;
  border: 2px dashed var(--primary-200);
}

.empty-text {
  font-size: var(--text-lg);
  font-weight: 600;
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.video-action {
  padding: var(--space-2) var(--space-3);
  opacity: 0;
  transition: opacity var(--duration-normal) var(--ease-default);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-1);
}

.video-action .action-left {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
}

.video-item:hover .video-action {
  opacity: 1;
}

/* 失败和进行中的作品，操作栏始终可见（不需要 hover 才能看到删除按钮） */
.video-action:has(.status-text) {
  opacity: 1;
}

/* Responsive */
@media (max-width: 1200px) {
  .video-grid { column-count: 3; }
}

@media (max-width: 900px) {
  .video-grid { column-count: 2; }
}

@media (max-width: 768px) {
  .profile-page { flex-direction: column; }
  .video-grid { column-count: 2; }
  .profile-info { flex-direction: column; text-align: center; }
  .profile-section { margin: var(--space-3); }
  .published-section { padding: 0 var(--space-4) var(--space-4); }
}

@media (max-width: 480px) {
  .video-grid { column-count: 1; }
}

/* 详情弹窗样式（与“我的作品”保持一致） */
:deep(.ant-modal.detail-dialog) {
  background: var(--bg-surface) !important;
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border-radius: 24px;
  border: 2px solid var(--primary-100);
  box-shadow: 0 24px 80px rgba(124, 58, 237, 0.15), 0 8px 24px rgba(236, 72, 153, 0.08);
  overflow: hidden;
}

:deep(.ant-modal.detail-dialog .ant-modal-content) {
  background: transparent !important;
  box-shadow: none !important;
  padding: 0 !important;
}

:deep(.ant-modal.detail-dialog .ant-modal-header) {
  background: transparent !important;
  border-bottom: 1px solid var(--border-subtle);
  padding: 12px 20px;
  margin: 0;
}

:deep(.ant-modal.detail-dialog .ant-modal-title) {
  color: var(--text-primary) !important;
  font-weight: 600;
  font-size: 15px;
}

:deep(.ant-modal.detail-dialog .ant-modal-close) {
  color: var(--text-tertiary) !important;
  transition: color 0.2s ease;
}
:deep(.ant-modal.detail-dialog .ant-modal-close:hover) {
  color: var(--text-primary) !important;
}

:deep(.ant-modal.detail-dialog .ant-modal-body) {
  background: transparent !important;
  padding: 0 !important;
}

/* 布局：左视频 + 右信息，紧凑无多余空白 */
.detail-content {
  display: flex;
  max-height: 70vh;
}

.detail-left {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-base);
  border-right: 1px solid var(--border-subtle);
  min-width: 0;
  overflow: hidden;
}

.detail-video, .detail-image {
  display: block;
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
  background: transparent;
}

.detail-right {
  flex: 0 0 300px;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow-y: auto;
  max-height: 70vh;
}

.detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

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

.detail-right .avatar {
  width: 32px;
  height: 32px;
  border: none;
}

.detail-right .username {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-primary);
}

.tabs {
  display: flex;
  gap: 6px;
}

.tab {
  padding: 4px 12px;
  background: transparent;
  color: var(--text-tertiary);
  cursor: pointer;
  border-radius: 6px;
  transition: all 0.2s ease;
  font-size: 13px;
}

.tab.active {
  background: var(--gradient-brand);
  color: #fff;
  box-shadow: 0 2px 8px rgba(124, 58, 237, 0.25);
}

.tab:hover:not(.active) {
  background: var(--bg-hover);
  color: var(--text-primary);
}

.category-label {
  padding: 4px 12px;
  background: var(--bg-hover);
  color: var(--text-tertiary);
  border-radius: 6px;
  font-size: 13px;
}

.description-section {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.section-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-tertiary);
  margin: 0;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.description-text {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-secondary);
  margin: 0;
  word-break: break-all;
}

.reference-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.input-details-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.input-images {
  display: flex;
  gap: var(--space-3);
}

.input-image-item {
  flex: 1;
}

.input-thumbnail {
  width: 100%;
  height: 80px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-default);
}

.metadata-section {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.metadata-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid var(--border-subtle);
}

.metadata-item:last-child {
  border-bottom: none;
}

.label {
  font-size: 12px;
  color: var(--text-tertiary);
}

.value {
  font-size: 12px;
  color: var(--text-primary);
  font-weight: 500;
  text-align: right;
  max-width: 60%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.action-section {
  margin-top: auto;
  padding-top: var(--space-5);
}

.create-similar-btn {
  width: 100%;
  background: var(--gradient-brand);
  color: #fff;
  border: none;
  border-radius: 12px;
  padding: var(--space-3) var(--space-6);
  font-size: var(--text-base);
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 16px rgba(124, 58, 237, 0.25);
}

.create-similar-btn:hover {
  box-shadow: 0 6px 24px rgba(124, 58, 237, 0.35);
  transform: translateY(-2px);
}

.create-similar-btn:active {
  transform: translateY(0);
}

/* Modal masks */
:deep(.ant-modal-wrap),
:deep(.ant-modal-mask) {
  background-color: rgba(0, 0, 0, 0.75) !important;
}

/* Processing/Failed overlays */
.processing-overlay,
.failed-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.75);
  backdrop-filter: blur(4px);
  z-index: 10;
  border-radius: var(--radius-lg);
}

.processing-icon,
.failed-icon {
  font-size: 32px;
  margin-bottom: var(--space-2);
}

.processing-text,
.failed-text {
  font-size: var(--text-sm);
  color: var(--text-primary);
  font-weight: var(--font-medium);
}

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

.status-text.processing {
  color: var(--primary-400);
}

.status-text.failed {
  color: var(--error);
}
</style>

<style>
/* Global dialog fallback */
.ant-modal.detail-dialog {
  background: var(--bg-surface) !important;
}
.ant-modal.detail-dialog .ant-modal-content {
  background: transparent !important;
  box-shadow: none !important;
}
.ant-modal.detail-dialog .ant-modal-header,
.ant-modal.detail-dialog .ant-modal-body {
  background: transparent !important;
}

/* Progress bar */
.progress-bar-container {
  width: 60%;
  height: 4px;
  background: var(--bg-hover);
  border-radius: var(--radius-full);
  overflow: hidden;
  margin-top: var(--space-3);
}

.progress-bar-animated {
  width: 30%;
  height: 100%;
  background: linear-gradient(90deg, var(--primary-500), var(--secondary-500), var(--accent-500), var(--primary-500));
  background-size: 300% 100%;
  border-radius: var(--radius-full);
  animation: progress-sweep 1.5s ease-in-out infinite, gradient-flow 2s linear infinite;
}

/* Badge tags */
.badge-pro, .badge-max {
  font-size: 9px;
  padding: 1px 4px;
  border-radius: var(--radius-xs);
  font-weight: var(--font-medium);
  margin-left: var(--space-1);
  background: var(--primary-glow-light);
  color: var(--primary-400);
  flex: 0 0 auto !important;
  width: auto !important;
}

.badge-max {
  background: rgba(255, 100, 150, 0.15);
  color: #FF7EB3;
}
</style>

<!-- Masonry grid (non-scoped) -->
<style>
/* 作品集标题与瀑布流之间的间距 */
.profile-page .published-section > h3 {
  margin-bottom: 20px !important;
}

.profile-page .video-grid {
  column-count: 5 !important;
  column-gap: var(--space-4) !important;
  display: block !important;
}

.profile-page .video-item {
  break-inside: avoid !important;
  margin-bottom: var(--space-4) !important;
  display: inline-block !important;
  width: 100% !important;
}

.profile-page .thumbnail-image {
  aspect-ratio: unset !important;
  height: auto !important;
  min-height: 120px;
}

.profile-page .video-cover-img {
  width: 100% !important;
  height: auto !important;
  display: block !important;
  object-fit: cover !important;
}

@media (max-width: 1200px) {
  .profile-page .video-grid { column-count: 4 !important; }
}
@media (max-width: 900px) {
  .profile-page .video-grid { column-count: 3 !important; }
}
@media (max-width: 768px) {
  .profile-page .video-grid { column-count: 2 !important; }
}
@media (max-width: 480px) {
  .profile-page .video-grid { column-count: 1 !important; }
}
</style>
