<template>
  <div class="mix-page">
    <!-- 页面头部 -->
    <div class="mix-page__header">
      <h1 class="mix-page__title">智能混剪</h1>
      <a-button @click="$router.push('/material/list')">
        <template #icon><ArrowLeftOutlined /></template>
        返回素材列表
      </a-button>
    </div>

    <div class="mix-page__content">
      <!-- 左侧：参数配置 -->
      <div class="mix-page__params">
        <a-card title="混剪参数" :bordered="false">
          <a-form layout="vertical">
            <!-- 分组选择 -->
            <a-form-item label="选择素材分组" required>
              <a-select
                v-model:value="formData.groupId"
                placeholder="请选择素材分组"
                :loading="loadingGroups"
                @change="handleGroupChange"
              >
                <a-select-option v-for="g in groupList" :key="g.id" :value="g.id">
                  {{ g.name }}
                </a-select-option>
              </a-select>
            </a-form-item>

            <!-- 视频标题 -->
            <a-form-item label="视频标题" required>
              <a-input
                v-model:value="formData.title"
                placeholder="请输入生成视频的标题"
                :maxlength="50"
                show-count
              />
            </a-form-item>

            <!-- 生成数量 -->
            <a-form-item label="生成数量">
              <a-radio-group v-model:value="formData.produceCount" button-style="solid" @change="saveProduceCount">
                <a-radio-button :value="1">1个</a-radio-button>
                <a-radio-button :value="3">3个</a-radio-button>
                <a-radio-button :value="5">5个</a-radio-button>
                <a-radio-button :value="10">10个</a-radio-button>
                <a-radio-button :value="15">15个</a-radio-button>
              </a-radio-group>
            </a-form-item>

            <!-- 成品总时长 -->
            <a-form-item label="成品总时长">
              <div class="mix-page__slider-box">
                <a-slider
                  v-model:value="formData.totalDuration"
                  :min="15"
                  :max="30"
                  :step="1"
                  :marks="{ 15: '15s', 20: '20s', 25: '25s', 30: '30s' }"
                />
                <div class="slider-value">{{ formData.totalDuration }}秒</div>
              </div>
            </a-form-item>

            <!-- 单切片时长 -->
            <a-form-item label="单切片时长">
              <div class="mix-page__slider-box">
                <a-slider
                  v-model:value="formData.clipDuration"
                  :min="3"
                  :max="5"
                  :step="1"
                  :marks="{ 3: '3s', 4: '4s', 5: '5s' }"
                />
                <div class="slider-value">{{ formData.clipDuration }}秒</div>
              </div>
            </a-form-item>

            <!-- 裁剪模式 -->
            <a-form-item label="裁剪模式">
              <a-radio-group v-model:value="formData.cropMode" button-style="solid">
                <a-radio-button value="center" class="crop-btn">
                  居中裁剪
                </a-radio-button>
                <a-radio-button value="fill" class="crop-btn">
                  填充模式
                </a-radio-button>
              </a-radio-group>
            </a-form-item>

            <!-- 自动计算的场景数 -->
            <div class="mix-page__scene-info">
              <div class="scene-row">
                <span>场景数</span>
                <strong>{{ sceneCount }} 个</strong>
              </div>
              <div class="scene-row">
                <span>实际总时长</span>
                <strong>{{ actualTotalDuration }}秒</strong>
              </div>
              <div class="scene-row">
                <span>已填充</span>
                <strong :class="{ 'text-green': filledCount === sceneCount }">
                  {{ filledCount }} / {{ sceneCount }}
                </strong>
              </div>
            </div>

            <!-- 一键填充按钮 -->
            <a-button
              block
              size="large"
              style="margin-bottom: 12px"
              :disabled="!groupFiles.length"
              @click="autoFillScenes"
            >
              <template #icon><ThunderboltOutlined /></template>
              一键填充
            </a-button>

            <a-button
              type="primary"
              block
              size="large"
              :loading="submitting"
              :disabled="!canSubmit"
              @click="handleSubmit"
            >
              <template #icon><RocketOutlined /></template>
              开始混剪
            </a-button>
          </a-form>
        </a-card>
      </div>

      <!-- 右侧：场景格子 + 素材列表 -->
      <div class="mix-page__preview">
        <!-- 场景格子区域 -->
        <a-card title="场景编排" :bordered="false" style="margin-bottom: 16px">
          <template #extra>
            <a-button size="small" @click="clearScenes">清空</a-button>
          </template>

          <div class="mix-page__scenes">
            <div
              v-for="(scene, index) in scenes"
              :key="index"
              class="mix-page__scene"
              :class="{ 'mix-page__scene--filled': scene.fileId }"
              @click="openSceneSelector(index)"
            >
              <!-- 场景序号 -->
              <span class="scene-index">{{ index + 1 }}</span>

              <!-- 已填充：显示封面 -->
              <template v-if="scene.fileId">
                <img
                  v-if="getFileById(scene.fileId)?.coverBase64"
                  :src="getFileById(scene.fileId).coverBase64"
                  class="scene-thumb"
                />
                <div v-else class="scene-placeholder filled">
                  <VideoCameraOutlined />
                </div>
                <div class="scene-name">{{ getFileById(scene.fileId)?.fileName }}</div>
                <a-button
                  class="scene-remove"
                  type="text"
                  size="small"
                  danger
                  @click.stop="removeScene(index)"
                >
                  <CloseOutlined />
                </a-button>
              </template>

              <!-- 未填充：空白格子 -->
              <template v-else>
                <div class="scene-placeholder">
                  <PlusOutlined />
                </div>
                <div class="scene-hint">点击选择</div>
              </template>

              <!-- 时长标签 -->
              <span class="scene-duration">{{ formData.clipDuration }}s</span>
            </div>
          </div>
        </a-card>

        <!-- 素材库 -->
        <a-card title="素材库" :bordered="false">
          <a-spin :spinning="loadingFiles">
            <div v-if="groupFiles.length > 0" class="mix-page__grid">
              <div
                v-for="file in groupFiles"
                :key="file.id"
                class="mix-page__item"
                :class="{ 'mix-page__item--used': isFileUsed(file.id) }"
                @click="handleFileClick(file)"
              >
                <!-- 封面图 -->
                <div class="mix-page__thumb">
                  <img v-if="file.isVideo && file.coverBase64" :src="file.coverBase64" :alt="file.fileName" />
                  <div v-else class="mix-page__placeholder">
                    <VideoCameraOutlined />
                  </div>
                </div>

                <!-- 已使用标记 -->
                <span v-if="isFileUsed(file.id)" class="mix-page__used-badge">
                  已使用 ×{{ getFileUsageCount(file.id) }}
                </span>

                <!-- 文件名 -->
                <div class="mix-page__name" :title="file.fileName">
                  {{ file.fileName }}
                </div>
              </div>
            </div>

            <a-empty v-else description="请先选择素材分组" />
          </a-spin>
        </a-card>
      </div>
    </div>

    <!-- 素材选择弹窗 -->
    <a-modal
      v-model:open="selectorVisible"
      title="选择素材"
      :footer="null"
      width="600px"
    >
      <div class="mix-page__selector-grid">
        <div
          v-for="file in groupFiles"
          :key="file.id"
          class="mix-page__selector-item"
          @click="selectFileForScene(file)"
        >
          <div class="selector-thumb">
            <img v-if="file.isVideo && file.coverBase64" :src="file.coverBase64" />
            <VideoCameraOutlined v-else />
          </div>
          <div class="selector-name">{{ file.fileName }}</div>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { useRouter } from 'vue-router'
