<template>
  <div class="mix-page">
    <!-- 顶部操作栏 -->
    <header class="page-header">
      <div class="header-left">
        <a-button type="text" @click="router.push('/material/list')">
          <template #icon><ArrowLeftOutlined /></template>
          返回
        </a-button>
        <a-divider type="vertical" />
        <h1 class="page-title">智能混剪</h1>
        <a-tag color="processing" size="small">{{ sceneCount }} 场景</a-tag>
      </div>

      <div class="header-center">
        <!-- 核心参数 -->
        <div class="param-item">
          <span class="param-label">总时长</span>
          <a-slider
            v-model:value="formData.totalDuration"
            :min="15"
            :max="30"
            :step="1"
            style="width: 100px;"
          />
          <span class="param-value">{{ formData.totalDuration }}s</span>
        </div>

        <a-divider type="vertical" />

        <div class="param-item">
          <span class="param-label">切片</span>
          <a-slider
            v-model:value="formData.clipDuration"
            :min="3"
            :max="5"
            :step="1"
            style="width: 80px;"
          />
          <span class="param-value">{{ formData.clipDuration }}s</span>
        </div>

        <a-divider type="vertical" />

        <div class="param-item">
          <span class="param-label">生成</span>
          <a-select
            v-model:value="formData.produceCount"
            size="small"
            style="width: 70px;"
            @change="saveProduceCount"
          >
            <a-select-option :value="1">1 个</a-select-option>
            <a-select-option :value="3">3 个</a-select-option>
            <a-select-option :value="5">5 个</a-select-option>
            <a-select-option :value="10">10 个</a-select-option>
            <a-select-option :value="15">15 个</a-select-option>
          </a-select>
        </div>
      </div>

      <div class="header-right">
        <a-button @click="showSettings = true">
          <template #icon><SettingOutlined /></template>
          高级设置
        </a-button>
        <a-button
          type="primary"
          :loading="uiState.submitting"
          :disabled="!canSubmit"
          @click="handleSubmit"
        >
          <template #icon><RocketOutlined /></template>
          开始混剪
        </a-button>
      </div>
    </header>

    <!-- 进度条 -->
    <div class="progress-bar">
      <div class="progress-track">
        <div class="progress-fill" :style="{ width: progressPercent + '%' }" />
      </div>
      <span class="progress-text">
        <CheckCircleFilled v-if="filledCount === sceneCount" class="icon-complete" />
        <span v-else class="icon-pending">{{ filledCount }}/{{ sceneCount }}</span>
        场景已就绪
      </span>
    </div>

    <!-- 主内容区：场景轨道全宽 -->
    <main class="page-main">
      <section class="scenes-section">
        <div class="section-header">
          <span class="section-title">
            <PlaySquareOutlined />
            场景编排
          </span>
          <div class="header-actions">
            <a-button size="small" @click="clearScenes">
              <template #icon><ClearOutlined /></template>
              清空
            </a-button>
            <a-button size="small" type="primary" ghost @click="autoFillAllScenes">
              <template #icon><ThunderboltOutlined /></template>
              一键填充
            </a-button>
          </div>
        </div>

        <div class="scenes-list">
          <draggable
            v-model="dataState.scenes"
            item-key="index"
            handle=".scene-drag"
            animation="200"
            class="draggable-list"
            @end="onSceneDragEnd"
          >
            <template #item="{ element: scene, index }">
              <div
                class="scene-card"
                :class="{
                  'scene-card--complete': scene.candidates?.length > 0
                }"
              >
                <!-- 场景头部 -->
                <div class="scene-header">
                  <div class="scene-drag">
                    <HolderOutlined />
                  </div>
                  <div class="scene-index">{{ index + 1 }}</div>
                  <div class="scene-duration">{{ formData.clipDuration }}s</div>
                  <div class="scene-status">
                    <a-badge
                      :count="scene.candidates?.length || 0"
                      :number-style="{
                        backgroundColor: scene.candidates?.length
                          ? 'var(--color-primary-500)'
                          : 'var(--color-gray-300)'
                      }"
                    />
                  </div>
                </div>

                <!-- 场景内容 -->
                <div class="scene-body">
                  <template v-if="scene.candidates?.length > 0">
                    <div
                      v-for="(candidate, cIndex) in scene.candidates"
                      :key="cIndex"
                      class="candidate-thumb"
                      @click.stop="removeCandidate(index, cIndex)"
                    >
                      <img
                        v-if="getFileById(candidate.fileId)?.coverBase64"
                        :src="getFileById(candidate.fileId).coverBase64"
                      />
                      <div v-else class="thumb-placeholder">
                        <VideoCameraOutlined />
                      </div>
                      <div class="thumb-order">{{ cIndex + 1 }}</div>
                      <div class="thumb-remove">
                        <CloseOutlined />
                      </div>
                    </div>
                    <div
                      v-if="scene.candidates.length < constants.MAX_CANDIDATES_PER_SCENE"
                      class="candidate-add"
                      @click.stop="openSceneSelector(index)"
                    >
                      <PlusOutlined />
                      <span>继续添加</span>
                    </div>
                  </template>
                  <template v-else>
                    <div class="scene-empty" @click.stop="openSceneSelector(index)">
                      <PlusCircleOutlined />
                      <span>点击添加候选素材</span>
                      <span class="empty-hint">最多 {{ constants.MAX_CANDIDATES_PER_SCENE }} 个</span>
                    </div>
                  </template>
                </div>

                <!-- 场景底部：素材来源（只读） -->
                <div class="scene-footer">
                  <span class="source-label">来源:</span>
                  <a-tag
                    size="small"
                    :color="scene.groupId ? 'blue' : 'default'"
                  >
                    {{ getSceneEffectiveGroupName(scene) }}
                  </a-tag>
                </div>
              </div>
            </template>
          </draggable>
        </div>
      </section>
    </main>

    <!-- 高级设置抽屉 -->
    <a-drawer
      v-model:open="showSettings"
      title="高级设置"
      placement="right"
      :width="320"
    >
      <a-form layout="vertical">
        <a-form-item label="裁剪模式">
          <a-radio-group v-model:value="formData.cropMode" button-style="solid">
            <a-radio-button value="center">居中裁剪</a-radio-button>
            <a-radio-button value="fill">填充模式</a-radio-button>
          </a-radio-group>
        </a-form-item>

        <a-divider />

        <a-form-item label="统计信息">
          <div class="stats-row">
            <div class="stat-item">
              <span class="stat-value">{{ sceneCount }}</span>
              <span class="stat-label">场景数</span>
            </div>
            <div class="stat-item">
              <span class="stat-value">{{ filledCount }}</span>
              <span class="stat-label">已填充</span>
            </div>
            <div class="stat-item">
              <span class="stat-value">{{ actualTotalDuration }}s</span>
              <span class="stat-label">总时长</span>
            </div>
          </div>
        </a-form-item>
      </a-form>
    </a-drawer>

    <!-- 场景选择弹窗 -->
    <SceneSelectorModal
      v-model:visible="uiState.selectorVisible"
      :scene-index="uiState.currentSceneIndex"
      :scene-group-id="dataState.scenes[uiState.currentSceneIndex]?.groupId"
      :global-group-id="uiState.selectedLibraryGroup"
      :group-list="dataState.groupList"
      :all-group-files="dataState.allGroupFiles"
      :group-files="dataState.groupFiles"
      :initial-candidates="currentSceneCandidateIds"
      :max-candidates="constants.MAX_CANDIDATES_PER_SCENE"
      @confirm="handleModalConfirm"
      @load-group-files="loadGroupFiles"
    />

    <!-- 一键填充分组选择弹窗 -->
    <GroupSelectModal
      v-model:visible="uiState.groupSelectVisible"
      :group-list="dataState.groupList"
      @confirm="handleGroupSelectConfirm"
    />
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { useRouter } from 'vue-router'
import draggable from 'vuedraggable'

