<template>
  <div class="material-list">
    <div class="material-list__header">
      <h1 class="material-list__title">素材列表</h1>
      <div class="material-list__actions">
        <a-button type="primary" @click="handleOpenUploadModal">
          <template #icon>
            <UploadOutlined />
          </template>
          上传素材
        </a-button>
        <a-button
          type="primary"
          ghost
          :disabled="selectedFileIds.length === 0"
          @click="handleOpenMixModal"
        >
          素材混剪
        </a-button>
        <a-button
          v-if="selectedFileIds.length > 0"
          type="primary"
          status="danger"
          @click="handleBatchDelete"
        >
          批量删除 ({{ selectedFileIds.length }})
        </a-button>
      </div>
    </div>

    <!-- 筛选条件 -->
    <div class="material-list__filters">
      <a-space>
        <a-select
          v-model:value="filters.fileCategory"
          style="width: 120px"
          placeholder="文件分类"
          @change="handleFilterChange"
        >
          <a-select-option value="">全部分类</a-select-option>
          <a-select-option value="video">视频</a-select-option>
          <a-select-option value="generate">生成</a-select-option>
          <a-select-option value="audio">音频</a-select-option>
          <a-select-option value="mix">混剪</a-select-option>
          <a-select-option value="voice">配音</a-select-option>
        </a-select>

        <a-input
          v-model="filters.fileName"
          placeholder="搜索文件名"
          style="width: 200px"
          allow-clear
          @press-enter="handleFilterChange"
        >
          <template #prefix>
            <SearchOutlined />
          </template>
        </a-input>
        <a-range-picker
          v-model:value="filters.createTime"
          style="width: 300px"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
          placeholder="['开始日期', '结束日期']"
          @change="handleFilterChange"
        />
        <a-button type="primary" @click="handleFilterChange">查询</a-button>
        <a-button @click="handleResetFilters">重置</a-button>
      </a-space>
    </div>

    <!-- 文件列表 -->
    <div class="material-list__content">
      <a-spin :spinning="loading" tip="加载中..." style="width: 100%; min-height: 400px;">
        <template v-if="fileList.length > 0">
          <div class="material-grid">
            <div
              v-for="file in fileList"
              :key="file.id"
              class="material-item"
              :class="{ 'material-item--selected': selectedFileIds.includes(file.id) }"
              @click="handleFileClick(file)"
            >
              <div class="material-item__content">
              <!-- 预览图 -->
              <div class="material-item__preview">
                <!-- 视频文件：统一使用 coverBase64，如果没有则使用 coverUrl，最后使用视频标签显示第一帧 -->
                <img
                  v-if="file.isVideo && (file.coverBase64 || file.coverUrl)"
                  :src="file.coverBase64"
                  :alt="file.fileName"
                  @error="handleImageError"
                />
                <!-- 视频文件：如果没有封面，使用视频标签显示第一帧 -->
                <video
                  v-else-if="file.isVideo && file.previewUrl"
                  :src="file.previewUrl"
                  muted
                  preload="metadata"
                  class="preview-video"
                />
                <!-- 图片或其他文件：使用图片标签 -->
                <!-- 优先级：coverUrl > coverBase64 > previewUrl -->
                <img
                  v-else-if="file.coverUrl || file.coverBase64 || file.previewUrl"
                  :src="file.coverUrl || file.coverBase64 || file.previewUrl"
                  :alt="file.fileName"
                  @error="handleImageError"
                />
                <div v-else class="material-item__placeholder">
                  <FileOutlined />
                </div>
                <!-- 文件类型标识 -->
                <div class="material-item__badge">
                  <a-tag v-if="file.isVideo" color="red">视频</a-tag>
                  <a-tag v-else-if="file.isImage" color="blue">图片</a-tag>
                  <a-tag v-else color="gray">文件</a-tag>
                </div>
                <!-- 删除图标 -->
                <div class="material-item__delete" @click.stop="handleDeleteFile(file)">
                  <DeleteOutlined />
                </div>
              </div>
              <!-- 文件信息 -->
              <div class="material-item__info">
                <div class="material-item__name" :title="file.fileName">
                  {{ file.fileName }}
                </div>
                <div class="material-item__meta">
                  <span>{{ formatFileSize(file.fileSize) }}</span>
                  <span>{{ formatDate(file.createTime) }}</span>
                </div>
              </div>
              </div>
            </div>
          </div>
        </template>
        <template v-else>
          <a-empty description="暂无素材" />
        </template>
      </a-spin>
    </div>

    <!-- 分页 -->
    <div class="material-list__pagination">
      <a-pagination
        v-model:current="pagination.pageNo"
        v-model:page-size="pagination.pageSize"
        :total="pagination.total"
        :show-total="(total) => `共 ${total} 条`"
        :show-size-changer="true"
        @change="handlePageChange"
      />
    </div>

    <!-- 上传对话框 -->
    <MaterialUploadModal
      v-model:visible="uploadModalVisible"
      :uploading="uploading"
      @confirm="handleConfirmUpload"
      @cancel="handleUploadCancel"
    />
    <a-modal
      v-model:open="mixModalVisible"
      title="素材混剪"
      centered
      :confirm-loading="mixing"
      ok-text="提交混剪"
      cancel-text="取消"
      @ok="handleMixConfirm"
      @cancel="handleMixCancel"
    >
      <div class="mix-modal__summary">
        <p>选中素材：{{ selectedFiles.length }} 个</p>
        <p>视频素材：{{ selectedVideoUrls.length }} 个</p>
        <p>背景音乐：{{ selectedAudioUrls.length }} 个</p>
      </div>
      <a-form layout="vertical">
        <a-form-item label="视频标题" required>
          <a-input v-model:value="mixForm.title" placeholder="请输入生成视频标题" />
        </a-form-item>
        <a-form-item label="文案内容" required>
          <a-textarea
            v-model:value="mixForm.text"
            placeholder="请输入文案（每句话换行以便自动拆分）"
            :rows="4"
          />
        </a-form-item>
        <a-form-item label="生成成片数量" required>
          <a-input-number
            v-model:value="mixForm.produceCount"
            :min="1"
            :max="10"
            style="width: 100%"
          />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { message, Modal } from 'ant-design-vue'