import {
  ArrowLeftOutlined,
  RocketOutlined,
  VideoCameraOutlined,
  PlusOutlined,
  CloseOutlined,
  ThunderboltOutlined
} from '@ant-design/icons-vue'
import { MaterialService, MaterialGroupService } from '@/api/material'
import { MixTaskService } from '@/api/mixTask'

const router = useRouter()

// 表单数据
const formData = ref({
  groupId: null,
  title: '',
  produceCount: loadProduceCount(),
  totalDuration: 15,  // 成品总时长 15-30s
  clipDuration: 3,    // 单切片时长 3-5s
  cropMode: 'center'  // 裁剪模式，默认居中裁剪
})

// 本地存储键名
const STORAGE_KEY = 'mix-produce-count'

// 从本地存储加载生成数量
function loadProduceCount() {
  const saved = localStorage.getItem(STORAGE_KEY)
  return saved ? parseInt(saved, 10) : 3
}

// 保存生成数量到本地存储
function saveProduceCount() {
  localStorage.setItem(STORAGE_KEY, formData.value.produceCount.toString())
}

// 状态
const loadingGroups = ref(false)
const loadingFiles = ref(false)
const submitting = ref(false)
const selectorVisible = ref(false)
const currentSceneIndex = ref(-1)

// 分组和文件
const groupList = ref([])
const groupFiles = ref([])