import {
  ArrowLeftOutlined,
  SettingOutlined,
  RocketOutlined,
  PlaySquareOutlined,
  ClearOutlined,
  ThunderboltOutlined,
  HolderOutlined,
  PlusOutlined,
  PlusCircleOutlined,
  CheckCircleFilled,
  VideoCameraOutlined,
  CloseOutlined
} from '@ant-design/icons-vue'

import { MaterialService, MaterialGroupService } from '@/api/material'
import { MixTaskService } from '@/api/mixTask'
import SceneSelectorModal from './components/SceneSelectorModal.vue'
import GroupSelectModal from './components/GroupSelectModal.vue'

const router = useRouter()

// ════════════════════════════════════════════════════════════════════════════
// 常量 & 工具函数
// ════════════════════════════════════════════════════════════════════════════
const constants = { MAX_CANDIDATES_PER_SCENE: 10 }

const createDeterministicRandom = (seed) => {
  let x = Math.sin(seed) * 10000
  return () => {
    x = Math.sin(x) * 10000
    return x - Math.floor(x)
  }
}

const randomlySelectMaterials = (count, materials, seed) => {
  const shuffled = [...materials]
  const random = createDeterministicRandom(seed)
  for (let i = shuffled.length - 1; i > 0; i--) {
    const j = Math.floor(random() * (i + 1))
    ;[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
  }
  return shuffled.slice(0, Math.min(count, shuffled.length)).map(m => ({
    fileId: m.id,
    fileUrl: m.fileUrl
  }))
}

// ════════════════════════════════════════════════════════════════════════════
// 状态
// ════════════════════════════════════════════════════════════════════════════
const showSettings = ref(false)

const formData = ref({
  title: '',
  produceCount: Number(localStorage.getItem('mix-produce-count')) || 3,
  totalDuration: 15,
  clipDuration: 5,
  cropMode: localStorage.getItem('mix-crop-mode') || 'center'
})

const uiState = ref({
  loadingGroups: false,
  loadingFiles: false,
  submitting: false,
  selectorVisible: false,
  currentSceneIndex: -1,
  selectedLibraryGroup: null,
  groupSelectVisible: false
})

const dataState = ref({
  groupList: [],
  groupFiles: [],
  allGroupFiles: {},
  scenes: []
})

// ════════════════════════════════════════════════════════════════════════════
// 计算属性
// ════════════════════════════════════════════════════════════════════════════
const sceneCount = computed(() =>
  Math.floor(formData.value.totalDuration / formData.value.clipDuration)
)

const actualTotalDuration = computed(() =>
  sceneCount.value * formData.value.clipDuration
)

const filledCount = computed(() =>
  dataState.value.scenes.filter(s => s.candidates?.length > 0).length
)

const progressPercent = computed(() =>
  sceneCount.value > 0 ? (filledCount.value / sceneCount.value) * 100 : 0
)

const currentSceneCandidateIds = computed(() => {
  const index = uiState.value.currentSceneIndex
  if (index < 0 || index >= dataState.value.scenes.length) return []
  return dataState.value.scenes[index]?.candidates?.map(c => c.fileId) || []
})

const canSubmit = computed(() => filledCount.value === sceneCount.value)

// ════════════════════════════════════════════════════════════════════════════
// 工具方法
// ════════════════════════════════════════════════════════════════════════════
const saveProduceCount = () => {
  localStorage.setItem('mix-produce-count', formData.value.produceCount.toString())
}

// 监听裁剪模式变化，保存到 localStorage
watch(() => formData.value.cropMode, (newVal) => {
  localStorage.setItem('mix-crop-mode', newVal)
})

const getFileById = (fileId) => {
  let file = dataState.value.groupFiles.find(f => f.id === fileId)
  if (file) return file
  for (const files of Object.values(dataState.value.allGroupFiles)) {
    file = files.find(f => f.id === fileId)
    if (file) return file
  }
  return null
}

const getSceneEffectiveGroupName = (scene) => {
  const effectiveGroupId = scene.groupId || uiState.value.selectedLibraryGroup
  if (!effectiveGroupId) return '默认'
  const group = dataState.value.groupList.find(g => g.id === effectiveGroupId)
  return group?.name || '未知'
}

// ════════════════════════════════════════════════════════════════════════════
// 场景管理
// ════════════════════════════════════════════════════════════════════════════
watch(sceneCount, (newCount) => {
  const current = dataState.value.scenes.length
  if (newCount > current) {
    for (let i = current; i < newCount; i++) {
      dataState.value.scenes.push({
        index: i,
        duration: formData.value.clipDuration,
        groupId: null,
        candidates: []
      })
    }
  } else if (newCount < current) {
    dataState.value.scenes = dataState.value.scenes.slice(0, newCount)
  }
}, { immediate: true })

const onSceneDragEnd = () => {
  dataState.value.scenes.forEach((scene, index) => {
    scene.index = index
  })
}

const clearScenes = () => {
  dataState.value.scenes = Array(sceneCount.value).fill(null).map((_, index) => ({
    index,
    duration: formData.value.clipDuration,
    groupId: null,
    candidates: []
  }))
  message.success('已清空所有场景')
}

const removeCandidate = (sceneIndex, candidateIndex) => {
  const candidates = dataState.value.scenes[sceneIndex]?.candidates
  if (candidates?.[candidateIndex] !== undefined) {
    candidates.splice(candidateIndex, 1)
    message.success('已移除候选')
  }
}

const openSceneSelector = (index) => {
  uiState.value.currentSceneIndex = index
  uiState.value.selectorVisible = true
}

const openGroupSelector = (index) => {
  const groups = dataState.value.groupList
  if (groups.length === 0) return

  const currentGroupId = dataState.value.scenes[index].groupId
  const currentIndex = groups.findIndex(g => g.id === currentGroupId)
  const nextIndex = (currentIndex + 1) % groups.length
  const nextGroup = groups[nextIndex]

  dataState.value.scenes[index].groupId = nextGroup.id
  dataState.value.scenes[index].candidates = []
  loadGroupFiles(nextGroup.id)
  message.success(`场景${index + 1} 切换到 ${nextGroup.name}`)
}

// ════════════════════════════════════════════════════════════════════════════
// 素材操作
// ════════════════════════════════════════════════════════════════════════════
const autoFillAllScenes = async () => {
  // 检查是否有分组
  if (dataState.value.groupList.length === 0) {
    message.warning('暂无素材分组，请先创建分组')
    return
  }

  // 如果没有选中分组，弹出选择弹窗
  if (!uiState.value.selectedLibraryGroup) {
    uiState.value.groupSelectVisible = true
    return
  }

  // 已有选中分组，直接填充
  await doAutoFill()
}

const handleGroupSelectConfirm = async (groupId) => {
  uiState.value.selectedLibraryGroup = groupId

  // 加载该分组的素材
  await handleLibraryGroupChange(groupId)

  // 执行填充
  await doAutoFill()
}

const doAutoFill = async () => {
  let filled = 0
  for (let i = 0; i < dataState.value.scenes.length; i++) {
    const scene = dataState.value.scenes[i]
    if (scene.candidates?.length >= 3) continue

    const groupId = scene.groupId || uiState.value.selectedLibraryGroup
    const materials = dataState.value.allGroupFiles[groupId] || await loadGroupFiles(groupId)

    if (materials.length === 0) continue

    const needed = 3 - (scene.candidates?.length || 0)
    const selected = randomlySelectMaterials(needed, materials, i + Date.now())
    scene.candidates = [...(scene.candidates || []), ...selected]
    filled++
  }

  if (filled > 0) {
    message.success(`已为 ${filled} 个场景填充候选素材`)
  } else {
    message.info('所有场景已满')
  }
}

// ════════════════════════════════════════════════════════════════════════════
// 数据加载
// ════════════════════════════════════════════════════════════════════════════
const loadGroups = async () => {
  uiState.value.loadingGroups = true
  try {
    const res = await MaterialGroupService.getGroupList()
    if (res.code === 0) {
      dataState.value.groupList = res.data || []
    }
  } catch {
    message.error('加载分组失败')
  } finally {
    uiState.value.loadingGroups = false
  }
}

const handleLibraryGroupChange = async (groupId) => {
  uiState.value.selectedLibraryGroup = groupId

  if (!dataState.value.allGroupFiles[groupId]) {
    uiState.value.loadingFiles = true
    try {
      const res = await MaterialService.getFilePage({
        groupId,
        fileCategory: 'video',
        pageNo: 1,
        pageSize: 50
      })
      if (res.code === 0) {
        dataState.value.allGroupFiles[groupId] = res.data.list || []
      }
    } catch {
      message.error('加载素材失败')
    } finally {
      uiState.value.loadingFiles = false
    }
  }
}

const loadGroupFiles = async (groupId) => {
  if (!groupId) return []
  if (dataState.value.allGroupFiles[groupId]) {
    return dataState.value.allGroupFiles[groupId]
  }

  try {
    const res = await MaterialService.getFilePage({
      groupId,
      fileCategory: 'video',
      pageNo: 1,
      pageSize: 50
    })
    if (res.code === 0) {
      const files = res.data.list || []
      dataState.value.allGroupFiles[groupId] = files
      return files
    }
  } catch {
    message.error('加载素材失败')
  }
  return []
}

// ════════════════════════════════════════════════════════════════════════════
// 弹窗处理
// ════════════════════════════════════════════════════════════════════════════
const handleModalConfirm = ({ sceneIndex, fileIds, setGroupId }) => {
  const scene = dataState.value.scenes[sceneIndex]
  if (!scene) return

  scene.candidates = fileIds.map(fileId => ({
    fileId,
    fileUrl: getFileById(fileId)?.fileUrl
  }))

  if (setGroupId !== null && setGroupId !== undefined) {
    scene.groupId = setGroupId
  }

  message.success(`场景 ${sceneIndex + 1} 已设置 ${scene.candidates.length} 个候选`)
}

// ════════════════════════════════════════════════════════════════════════════
// 提交
// ════════════════════════════════════════════════════════════════════════════
const handleSubmit = async () => {
  if (!canSubmit.value) return

  uiState.value.submitting = true
  try {
    const sceneConfigs = dataState.value.scenes.map(scene => ({
      duration: scene.duration,
      candidates: scene.candidates.map(candidate => ({
        fileId: candidate.fileId,
        fileUrl: candidate.fileUrl,
        fileDuration: getFileById(candidate.fileId)?.duration || null
      }))
    }))

    const res = await MixTaskService.createTask({
      title: formData.value.title || `混剪视频_${new Date().toLocaleString()}`,
      scenes: sceneConfigs,
      produceCount: formData.value.produceCount,
      cropMode: formData.value.cropMode
    })

    if (res.code === 0) {
      message.success('混剪任务创建成功！')
    }
  } catch (error) {
    message.error('提交失败：' + error.message)
  } finally {
    uiState.value.submitting = false
  }
}

// ════════════════════════════════════════════════════════════════════════════
// 生命周期
// ════════════════════════════════════════════════════════════════════════════
onMounted(() => {
  loadGroups()
})
</script>

<style scoped lang="less">
// ════════════════════════════════════════════════════════════════════════════
// 混剪页面 - 使用项目设计系统
// ════════════════════════════════════════════════════════════════════════════

// 🎨 使用 CSS 变量引用项目设计令牌
@primary: var(--color-primary-500);
@primary-light: var(--color-primary-50);
@primary-hover: var(--color-primary-400);

@success: var(--color-success-500);
@success-light: var(--color-success-50);

@warning: var(--color-warning-500);
@danger: var(--color-error-500);

@text: var(--color-text);
@text-secondary: var(--color-text-secondary);
@text-muted: var(--color-text-muted);
@text-disabled: var(--color-text-disabled);

@bg-page: var(--color-bg-page);
@bg-card: var(--color-bg-card);
@bg-elevated: var(--color-gray-100);

@border: var(--color-border);
@border-light: var(--color-gray-100);

// ════════════════════════════════════════════════════════════════════════════
// 页面容器
// ════════════════════════════════════════════════════════════════════════════
.mix-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: @bg-page;
  overflow: hidden;
}