import {
  UploadOutlined,
  SearchOutlined,
  FileOutlined,
  DeleteOutlined
} from '@ant-design/icons-vue'
import { MaterialService } from '@/api/material'
import { MixService } from '@/api/mix'
import MaterialUploadModal from '@/components/material/MaterialUploadModal.vue'
import { formatFileSize, formatDate } from '@/utils/file'

// 数据
const loading = ref(false)
const fileList = ref([])
const selectedFileIds = ref([])
const uploadModalVisible = ref(false)
const uploading = ref(false)
const mixModalVisible = ref(false)
const mixing = ref(false)

// 筛选条件
const filters = reactive({
  fileCategory: 'video', // 默认分类为视频
  fileName: '',
  createTime: undefined
})

// 分页
const pagination = reactive({
  pageNo: 1,
  pageSize: 20,
  total: 0
})

// 构建查询参数
const buildQueryParams = () => {
  const params = {
    pageNo: pagination.pageNo,
    pageSize: pagination.pageSize,
    fileCategory: filters.fileCategory || undefined,
    fileName: filters.fileName || undefined
  }

  // 处理日期范围
  if (filters.createTime && Array.isArray(filters.createTime) && filters.createTime.length === 2) {
    params.createTime = [
      `${filters.createTime[0]} 00:00:00`,
      `${filters.createTime[1]} 23:59:59`
    ]
  }

  return params
}

// 加载文件列表
const loadFileList = async () => {
  loading.value = true
  try {
    const res = await MaterialService.getFilePage(buildQueryParams())
    if (res.code === 0) {
      fileList.value = res.data.list || []
      pagination.total = res.data.total || 0
    } else {
      message.error(res.msg || '加载失败')
    }
  } catch (error) {
    console.error('加载文件列表失败:', error)
    message.error('加载失败，请重试')
  } finally {
    loading.value = false
  }
}

// 打开上传对话框
const handleOpenUploadModal = () => {
  uploadModalVisible.value = true
}

// 确认上传
const handleConfirmUpload = async (filesWithCover, fileCategory) => {
  if (!filesWithCover?.length) {
    message.warning('请选择文件')
    return
  }

  uploading.value = true
  let successCount = 0
  let failCount = 0

  try {
    for (const { file, coverBase64 } of filesWithCover) {
      try {
        await MaterialService.uploadFile(file, fileCategory, coverBase64)
        successCount++
      } catch (error) {
        console.error('文件上传失败:', file.name, error)
        failCount++
      }
    }

    if (successCount > 0) {
      message.success(`成功上传 ${successCount} 个文件${failCount > 0 ? `，${failCount} 个失败` : ''}`)
      uploadModalVisible.value = false
      loadFileList()
    } else {
      message.error('所有文件上传失败，请重试')
    }
  } catch (error) {
    console.error('上传失败:', error)
    message.error(error.message || '上传失败，请重试')
  } finally {
    uploading.value = false
  }
}

// 取消上传
const handleUploadCancel = () => {
  uploadModalVisible.value = false
}