// 场景列表 [{ fileId, fileUrl }, ...]
const scenes = ref([])

// 计算场景数 = 总时长 / 单切片时长
const sceneCount = computed(() => {
  return Math.floor(formData.value.totalDuration / formData.value.clipDuration)
})

// 实际总时长 = 场景数 × 单切片时长
const actualTotalDuration = computed(() => {
  return sceneCount.value * formData.value.clipDuration
})

// 已填充数量
const filledCount = computed(() => {
  return scenes.value.filter(s => s.fileId).length
})

// 监听场景数变化，自动调整场景数组
watch(sceneCount, (newCount) => {
  const current = scenes.value.length
  if (newCount > current) {
    // 增加空场景
    for (let i = current; i < newCount; i++) {
      scenes.value.push({ fileId: null, fileUrl: null })
    }
  } else if (newCount < current) {
    // 减少场景
    scenes.value = scenes.value.slice(0, newCount)
  }
}, { immediate: true })

// 根据fileId获取文件信息
const getFileById = (fileId) => {
  return groupFiles.value.find(f => f.id === fileId)
}

// 检查文件是否已使用
const isFileUsed = (fileId) => {
  return scenes.value.some(s => s.fileId === fileId)
}

// 获取文件使用次数
const getFileUsageCount = (fileId) => {
  return scenes.value.filter(s => s.fileId === fileId).length
}

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