// ════════════════════════════════════════════════════════════════════════════
// 顶部操作栏
// ════════════════════════════════════════════════════════════════════════════
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--header-height);
  padding: 0 var(--space-5);
  background: @bg-card;
  border-bottom: 1px solid @border;
  flex-shrink: 0;

  .header-left {
    display: flex;
    align-items: center;
    gap: var(--space-3);

    .page-title {
      margin: 0;
      font-size: var(--font-size-md);
      font-weight: 600;
      color: @text;
    }
  }

  .header-center {
    display: flex;
    align-items: center;
    gap: var(--space-4);

    .param-item {
      display: flex;
      align-items: center;
      gap: var(--space-2);

      .param-label {
        font-size: var(--font-size-sm);
        color: @text-secondary;
        white-space: nowrap;
      }

      .param-value {
        font-size: var(--font-size-sm);
        font-weight: 500;
        color: @primary;
        min-width: 28px;
      }

      :deep(.ant-slider) {
        margin: 0;

        .ant-slider-track {
          background: @primary;
        }

        .ant-slider-handle {
          border-color: @primary;
        }
      }

      :deep(.ant-select) {
        .ant-select-selector {
          height: 24px !important;
          line-height: 22px !important;
          padding: 0 var(--space-2) !important;
        }

        .ant-select-selection-item {
          line-height: 22px !important;
        }
      }
    }
  }

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