// 删除文件
const handleBatchDelete = () => {
  if (selectedFileIds.value.length === 0) return

  // 二次确认弹窗
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除选中的 ${selectedFileIds.value.length} 个文件吗？删除后无法恢复。`,
    okText: '确定删除',
    cancelText: '取消',
    okType: 'danger',
    onOk: async () => {
      try {
        await MaterialService.deleteFiles(selectedFileIds.value)
        message.success('删除成功')
        selectedFileIds.value = []
        loadFileList()
      } catch (error) {
        console.error('删除失败:', error)
        message.error(error.message || '删除失败，请重试')
      }
    }
  })
}

// 删除单个文件
const handleDeleteFile = (file) => {
  if (!file?.id) return

  // 二次确认弹窗
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除文件 "${file.fileName}" 吗？删除后无法恢复。`,
    okText: '确定删除',
    cancelText: '取消',
    okType: 'danger',
    onOk: async () => {
      try {
        await MaterialService.deleteFiles([file.id])
        message.success('删除成功')
        // 如果在选中列表中，也移除
        const index = selectedFileIds.value.indexOf(file.id)
        if (index > -1) {
          selectedFileIds.value.splice(index, 1)
        }
        loadFileList()
      } catch (error) {
        console.error('删除失败:', error)
        message.error(error.message || '删除失败，请重试')
      }
    }
  })
}

// 文件点击
const handleFileClick = (file) => {
  const isSelected = selectedFileIds.value.includes(file.id)
  // 切换选中状态
  if (isSelected) {
    selectedFileIds.value = selectedFileIds.value.filter(id => id !== file.id)
  } else {
    selectedFileIds.value.push(file.id)
  }
}

// 筛选
const handleFilterChange = () => {
  pagination.pageNo = 1
  loadFileList()
}

const handleResetFilters = () => {
  filters.fileCategory = 'video'
  filters.fileName = ''
  filters.createTime = undefined
  pagination.pageNo = 1
  loadFileList()
}

// 分页
const handlePageChange = (page, pageSize) => {
  pagination.pageNo = page
  if (pageSize && pageSize !== pagination.pageSize) {
    pagination.pageSize = pageSize
    pagination.pageNo = 1
  }
  loadFileList()
}

// 图片加载错误处理（支持回退到其他图片源）
const handleImageError = (e) => {
  const img = e.target
  const currentSrc = img.src
  
  // 找到对应的文件对象
  const file = fileList.value.find(f => 
    f.coverBase64 === currentSrc || 
    f.coverUrl === currentSrc || 
    f.previewUrl === currentSrc
  )
  
  if (file) {
    // 视频文件：优先使用 coverBase64，如果失败则尝试 coverUrl，最后尝试 previewUrl
    if (file.isVideo) {
      if (currentSrc === file.coverBase64 && file.coverUrl && file.coverUrl !== currentSrc) {
        // coverBase64 失败，尝试 coverUrl
        img.src = file.coverUrl
        return
      }
      if ((currentSrc === file.coverBase64 || currentSrc === file.coverUrl) && file.previewUrl && file.previewUrl !== currentSrc) {
        // coverBase64 和 coverUrl 都失败，尝试 previewUrl（视频第一帧）
        img.src = file.previewUrl
        return
      }
    } else {
      // 非视频文件：尝试其他图片源
      if (file.coverUrl && file.coverUrl !== currentSrc) {
        img.src = file.coverUrl
        return
      }
      if (file.coverBase64 && file.coverBase64 !== currentSrc && file.coverBase64.startsWith('data:image')) {
        img.src = file.coverBase64
        return
      }
      if (file.previewUrl && file.previewUrl !== currentSrc) {
        img.src = file.previewUrl
        return
      }
    }
  }
  
  // 如果所有图片源都失败，隐藏图片
  img.style.display = 'none'
}

const selectedFiles = computed(() =>
  fileList.value.filter((file) => selectedFileIds.value.includes(file.id))
)

const isVideoFile = (file) => {
  if (!file) return false
  if (file.isVideo) return true
  if (file.fileCategory === 'video') return true
  if (typeof file.fileType === 'string' && file.fileType.startsWith('video')) return true
  return false
}

const isAudioFile = (file) => {
  if (!file) return false
  if (file.fileCategory === 'audio') return true
  if (file.fileType === 'audio') return true
  if (typeof file.fileType === 'string' && file.fileType.startsWith('audio')) return true
  return false
}

const selectedVideoUrls = computed(() =>
  selectedFiles.value.map((file) => (isVideoFile(file) ? file?.fileUrl || file?.previewUrl : null)).filter(Boolean)
)