// 分组变更时加载素材
const handleGroupChange = async (groupId) => {
  if (!groupId) {
    groupFiles.value = []
    clearScenes()
    return
  }

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

// 打开场景选择器
const openSceneSelector = (index) => {
  currentSceneIndex.value = index
  selectorVisible.value = true
}

// 为场景选择文件
const selectFileForScene = (file) => {
  if (currentSceneIndex.value >= 0 && currentSceneIndex.value < scenes.value.length) {
    scenes.value[currentSceneIndex.value] = {
      fileId: file.id,
      fileUrl: file.fileUrl
    }
  }
  selectorVisible.value = false
}

// 点击素材库文件：填充到第一个空场景
const handleFileClick = (file) => {
  const emptyIndex = scenes.value.findIndex(s => !s.fileId)
  if (emptyIndex >= 0) {
    scenes.value[emptyIndex] = {
      fileId: file.id,
      fileUrl: file.fileUrl
    }
  } else {
    message.info('所有场景已填满')
  }
}

// 移除场景
const removeScene = (index) => {
  scenes.value[index] = { fileId: null, fileUrl: null }
}

// 清空场景
const clearScenes = () => {
  scenes.value = Array(sceneCount.value).fill(null).map(() => ({ fileId: null, fileUrl: null }))
}

// 一键填充：随机分配素材到空场景
const autoFillScenes = () => {
  if (!groupFiles.value.length) {
    message.warning('请先选择素材分组')
    return
  }

  // 打乱素材顺序
  const shuffled = [...groupFiles.value].sort(() => Math.random() - 0.5)
  let fileIndex = 0

  // 填充每个空场景
  scenes.value = scenes.value.map(scene => {
    if (!scene.fileId) {
      const file = shuffled[fileIndex % shuffled.length]
      fileIndex++
      return { fileId: file.id, fileUrl: file.fileUrl }
    }
    return scene
  })

  message.success('已随机填充所有场景')
}

// 是否可提交
const canSubmit = computed(() => {
  return formData.value.groupId &&
         formData.value.title.trim() &&
         filledCount.value === sceneCount.value
})

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

  submitting.value = true
  try {
    // 构建素材列表（带上素材实际时长 fileDuration）
    const materials = scenes.value.map(scene => {
      const file = getFileById(scene.fileId)
      return {
        fileId: scene.fileId,
        fileUrl: scene.fileUrl,
        duration: formData.value.clipDuration,
        fileDuration: file?.duration || null  // 素材实际时长
      }
    })

    const res = await MixTaskService.createTask({
      title: formData.value.title,
      materials: materials,
      produceCount: formData.value.produceCount,
      cropMode: formData.value.cropMode
    })

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

onMounted(() => {
  loadGroups()
})
</script>

<style scoped lang="less">
.mix-page {
  padding: 24px;
  background: var(--color-bg-2);
  min-height: 100vh;

  &__header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 24px;
  }

  &__title {
    font-size: 24px;
    font-weight: 600;
    margin: 0;
  }

  &__content {
    display: flex;
    gap: 24px;
  }

  &__params {
    width: 340px;
    flex-shrink: 0;

    .ant-card {
      position: sticky;
      top: 24px;
    }
  }

  &__preview {
    flex: 1;
    min-width: 0;
  }

  &__slider-box {
    .slider-value {
      text-align: center;
      margin-top: 8px;
      font-size: 16px;
      font-weight: 600;
      color: #1890ff;
    }
  }

  &__scene-info {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 16px;
    padding: 16px;
    background: var(--color-bg-3);
    border-radius: 8px;

    .scene-row {
      display: flex;
      justify-content: space-between;
      align-items: center;

      span {
        color: #666;
        font-size: 14px;
      }

      strong {
        color: #333;
        font-size: 16px;

        &.text-green {
          color: #52c41a;
        }
      }
    }
  }

  // 场景格子样式
  &__scenes {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
  }

  &__scene {
    position: relative;
    width: 120px;
    height: 100px;
    border: 2px dashed #d9d9d9;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #fafafa;

    &:hover {
      border-color: #1890ff;
      background: #f0f7ff;
    }

    &--filled {
      border-style: solid;
      border-color: #1890ff;
      background: #fff;
    }

    .scene-index {
      position: absolute;
      top: 4px;
      left: 4px;
      width: 20px;
      height: 20px;
      background: rgba(0, 0, 0, 0.5);
      color: #fff;
      border-radius: 4px;
      font-size: 12px;
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 2;
    }

    .scene-thumb {
      width: 100%;
      height: 60px;
      object-fit: cover;
      border-radius: 4px 4px 0 0;
    }

    .scene-placeholder {
      font-size: 24px;
      color: #bfbfbf;

      &.filled {
        color: #1890ff;
      }
    }

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

    .scene-name {
      font-size: 11px;
      color: #333;
      padding: 4px;
      text-align: center;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      width: 100%;
    }

    .scene-duration {
      position: absolute;
      bottom: 4px;
      right: 4px;
      background: rgba(0, 0, 0, 0.6);
      color: #fff;
      padding: 2px 6px;
      border-radius: 4px;
      font-size: 10px;
    }

    .scene-remove {
      position: absolute;
      top: 2px;
      right: 2px;
      z-index: 3;
    }
  }

  // 素材库格子样式
  &__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 12px;
  }

  &__item {
    position: relative;
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
    transition: all 0.2s;
    border: 2px solid transparent;
    background: #fff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);

    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
      border-color: #1890ff;
    }

    &--used {
      opacity: 0.6;
    }
  }

  &__thumb {
    aspect-ratio: 16 / 9;
    background: #f0f0f0;
    overflow: hidden;

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

  &__placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #bfbfbf;
    font-size: 24px;
  }

  &__used-badge {
    position: absolute;
    top: 4px;
    right: 4px;
    background: #1890ff;
    color: #fff;
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 10px;
  }

  &__name {
    padding: 8px;
    font-size: 12px;
    color: #333;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  // 选择器弹窗样式
  &__selector-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    max-height: 400px;
    overflow-y: auto;
  }

  &__selector-item {
    cursor: pointer;
    border-radius: 8px;
    overflow: hidden;
    border: 2px solid transparent;
    transition: all 0.2s;

    &:hover {
      border-color: #1890ff;
    }

    .selector-thumb {
      aspect-ratio: 16 / 9;
      background: #f0f0f0;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #bfbfbf;
      font-size: 24px;

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

    .selector-name {
      padding: 6px;
      font-size: 11px;
      text-align: center;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
}
</style>