// ════════════════════════════════════════════════════════════════════════════
// 进度条 - 状态指示器
// ════════════════════════════════════════════════════════════════════════════
.progress-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: 36px;
  padding: 0 var(--space-5);
  background: @bg-card;
  border-bottom: 1px solid @border;

  .progress-track {
    flex: 1;
    max-width: 300px;
    height: 6px;
    background: @border;
    border-radius: 3px;
    overflow: hidden;

    .progress-fill {
      height: 100%;
      background: linear-gradient(90deg, var(--color-primary-400), var(--color-primary-600));
      border-radius: 3px;
      transition: width var(--duration-slow) ease;
    }
  }

  .progress-text {
    font-size: var(--font-size-sm);
    color: @text-secondary;
    display: flex;
    align-items: center;
    gap: var(--space-1);

    .icon-complete {
      color: var(--color-primary-400);
    }

    .icon-pending {
      font-weight: 500;
      color: @primary;
    }
  }
}

// ════════════════════════════════════════════════════════════════════════════
// 主内容区
// ════════════════════════════════════════════════════════════════════════════
.page-main {
  display: flex;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

// ════════════════════════════════════════════════════════════════════════════
// 场景区 - 全宽
// ════════════════════════════════════════════════════════════════════════════
.scenes-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: @bg-card;

  .section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 48px;
    padding: 0 var(--space-5);
    border-bottom: 1px solid @border-light;
    flex-shrink: 0;

    .section-title {
      display: flex;
      align-items: center;
      gap: var(--space-2);
      font-size: var(--font-size-base);
      font-weight: 500;
      color: @text;

      .anticon {
        color: @primary;
      }
    }

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

  .scenes-list {
    flex: 1;
    overflow-y: auto;
    padding: var(--space-4) var(--space-5);

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

.scene-card {
  background: @bg-elevated;
  border: 1px solid @border;
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: all var(--duration-base) ease;

  &:hover {
    border-color: @primary;
    box-shadow: var(--shadow-blue);
  }

  // ✅ 已完成状态 - 青色主题
  &--complete {
    border-left: 3px solid var(--color-primary-400);
    background: var(--color-primary-50);
  }

  .scene-header {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    background: @bg-card;
    border-bottom: 1px solid @border-light;

    .scene-drag {
      cursor: grab;
      color: @text-disabled;
      padding: var(--space-1);

      &:hover {
        color: @primary;
      }

      &:active {
        cursor: grabbing;
      }
    }

    .scene-index {
      width: 28px;
      height: 28px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: @primary;
      color: var(--color-text-inverse);
      font-size: var(--font-size-base);
      font-weight: 600;
      border-radius: var(--radius-button);
    }

    .scene-duration {
      font-size: var(--font-size-sm);
      color: @text-secondary;
      padding: 3px var(--space-2);
      background: var(--color-gray-100);
      border-radius: var(--radius-tag);
    }

    .scene-status {
      margin-left: auto;
    }
  }

  .scene-body {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-4);
    min-height: 90px;
    overflow-x: auto;

    .candidate-thumb {
      position: relative;
      width: 100px;
      height: 65px;
      border-radius: var(--radius-button);
      overflow: hidden;
      flex-shrink: 0;
      cursor: pointer;
      border: 2px solid transparent;
      transition: all var(--duration-base) ease;

      img {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }

      .thumb-placeholder {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        background: var(--color-gray-100);
        color: @text-disabled;
      }

      // 🏷️ 候选序号
      .thumb-order {
        position: absolute;
        top: var(--space-1);
        left: var(--space-1);
        width: 18px;
        height: 18px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: @warning;
        color: var(--color-text-inverse);
        font-size: var(--font-size-xs);
        font-weight: 600;
        border-radius: 50%;
      }

      // 🗑️ 删除遮罩
      .thumb-remove {
        position: absolute;
        inset: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        background: rgba(239, 68, 68, 0.9);
        color: var(--color-text-inverse);
        font-size: var(--font-size-md);
        opacity: 0;
        transition: opacity var(--duration-base) ease;
      }

      &:hover {
        border-color: @danger;

        .thumb-remove {
          opacity: 1;
        }
      }
    }

    // ➕ 添加更多
    .candidate-add {
      display: flex;
      align-items: center;
      gap: var(--space-1);
      padding: 18px var(--space-5);
      border: 2px dashed var(--color-gray-300);
      border-radius: var(--radius-button);
      color: @text-muted;
      font-size: var(--font-size-sm);
      cursor: pointer;
      flex-shrink: 0;
      transition: all var(--duration-base) ease;

      &:hover {
        border-color: @primary;
        color: @primary;
        background: @primary-light;
      }
    }

    // 📭 空状态
    .scene-empty {
      flex: 1;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: var(--space-2);
      padding: var(--space-6);
      border: 2px dashed var(--color-gray-300);
      border-radius: var(--radius-lg);
      color: @text-muted;
      font-size: var(--font-size-base);
      cursor: pointer;
      transition: all var(--duration-base) ease;

      .anticon {
        font-size: 28px;
        color: @text-disabled;
      }

      .empty-hint {
        font-size: var(--font-size-xs);
        color: @text-disabled;
      }

      &:hover {
        border-color: @primary;
        color: @primary;
        background: @primary-light;

        .anticon {
          color: @primary;
        }
      }
    }
  }

  // 📎 来源标签
  .scene-footer {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-4);
    border-top: 1px solid @border-light;
    background: @bg-card;

    .source-label {
      font-size: var(--font-size-xs);
      color: @text-muted;
    }
  }
}

