<template>
  <div class="p-2">
    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
      <div v-show="showSearch" class="mb-[10px]">
        <el-card shadow="hover">
          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
            <el-form-item label="视频标题" prop="title">
              <el-input v-model="queryParams.title" placeholder="请输入视频标题" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="状态" prop="status">
              <el-select v-model="queryParams.status" placeholder="请选择状态" clearable @change="handleQuery">
                <el-option label="上架" value="up" />
                <el-option label="下架" value="down" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </div>
    </transition>

    <el-card shadow="never">
      <template #header>
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['physical:videoContent:add']">新增</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['physical:videoContent:edit']"
              >修改</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['physical:videoContent:remove']"
              >删除</el-button
            >
          </el-col>
          <el-col :span="3">
            <el-button type="warning" plain icon="Wrench" @click="handleFixAll" v-hasPermi="['physical:videoContent:edit']" :loading="isFixing"
              >修复所有数据</el-button
            >
          </el-col>
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
        </el-row>
      </template>

      <el-table v-loading="loading" border :data="videoContentList" @selection-change="handleSelectionChange" :row-height="60">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="编号" align="center" prop="id" v-if="true" />
        <el-table-column label="视频标题" align="center" prop="title" />
        <el-table-column label="文件名" align="center" prop="videoFileName" width="180">
          <template #default="scope">
            <span class="file-name-ellipsis" :title="scope.row.videoFileName">{{ scope.row.videoFileName }}</span>
          </template>
        </el-table-column>
        <el-table-column label="封面" align="center" width="90">
          <template #default="scope">
            <el-image
              v-if="scope.row.videoCoverUrl"
              :src="scope.row.videoCoverUrl"
              style="width: 40px; height: 40px; border-radius: 4px; cursor: zoom-in"
              :preview-src-list="[scope.row.videoCoverUrl]"
              :preview-teleported="true"
              fit="cover"
            />
            <span v-else></span>
          </template>
        </el-table-column>
        <el-table-column label="观看人数" align="center" prop="videoSeeCount" />
        <el-table-column label="所需视频点" align="center" prop="requiredPoints" />
        <el-table-column label="所属标签" align="center" prop="serviceTagName" />
        <el-table-column label="视频时长(秒)" align="center">
          <template #default="{ row }">
            <span
              :class="{ 'text-danger': !isDurationValid(row.durationSeconds) && row.durationSeconds !== null && row.durationSeconds !== undefined }"
            >
              {{ row.durationSeconds ?? '待更新' }}
              <span
                v-if="!isDurationValid(row.durationSeconds) && row.durationSeconds !== null && row.durationSeconds !== undefined"
                style="font-size: 12px; color: #f56c6c"
                >(异常)</span
              >
              <span v-if="row.durationSeconds === null || row.durationSeconds === undefined" style="font-size: 12px; color: #909399"
                >(待异步更新)</span
              >
            </span>
          </template>
        </el-table-column>
        <el-table-column label="试看时长(秒)" align="center" prop="previewDurationSeconds" />
        <el-table-column label="订阅时效(天)" align="center" prop="subscriptionValidHours" />
        <el-table-column label="数据状态" align="center">
          <template #default="{ row }">
            <el-tag :type="isVideoDataValid(row) ? 'success' : 'danger'">
              {{ isVideoDataValid(row) ? '正常' : '异常' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="视频状态" align="center">
          <template #default="{ row }">
            <el-tag :type="row.status === 'up' ? 'success' : 'info'">
              {{ row.status === 'up' ? '已上架' : '未上架' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="创建时间" align="center" prop="createdAt" width="180">
          <template #default="scope">
            <span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="80">
          <template #default="scope">
            <el-dropdown trigger="click" placement="bottom">
              <span style="color: #303133; cursor: pointer; font-size: 14px; font-weight: 500">
                操作 <span style="font-size: 14px; margin-left: 2px">▼</span>
              </span>
              <template #dropdown>
                <el-dropdown-menu style="min-width: 100px; padding: 4px 0">
                  <el-dropdown-item @click="handleUpdate(scope.row)" v-hasPermi="['physical:videoContent:edit']">修改</el-dropdown-item>
                  <el-dropdown-item @click="handleDelete(scope.row)" v-hasPermi="['physical:videoContent:remove']">删除</el-dropdown-item>
                  <el-dropdown-item @click="matchFromBackup(scope.row)" v-hasPermi="['physical:videoContent:edit']">异步获取</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </template>
        </el-table-column>
      </el-table>

      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
    </el-card>

    <!-- 添加或修改视频内容信息对话框 -->
    <el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" append-to-body>
      <el-form ref="videoContentFormRef" :model="form" :rules="rules" label-width="120px">
        <el-form-item label="视频标题" prop="title">
          <el-input v-model="form.title" placeholder="请输入视频标题" />
        </el-form-item>
        <el-form-item label="视频封面图" prop="videoCoverUrl">
          <div class="upload-container">
            <el-upload
              class="upload-icon"
              action="#"
              :on-change="handleVideoCoverUrlChange"
              :on-remove="handleVideoCoverUrlRemove"
              :file-list="videoCoverUrlFileList"
              :auto-upload="false"
              :limit="1"
              accept="image/*"
            >
              <template #trigger>
                <el-button type="primary">点击选择封面图</el-button>
              </template>
              <template #default>
                <div class="preview-area">
                  <template v-if="coverUploading">
                    <div style="margin-top: 10px; width: 200px">
                      <div style="display: flex; justify-content: space-between; margin-bottom: 5px; font-size: 14px">
                        <span>上传中...</span>
                        <span>{{ coverUploadProgress }}%</span>
                      </div>
                      <el-progress :percentage="coverUploadProgress" :stroke-width="15" />
                    </div>
                  </template>
                  <template v-else>
                    <div v-if="videoCoverUrlPreviewUrl || form.videoCoverUrl" style="position: relative; display: inline-block">
                      <img
                        :src="videoCoverUrlPreviewUrl || form.videoCoverUrl"
                        alt="预览图"
                        style="max-width: 100px; max-height: 100px; margin-top: 10px; cursor: pointer"
                        @click="handleVideoCoverUrlPreviewClick"
                      />
                      <el-button
                        type="danger"
                        size="small"
                        icon="Delete"
                        @click.stop="handleVideoCoverUrlRemove"
                        style="position: absolute; top: 5px; right: -50px"
                        >删除</el-button
                      >
                    </div>
                    <div v-else style="margin-top: 10px; color: #999">无图片</div>
                  </template>
                </div>
              </template>
            </el-upload>
          </div>
        </el-form-item>
        <el-form-item label="视频文件" prop="ossVideoUrl">
          <div class="upload-container">
            <el-upload
              class="upload-icon"
              action="#"
              :on-change="handleOssVideoUrlChange"
              :on-remove="handleOssVideoUrlRemove"
              :file-list="ossVideoUrlFileList"
              :auto-upload="false"
              :limit="1"
              accept="video/*"
            >
              <template #trigger>
                <el-button type="primary">点击选择视频</el-button>
              </template>
              <template #default>
                <div class="preview-area">
                  <template v-if="uploading && uploadProgress < 100">
                    <div style="margin-top: 10px; width: 300px">
                      <div style="display: flex; justify-content: space-between; margin-bottom: 5px; font-size: 14px">
                        <span>上传中...</span>
                        <span>{{ uploadProgress }}%</span>
                      </div>
                      <el-progress :percentage="uploadProgress" :stroke-width="20" />
                    </div>
                  </template>
                  <template v-else-if="uploading && uploadProgress >= 100">
                    <div style="margin-top: 10px; width: 300px">
                      <div style="display: flex; justify-content: space-between; margin-bottom: 5px; font-size: 14px">
                        <span>处理中...</span>
                        <span>100%</span>
                      </div>
                      <el-progress :percentage="100" :stroke-width="20" status="success" />
                    </div>
                    <video
                      v-if="ossVideoUrlPreviewUrl"
                      :src="ossVideoUrlPreviewUrl"
                      controls
                      style="max-width: 300px; max-height: 200px; margin-top: 10px"
                    />
                  </template>
                  <template v-else>
                    <!-- ✅ 使用 videoTempUrl 作为视频源 -->
                    <video
                      v-if="ossVideoUrlPreviewUrl"
                      :src="ossVideoUrlPreviewUrl"
                      controls
                      style="max-width: 300px; max-height: 200px; margin-top: 10px"
                      @error="handleVideoError"
                    />
                    <div v-else style="margin-top: 10px; color: #999">暂无视频</div>
                    <el-button
                      v-if="ossVideoUrlPreviewUrl || form.ossVideoUrl"
                      type="danger"
                      size="small"
                      icon="Delete"
                      @click="handleOssVideoUrlRemove"
                      style="margin-top: 10px"
                      >删除视频</el-button
                    >
                  </template>
                </div>
                <!-- ✅ 数据状态显示 -->
                <div v-if="dataStatus" style="margin-top: 10px">
                  <span :class="['status-badge', dataStatus === '正常' ? 'status-normal' : 'status-abnormal']">
                    {{ dataStatus || '异常' }}
                  </span>
                  <el-button v-if="dataStatus === '异常'" type="primary" size="small" @click="handleMatchFromBackup" style="margin-left: 10px"
                    >异步获取</el-button
                  >
                </div>
              </template>
            </el-upload>
          </div>
        </el-form-item>
        <el-form-item label="观看数">
          <el-input v-model="form.videoSeeCount" placeholder="请输入观看数" />
        </el-form-item>
        <el-form-item label="所需视频点" prop="requiredPoints">
          <el-input v-model="form.requiredPoints" placeholder="请输入所需视频点" />
        </el-form-item>
        <el-form-item label="试看时长 (秒)" prop="previewDurationSeconds">
          <div>
            <el-input v-model="form.previewDurationSeconds" placeholder="请输入试看时长 (秒)" style="width: 100%" />
            <div style="margin-top: 4px; font-size: 12px; color: #999">温馨提示：输入 -1 表示免费观看</div>
          </div>
        </el-form-item>
        <el-form-item label="订阅时效（天）" prop="subscriptionValidHours">
          <el-input v-model="form.subscriptionValidHours" placeholder="请输入订阅时效（天）" />
        </el-form-item>
        <el-form-item label="所属标签" prop="categoryTagId">
          <el-select v-model="form.categoryTagId" placeholder="请选择所属标签" filterable clearable style="width: 100%">
            <el-option v-for="item in serviceTabOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="form.status" placeholder="请选择状态">
            <el-option label="上架" value="up" />
            <el-option label="下架" value="down" />
          </el-select>
        </el-form-item>
        <el-form-item label="视频时长(秒)" prop="durationSeconds">
          <el-input v-model="form.durationSeconds" placeholder="视频时长（秒）- 由系统自动获取" readonly />
          <div style="margin-top: 4px; font-size: 12px; color: #909399">视频时长由系统自动获取</div>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="VideoContent" lang="ts">
import { ref, reactive, onMounted, getCurrentInstance, type ComponentInternalInstance, onUnmounted, toRefs } from 'vue';import { ElFormInstance } from 'element-plus';
import { ElMessageBox } from 'element-plus';
import request from '@/utils/request';

import { listVideoContent, getVideoContent, delVideoContent, updateVideoContent } from '@/api/system/physical/videoContent';
import type { VideoContentVO, VideoContentForm, VideoContentQuery } from '@/api/system/physical/videoContent/types';
import { selectEnabledTabsByCategoryList } from '@/api/system/physical/serviceTab';
import type { ServiceTabVO } from '@/api/system/physical/serviceTab/types';
import { uploadTournament } from '@/api/system/business/tournaments';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

// ============ 状态管理 ============
const videoContentList = ref<VideoContentVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const isFixing = ref(false);

// ✅ 轮询相关状态
const pollTimer = ref<number | null>(null);
const pollCount = ref(0);
const dataStatus = ref(''); // 数据状态：正常/异常

const queryFormRef = ref<ElFormInstance>();
const videoContentFormRef = ref<ElFormInstance>();

const dialog = reactive<DialogOption>({ visible: false, title: '' });

const initFormData: VideoContentForm = {
  id: undefined,
  videoFileName: undefined,
  title: undefined,
  requiredPoints: undefined,
  durationSeconds: undefined,
  previewDurationSeconds: undefined,
  subscriptionValidHours: undefined,
  ossVideoUrl: undefined,
  status: 'up',
  createdAt: undefined,
  updatedAt: undefined,
  ossId: undefined,
  videoCoverUrl: undefined,
  videoSeeCount: undefined,
  categoryTagId: undefined,
  serviceTagName: undefined
};

const data = reactive<PageData<VideoContentForm, VideoContentQuery>>({
  form: { ...initFormData },
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    title: undefined,
    requiredPoints: undefined,
    durationSeconds: undefined,
    previewDurationSeconds: undefined,
    subscriptionValidHours: undefined,
    status: undefined,
    createdAt: undefined,
    updatedAt: undefined,
    ossId: undefined,
    orderBy: 'createdAt',
    orderDirection: 'desc',
    params: {}
  },
  rules: {
    title: [{ required: true, message: '视频标题不能为空', trigger: 'blur' }],
    requiredPoints: [{ required: true, message: '观看完整视频所需消耗的视频点数不能为空', trigger: 'blur' }],
    previewDurationSeconds: [{ required: true, message: '免费试看时长，单位：秒不能为空', trigger: 'blur' }],
    subscriptionValidHours: [{ required: true, message: '订阅后可观看的有效期，单位：小时不能为空', trigger: 'blur' }],
    videoCoverUrl: [{ required: true, message: '视频封面不能为空', trigger: 'blur' }],
    status: [{ required: true, message: '视频状态：up=已上架不能为空', trigger: 'change' }],
    categoryTagId: [{ required: true, message: '不能为空', trigger: 'blur' }],
    durationSeconds: []
  }
});

const { queryParams, form, rules } = toRefs(data);

// 上传状态
const uploading = ref(false);
const uploadProgress = ref(0);
const coverUploading = ref(false);
const coverUploadProgress = ref(0);

// 文件列表
const ossVideoUrlFileList = ref<any[]>([]);
const ossVideoUrlPreviewUrl = ref('');
const videoCoverUrlFileList = ref<any[]>([]);
const videoCoverUrlPreviewUrl = ref('');

// 页签选项
const serviceTabOptions = ref<ServiceTabVO[]>([]);

// ============ 工具函数 ============
const isDurationValid = (duration?: number): boolean => {
  return duration !== undefined && duration !== null && duration >= 0;
};

const isVideoDataValid = (row: VideoContentVO): boolean => {
  const hasValidOssId = row.ossId && Number(row.ossId) > 0;
  const hasValidUrl = row.ossVideoUrl && String(row.ossVideoUrl).startsWith('http');
  const hasValidDuration = isDurationValid(row.durationSeconds);
  return hasValidOssId && hasValidUrl && hasValidDuration;
};
// ============ 轮询功能 ============
// ✅ 启动轮询
const startPolling = (videoId: number | string) => {
  stopPolling(); // 先停止之前的轮询
  pollCount.value = 0;

  pollTimer.value = window.setInterval(async () => {
    await pollVideoStatus(videoId);
  }, 1000); // 每秒查询一次
};

// ✅ 停止轮询
const stopPolling = () => {
  if (pollTimer.value) {
    clearInterval(pollTimer.value);
    pollTimer.value = null;
  }
};

// ✅ 轮询查询状态 - 只更新时长和状态，不更新视频URL！
const pollVideoStatus = async (videoId: number | string) => {
  pollCount.value++;

  try {
    const res = await request({
      url: `/physical/videoContent/status/${videoId}`,
      method: 'GET'
    });

    if (res.data && res.data.data) {
      const statusData = res.data.data;

      // ✅ 更新时长
      if (statusData.durationSeconds !== undefined && statusData.durationSeconds !== null) {
        form.value.durationSeconds = statusData.durationSeconds;
      }

      // ✅ 更新数据状态
      if (statusData.dataStatus !== undefined) {
        dataStatus.value = statusData.dataStatus;
      }

      // ⚠️ 不要更新视频URL！只有异步获取时才更新

      // 数据正常或超过30秒停止轮询
      if (statusData.dataStatus === '正常' || pollCount.value >= 30) {
        stopPolling();
        await getList(); // 刷新列表
      }
    }
  } catch (error) {
    console.error('轮询查询状态失败:', error);
    // 如果轮询失败超过30次也停止
    if (pollCount.value >= 30) {
      stopPolling();
    }
  }
};

// ============ 数据查询 ============
const getList = async () => {
  loading.value = true;
  const res = await listVideoContent(queryParams.value);
  videoContentList.value = res.rows;
  total.value = res.total;
  loading.value = false;
};

const handleQuery = () => {
  queryParams.value.pageNum = 1;
  getList();
};

const resetQuery = () => {
  queryFormRef.value?.resetFields();
  queryParams.value.status = undefined;
  handleQuery();
};

const handleSelectionChange = (selection: VideoContentVO[]) => {
  ids.value = selection.map((item) => item.id);
  single.value = selection.length !== 1;
  multiple.value = !selection.length;
};

// ============ 表单操作 ============
const reset = () => {
  stopPolling(); // ✅ 重置时停止轮询
  dataStatus.value = ''; // 重置数据状态
  form.value = { ...initFormData };
  videoContentFormRef.value?.resetFields();
  ossVideoUrlFileList.value = [];
  ossVideoUrlPreviewUrl.value = '';
  videoCoverUrlFileList.value = [];
  videoCoverUrlPreviewUrl.value = '';
  uploading.value = false;
  uploadProgress.value = 0;
  coverUploading.value = false;
  coverUploadProgress.value = 0;
};

const cancel = () => {
  reset();
  dialog.visible = false;
};

const handleAdd = () => {
  reset();
  dialog.visible = true;
  dialog.title = '添加';
};

const handleUpdate = async (row?: VideoContentVO) => {
  reset();
  const _id = row?.id || ids.value[0];
  const res = await getVideoContent(_id);
  Object.assign(form.value, res.data);
  ossVideoUrlPreviewUrl.value = String(res.data?.ossVideoUrl || '');

  if (res.data.videoCoverUrl) {
    videoCoverUrlFileList.value = [{ name: '已上传封面图', url: res.data.videoCoverUrl, status: 'success' }];
    videoCoverUrlPreviewUrl.value = res.data.videoCoverUrl;
  }

  dialog.visible = true;
  dialog.title = '修改';
};

const submitForm = () => {
  if (!form.value.ossVideoUrl && ossVideoUrlPreviewUrl.value) {
    form.value.ossVideoUrl = ossVideoUrlPreviewUrl.value;
  }

  if (!form.value.ossVideoUrl) {
    proxy?.$modal.msgError('请先上传视频文件');
    return;
  }

  videoContentFormRef.value?.validate(async (valid) => {
    if (valid) {
      buttonLoading.value = true;
      try {
        if (form.value.id) {
          await updateVideoContent(form.value);
        }
        proxy?.$modal.msgSuccess('操作成功');
        dialog.visible = false;
        await getList();
      } finally {
        buttonLoading.value = false;
      }
    } else {
      proxy?.$modal.msgWarning('请检查并填写所有必填字段');
      setTimeout(() => {
        const errorField = document.querySelector('.el-form-item__error');
        if (errorField) {
          errorField.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }
      }, 100);
    }
  });
};

const handleDelete = async (row?: VideoContentVO) => {
  const _ids = row?.id || ids.value;

  if (!_ids || (Array.isArray(_ids) && _ids.length === 0)) {
    proxy?.$modal.msgError('请先选择要删除的数据');
    return;
  }

  await proxy?.$modal.confirm(`是否确认删除视频内容信息编号为"${_ids}"的数据项？`).finally(() => (loading.value = false));

  try {
    await delVideoContent(_ids);
    proxy?.$modal.msgSuccess('删除成功');
    await getList();
  } catch (error: any) {
    console.error('删除失败:', error);
    proxy?.$modal.msgError('删除失败：' + (error.message || '未知错误'));
    await getList();
  }
};

// ✅ 编辑页面内的异步获取按钮 - 核心原则2：异步获取成功时设置视频URL
const handleMatchFromBackup = async () => {
  if (!form.value.id) {
    proxy?.$modal.msgError('请先选择视频');
    return;
  }

  try {
    await proxy?.$modal.confirm(`确认对视频「${form.value.title}」执行异步获取？`);

    const res = await request({
      url: `/physical/videoContent/matchFromBackup/${form.value.id}`,
      method: 'POST'
    });

    if (res.data && res.data.success) {
      // ✅ 核心原则2：只有异步获取成功时才能更新视频URL
      if (res.data.tempUrl) {
        ossVideoUrlPreviewUrl.value = res.data.tempUrl;
      }
      if (res.data.duration) {
        form.value.durationSeconds = res.data.duration;
      }
      dataStatus.value = '正常';

      proxy?.$modal.msgSuccess('异步获取成功！已更新视频URL和时长');
      await getList();
    } else {
      proxy?.$modal.msgWarning(res.data?.message || '未找到可异步获取的数据');
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('异步获取失败:', error);
      proxy?.$modal.msgError('异步获取失败：' + (error.message || '未知错误'));
    }
  }
};

// 表格操作栏的异步获取
const matchFromBackup = async (row: VideoContentVO) => {
  try {
    await proxy?.$modal.confirm(`确认对视频「${row.title}」执行异步获取？`);

    proxy?.$modal.msgSuccess(`正在执行异步获取...`);

    const res = await request({
      url: `/physical/videoContent/matchFromBackup/${row.id}`,
      method: 'POST'
    });

    if (res.data && res.data.success) {
      proxy?.$modal.msgSuccess('异步获取成功！已更新视频URL和时长');
      await getList();
    } else {
      proxy?.$modal.msgWarning(res.data?.message || '未找到可异步获取的数据');
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('异步获取失败:', error);
      proxy?.$modal.msgError('异步获取失败：' + (error.message || '未知错误'));
    }
  }
};

const handleFixAll = async () => {
  try {
    await proxy?.$modal.confirm('确定要批量修复所有缺失URL、时长或oss_id的视频数据吗？');

    isFixing.value = true;

    const res = await request({
      url: '/physical/videoContent/fixAllVideoData',
      method: 'POST'
    });

    if (res.data && res.data.success) {
      const data = res.data;
      proxy?.$modal.msgSuccess({
        message: data.message || `批量修复任务已启动！共处理 ${data.count || 0} 条数据`,
        duration: 5000
      });

      setTimeout(() => {
        getList();
      }, 1500);
    } else {
      proxy?.$modal.msgWarning(res.data?.message || '没有需要修复的数据');
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('批量修复失败:', error);
      proxy?.$modal.msgError('批量修复失败：' + (error.message || '未知错误'));
    }
  } finally {
    isFixing.value = false;
  }
};
// ============ 文件上传 ============
const handleOssVideoUrlChange = async (file: any) => {
  ossVideoUrlPreviewUrl.value = '';
  dataStatus.value = ''; // 重置数据状态
  const fileObj = file.raw || file;

  if (!fileObj) return;

  const fileSizeMB = fileObj.size / (1024 * 1024);
  if (fileSizeMB > 2048) {
    proxy?.$modal.msgError('视频文件大小不能超过2GB');
    return;
  }

  form.value.ossId = undefined;
  form.value.durationSeconds = undefined;

  uploading.value = true;
  uploadProgress.value = 0;
  const localPreviewUrl = URL.createObjectURL(fileObj);

  try {
    const formData = new FormData();
    formData.append('file', fileObj);

    if (form.value.title) formData.append('title', form.value.title);
    if (form.value.requiredPoints) formData.append('requiredPoints', String(form.value.requiredPoints));
    if (form.value.previewDurationSeconds) formData.append('previewDurationSeconds', String(form.value.previewDurationSeconds));
    if (form.value.subscriptionValidHours) formData.append('subscriptionValidHours', String(form.value.subscriptionValidHours));
    if (form.value.videoCoverUrl) formData.append('videoCoverUrl', form.value.videoCoverUrl);
    if (form.value.status) formData.append('status', form.value.status);
    if (form.value.categoryTagId) formData.append('categoryTagId', String(form.value.categoryTagId));
    if (form.value.videoSeeCount) formData.append('videoSeeCount', String(form.value.videoSeeCount));
    if (form.value.id) formData.append('videoId', String(form.value.id));

    const timeout = Math.max(300000, Math.floor(fileSizeMB * 3000));

    const uploadRes = await request({
      url: '/physical/videoContent/uploadVideo',
      method: 'POST',
      data: formData,
      headers: { 'Content-Type': 'multipart/form-data' },
      timeout,
      onUploadProgress: (progressEvent: any) => {
        if (progressEvent.total > 0) {
          uploadProgress.value = Math.round((progressEvent.loaded / progressEvent.total) * 100);
          if (uploadProgress.value >= 100) {
            ossVideoUrlPreviewUrl.value = localPreviewUrl;
          }
        }
      }
    });

    uploading.value = false;

    // ⚠️ 根据核心原则：上传成功后不设置视频URL！
    // 视频URL只在两个地方设置：1. 修改页面打开时 2. 异步获取成功时
    const videoUrl = uploadRes.data?.data?.url || uploadRes.data?.data?.ossVideoUrl;
    const ossId = uploadRes.data?.data?.ossId;
    const duration = uploadRes.data?.data?.duration || uploadRes.data?.data?.videoDuration;
    const videoFileName = uploadRes.data?.data?.videoFileName;
    const serviceTagName = uploadRes.data?.data?.serviceTagName;

    // ❌ 删除：不设置视频URL
    // form.value.ossVideoUrl = videoUrl || localPreviewUrl;
    // ossVideoUrlPreviewUrl.value = videoTempUrl;

    if (ossId) form.value.ossId = ossId;
    if (videoFileName) {
      form.value.videoFileName = videoFileName;
    } else if (fileObj?.name) {
      form.value.videoFileName = fileObj.name;
    }
    if (serviceTagName) {
      form.value.serviceTagName = serviceTagName;
    }

    if (uploadRes.data?.data?.id) {
      form.value.id = uploadRes.data.data.id;

      // ✅ 上传成功后启动轮询（轮询只更新时长和状态，不更新视频URL）
      startPolling(uploadRes.data.data.id);
    }

    let finalDuration = duration && !isNaN(duration) && Number(duration) > 0 ? Math.floor(Number(duration)) : 0;

    if (!isDurationValid(finalDuration) && uploadRes.data?.data?.id) {
      try {
        const durationRes = await request({
          url: `/physical/videoContent/getVideoDuration/${uploadRes.data.data.id}`,
          method: 'GET'
        });
        if (durationRes.data && durationRes.data.success && durationRes.data.duration > 0) {
          finalDuration = durationRes.data.duration;
        }
      } catch (durationError) {
        console.error('调用获取时长接口失败:', durationError);
      }
    }

    if (finalDuration > 0) {
      form.value.durationSeconds = finalDuration;
    }

    proxy?.$modal.msgSuccess('视频上传成功！时长已自动获取');
    await getList();
  } catch (error: any) {
    console.error('视频上传失败:', error);
    uploading.value = false;
    uploadProgress.value = 0;
    ossVideoUrlPreviewUrl.value = localPreviewUrl;
    URL.revokeObjectURL(localPreviewUrl);

    proxy?.$modal.msgError(
      error.code === 'ECONNABORTED' ? '视频上传超时，请尝试上传更小的文件或联系管理员' : '视频上传失败：' + (error.message || '未知错误')
    );

    form.value.ossVideoUrl = '';
    form.value.ossId = undefined;
    form.value.durationSeconds = undefined;
    form.value.id = undefined;
  }
};

const handleOssVideoUrlRemove = async () => {
  if (!form.value.ossVideoUrl && !ossVideoUrlPreviewUrl.value) {
    ossVideoUrlFileList.value = [];
    ossVideoUrlPreviewUrl.value = '';
    form.value.ossVideoUrl = '';
    form.value.ossId = undefined;
    form.value.durationSeconds = undefined;
    return;
  }

  try {
    await proxy?.$modal.confirm('确定要删除当前视频吗？删除后需要重新上传。');

    ossVideoUrlFileList.value = [];
    ossVideoUrlPreviewUrl.value = '';
    form.value.ossVideoUrl = '';
    form.value.ossId = undefined;
    form.value.durationSeconds = undefined;
    form.value.videoFileName = undefined;
    dataStatus.value = ''; // 重置数据状态

    if (form.value.id) {
      try {
        await request({
          url: `/physical/videoContent/clearVideo/${form.value.id}`,
          method: 'POST'
        });
        proxy?.$modal.msgSuccess('视频删除成功');
        await getList();
      } catch (error) {
        console.error('删除视频失败:', error);
      }
    } else {
      proxy?.$modal.msgSuccess('视频已从表单中移除');
    }
  } catch (error) {
    // 用户取消删除
  }
};

const handleVideoCoverUrlChange = async (file: any) => {
  videoCoverUrlFileList.value = [];

  if (file.raw) {
    videoCoverUrlPreviewUrl.value = URL.createObjectURL(file.raw);
  }

  videoCoverUrlFileList.value.push(file);
  coverUploading.value = true;

  try {
    const res = await uploadTournament(file.raw);
    if (res.code === 200) {
      videoCoverUrlFileList.value[0] = { ...file, status: 'success', response: res.data.url };
      form.value.videoCoverUrl = res.data.url;
      videoCoverUrlPreviewUrl.value = res.data.url;
      proxy?.$modal.msgSuccess('封面图上传成功');
    } else {
      throw new Error(res.msg);
    }
  } catch (error) {
    videoCoverUrlFileList.value[0] = { ...file, status: 'fail', error: '上传失败' };
    proxy?.$modal.msgError('封面图上传失败，请重试');
  } finally {
    coverUploading.value = false;
  }
};

const handleVideoCoverUrlRemove = () => {
  videoCoverUrlFileList.value = [];
  videoCoverUrlPreviewUrl.value = '';
  form.value.videoCoverUrl = '';
};

const handleVideoCoverUrlPreviewClick = () => {
  const imageUrl = videoCoverUrlPreviewUrl.value || form.value.videoCoverUrl;
  if (imageUrl) {
    ElMessageBox.alert(`<img src="${imageUrl}" style="max-width: 100%;" />`, '视频封面图预览', {
      dangerouslyUseHTMLString: true,
      confirmButtonText: '关闭'
    });
  }
};

// ✅ 视频错误处理
const handleVideoError = () => {
  console.error('视频加载失败');
};

// ============ 初始化和清理 ============
onMounted(() => {
  getList();
  loadServiceTabOptions();
});

onUnmounted(() => {
  stopPolling(); // ✅ 组件卸载时停止轮询
});

const loadServiceTabOptions = async () => {
  try {
    const res = await selectEnabledTabsByCategoryList('video');
    serviceTabOptions.value = Array.isArray(res.data) ? res.data : Array.isArray(res) ? res : [];
  } catch (error) {
    console.error('加载页签列表失败:', error);
    proxy?.$modal.msgError('加载页签列表失败');
  }
};
</script>

<style scoped>
.file-name-ellipsis {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

/* ✅ 数据状态样式 */
.status-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
}

.status-normal {
  background-color: #f0f9eb;
  color: #67c23a;
}

.status-abnormal {
  background-color: #fef0f0;
  color: #f56c6c;
}
</style>