const selectedAudioUrls = computed(() =>
  selectedFiles.value.map((file) => (isAudioFile(file) ? file?.fileUrl || file?.previewUrl : null)).filter(Boolean)
)

const mixForm = reactive({
  title: '',
  text: '',
  produceCount: 1
})

const resetMixForm = () => {
  mixForm.title = ''
  mixForm.text = ''
  mixForm.produceCount = 1
}

const handleOpenMixModal = () => {
  if (selectedFileIds.value.length === 0) {
    message.warning('请先选择至少一个素材')
    return
  }
  if (selectedVideoUrls.value.length === 0) {
    message.warning('请至少选择一个视频素材')
    return
  }
  if (selectedAudioUrls.value.length === 0) {
    message.warning('请至少选择一个背景音乐素材')
    return
  }
  mixModalVisible.value = true
}

const handleMixCancel = () => {
  mixModalVisible.value = false
}

const handleMixConfirm = async () => {
  const title = mixForm.title.trim()
  const text = mixForm.text.trim()
  if (!title) {
    message.warning('请输入视频标题')
    return
  }
  if (!text) {
    message.warning('请输入文案内容')
    return
  }
  const produceCount = Math.max(1, Math.min(10, Number(mixForm.produceCount) || 1))
  if (selectedVideoUrls.value.length === 0) {
    message.warning('请至少选择一个视频素材')
    return
  }
  if (selectedAudioUrls.value.length === 0) {
    message.warning('请至少选择一个背景音乐素材')
    return
  }
  mixing.value = true
  try {
    const { data } = await MixService.batchProduceAlignment({
      title,
      text,
      videoUrls: selectedVideoUrls.value,
      bgMusicUrls: selectedAudioUrls.value,
      produceCount
    })
    const jobIds = Array.isArray(data) ? data : []
    message.success(
      jobIds.length > 0
        ? `混剪任务提交成功，JobId：${jobIds.join(', ')}`
        : '混剪任务提交成功'
    )
    mixModalVisible.value = false
    resetMixForm()
  } catch (error) {
    console.error('混剪失败:', error)
    message.error(error?.message || '混剪任务提交失败，请重试')
  } finally {
    mixing.value = false
  }
}

// 初始化
onMounted(() => {
  loadFileList()
})
</script>

<style scoped>
.material-list {
  padding: 24px;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.material-list__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
}

.material-list__title {
  font-size: 24px;
  font-weight: 600;
  margin: 0;
}

.material-list__actions {
  display: flex;
  gap: 12px;
}

.material-list__filters {
  margin-bottom: 24px;
  padding: 16px;
  background: var(--color-surface);
  border-radius: var(--radius-card);
  border: 1px solid var(--color-border);
}

.material-list__content {
  flex: 1;
  overflow-y: auto;
  margin-bottom: 24px;
  position: relative;
}

.material-list__content :deep(.arco-spin) {
  min-height: 400px;
}

.material-list__content :deep(.arco-spin-content) {
  min-height: 400px;
}

.material-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
}

.material-list__pagination {
  display: flex;
  justify-content: center;
}

.material-item {
  cursor: pointer;
}

.material-item__content {
  background: var(--color-surface);
  border: 2px solid transparent;
  border-radius: var(--radius-card);
  overflow: hidden;
  transition: border-color 0.2s;
}

.material-item--selected .material-item__content {
  border-color: var(--color-primary);
}

.material-item__preview {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 */
  background: var(--color-bg-2);
  overflow: hidden;
}

.material-item__preview img,
.material-item__preview video {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.material-item__preview video {
  pointer-events: none; /* 禁用视频交互，避免点击播放 */
}

.material-item__placeholder {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 48px;
  color: var(--color-text-3);
}

.material-item__badge {
  position: absolute;
  top: 8px;
  left: 8px;
}

.material-item__delete {
  position: absolute;
  bottom: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  background: rgba(255, 77, 79, 0.9);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  cursor: pointer;
  opacity: 0;
  transition: all 0.3s;
  font-size: 16px;
}

.material-item:hover .material-item__delete {
  opacity: 1;
}

.material-item__delete:hover {
  background: rgb(255, 77, 79);
  transform: scale(1.1);
}

.material-item__info {
  padding: 12px;
}

.material-item__name {
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.material-item__meta {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--color-text-3);
}

.mix-modal__summary {
  margin-bottom: 16px;
  padding: 12px;
  background: var(--color-bg-2);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-card);
  font-size: 13px;
  color: var(--color-text-2);
}

.mix-modal__summary p {
  margin: 0;
  line-height: 1.6;
}

</style>