// ════════════════════════════════════════════════════════════════════════════
// 统计信息 - 抽屉内
// ════════════════════════════════════════════════════════════════════════════
.stats-row {
  display: flex;
  gap: var(--space-3);

  .stat-item {
    flex: 1;
    text-align: center;
    padding: var(--space-3);
    background: var(--color-gray-100);
    border-radius: var(--radius-button);

    .stat-value {
      display: block;
      font-size: var(--font-size-xl);
      font-weight: 600;
      color: @primary;
    }

    .stat-label {
      display: block;
      font-size: var(--font-size-xs);
      color: @text-muted;
      margin-top: var(--space-1);
    }
  }
}

// ════════════════════════════════════════════════════════════════════════════
// 响应式适配
// ════════════════════════════════════════════════════════════════════════════
@media (max-width: 1000px) {
  .header-center {
    display: none !important;
  }
}

@media (max-width: 768px) {
  .page-header {
    flex-wrap: wrap;
    height: auto;
    padding: var(--space-3);
    gap: var(--space-2);

    .header-left {
      order: 1;
    }

    .header-right {
      order: 2;
    }

    .header-center {
      order: 3;
      width: 100%;
      justify-content: flex-start;
      display: flex !important;
    }
  }

  .scene-card {
    .scene-body {
      .candidate-thumb {
        width: 80px;
        height: 55px;
      }
    }
  }
}
</style>
