<template>
  <!-- 添加或修改视频抽屉 -->
  <el-drawer v-model="visibleProxy" :title="title" size="70%" append-to-body :close-on-click-modal="false" @closed="resetForm">
    <el-card shadow="always" class="box-card" style="padding-top: 10px">
      <el-form ref="videoFormRef" :model="form" :rules="rules" label-width="100px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="渠道" prop="branchType">
              <i-select v-model="form.branchType" dict-type="branchtype" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单" prop="menuId">
              <el-tree-select
                v-model="form.menuId"
                :data="menuOptions"
                :props="{ value: 'menuId', label: 'menuName', children: 'children' }"
                value-key="menuId"
                placeholder="选择菜单"
                check-strictly
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="时长" prop="duration">
              <el-input v-model="form.duration" placeholder="请输入视频时长" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态" prop="state" v-if="isEdit">
              <el-select v-model="form.state" placeholder="请选择状态" disabled>
                <el-option v-for="dict in sys_upload_state" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="说明" prop="description">
          <el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入视频说明" />
        </el-form-item>

        <!-- 视频文件管理 -->
        <el-form-item label="视频文件">
          <!-- 已有文件显示 -->
          <div v-if="hasExistingFile" class="existing-file-info mb-3">
            <el-card shadow="hover" class="file-card">
              <div class="file-info-content">
                <div class="file-details">
                  <el-icon class="file-icon"><VideoPlay /></el-icon>
                  <div class="file-text">
                    <div class="file-name">{{ attachInfo.originalName || attachInfo.fileName }}</div>
                    <div class="file-meta">
                      {{ formatFileSize(attachInfo.fileSize) }} •
                      {{ attachInfo.fileSuffix?.toUpperCase() || 'VIDEO' }}
                    </div>
                  </div>
                </div>
                <div class="file-actions">
                  <el-button type="primary" link icon="Download" @click="handleDownloadVideo" :loading="downloadLoading"> 下载 </el-button>
                  <el-button type="warning" link icon="RefreshRight" @click="handleReplaceVideo" :loading="replacingFile"> 更换 </el-button>
                </div>
              </div>
            </el-card>
          </div>

          <!-- 文件上传区域 -->
          <div v-if="!hasExistingFile || showUploadArea">
            <el-upload
              ref="uploadRef"
              v-model:file-list="uploadFile"
              :auto-upload="false"
              :limit="1"
              :on-change="handleFileChange"
              :on-exceed="handleFileExceed"
              :before-remove="handleFileRemove"
              accept=".mp4, .avi, .mkv, .mov, .wmv, .flv, .webm, .mpg, .mpeg, .mts, .m2ts, .ogv"
              class="upload-area"
            >
              <el-button icon="UploadFilled" type="primary" :loading="uploadingFile">
                {{ uploadingFile ? '上传中...' : '选择视频文件' }}
              </el-button>
              <template #tip>
                <div class="el-upload__tip text-gray-500 text-sm mt-2">
                  支持 mp4、avi、mkv、mov、wmv、flv、webm、mpg、mpeg、mts、m2ts、ogv 格式，文件大小不超过1000MB
                </div>
              </template>
            </el-upload>

            <!-- 选中文件信息显示 -->
            <div v-if="uploadFile.length > 0" class="mt-3">
              <el-card shadow="hover" class="selected-file-card">
                <div class="selected-file-info">
                  <el-icon class="file-icon"><Document /></el-icon>
                  <div class="file-details">
                    <div class="file-name">{{ uploadFile[0].name }}</div>
                    <div class="file-size">{{ formatFileSize(uploadFile[0].size || 0) }}</div>
                  </div>
                  <el-button type="primary" @click="uploadVideoFile" :loading="uploadingFile" :disabled="!form.id">
                    {{ uploadingFile ? '上传中...' : '上传文件' }}
                  </el-button>
                </div>
              </el-card>
              <div v-if="!form.id" class="mt-2 text-sm text-orange-500">
                <el-icon><Warning /></el-icon> 请先保存视频基本信息
              </div>
            </div>
          </div>
        </el-form-item>

        <!-- 视频预览区域 -->
        <el-form-item label="视频预览" v-if="previewUrl || currentVideoUrl">
          <div class="video-preview">
            <video
              ref="previewVideoRef"
              :src="previewUrl || currentVideoUrl"
              width="400"
              height="240"
              controls
              preload="metadata"
              @loadedmetadata="onVideoLoaded"
              @error="onVideoError"
            >
              您的浏览器不支持视频播放
            </video>
            <div class="video-info mt-2" v-if="videoInfo.duration">
              <el-tag type="info" size="small"> 时长: {{ formatDuration(videoInfo.duration) }} </el-tag>
              <el-tag type="info" size="small" class="ml-2"> 尺寸: {{ videoInfo.width }}x{{ videoInfo.height }} </el-tag>
            </div>
          </div>
        </el-form-item>
      </el-form>
    </el-card>

    <template #footer>
      <div class="dialog-footer">
        <el-button v-if="!isEdit && !form.id" :loading="buttonLoading" type="primary" @click="saveBasicInfo"> 保存基本信息 </el-button>
        <el-button v-if="isEdit && form.id" :loading="buttonLoading" type="primary" @click="updateBasicInfo"> 更新 </el-button>
        <el-button @click="cancel">取消</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { addVideoInfo, updateVideoInfo, queryVideoUrl } from '@/api/system/video';
import { UserVideoPlayForm, UserVideoPlayVO } from '@/api/system/video/types';
import { delAttachments, sysUploadFile } from '@/api/common/syscommon';
// import { AttachBusCodeConstant } from '@/enums/AttachBusCodeConstant';
import { UploadUserFile } from 'element-plus';
import { Document, VideoPlay, Warning } from '@element-plus/icons-vue';
import ISelect from '@/views/modules/common/ISelect.vue';
import { secureRandom } from '@/utils/ruoyi';

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  editType: {
    type: String,
    default: 'add'
  },
  rowData: {
    type: Object as PropType<UserVideoPlayVO | null>,
    default: null
  },
  menuOptions: {
    type: Array,
    default: () => []
  }
});

const emit = defineEmits(['update:visible', 'save']);

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { sys_upload_state } = toRefs<any>(proxy?.useDict('sys_upload_state'));

// 可见性的双向绑定
const visibleProxy = computed({
  get: () => props.visible,
  set: (val) => emit('update:visible', val)
});

// 根据编辑类型决定标题
const title = computed(() => (props.editType === 'add' ? '上传视频' : '修改视频'));
const isEdit = computed(() => props.editType === 'edit');

// 状态变量
const buttonLoading = ref(false);
const uploadingFile = ref(false);
const downloadLoading = ref(false);
const replacingFile = ref(false);
const showUploadArea = ref(false);

// 表单ref
const videoFormRef = ref<ElFormInstance>();
const uploadRef = ref<ElUploadInstance>();
const previewVideoRef = ref<HTMLVideoElement>();

// 上传文件
const uploadFile = ref<UploadUserFile[]>([]);

// 视频预览相关
const previewUrl = ref('');
const currentVideoUrl = ref('');
const videoInfo = reactive({
  duration: 0,
  width: 0,
  height: 0
});

// 附件信息
const attachInfo = reactive({
  attId: '',
  fileName: '',
  originalName: '',
  fileSuffix: '',
  fileSize: 0,
  url: '',
  service: ''
});

// 是否有现有文件
const hasExistingFile = computed(() => {
  return attachInfo.attId && attachInfo.fileName && !showUploadArea.value;
});

// 初始化表单数据
const initFormData: UserVideoPlayForm & { state?: string; id?: string } = {
  branchType: '2',
  menuId: undefined,
  duration: undefined,
  description: undefined,
  state: '0',
  id: undefined,
  attId: undefined
};

// 表单数据
const form = ref({ ...initFormData });

// 表单校验规则
const rules = computed(() => {
  const baseRules = {
    branchType: [{ required: true, message: '请选择渠道', trigger: 'change' }],
    menuId: [{ required: true, message: '请选择菜单', trigger: 'change' }],
    description: [{ required: true, message: '请输入视频说明', trigger: 'blur' }]
  };

  return baseRules;
});

// 格式化文件大小
const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

/** 处理文件选择 */
const handleFileChange = (file: UploadUserFile) => {
  uploadFile.value = [file];

  // 创建预览URL
  if (file.raw) {
    // 清除之前的预览URL
    if (previewUrl.value) {
      URL.revokeObjectURL(previewUrl.value);
    }
    previewUrl.value = URL.createObjectURL(file.raw);
  }
};

/** 处理文件数量超出 */
const handleFileExceed = () => {
  proxy?.$modal.msgWarning('只能上传一个视频文件');
};

/** 处理文件移除 */
const handleFileRemove = () => {
  if (previewUrl.value) {
    URL.revokeObjectURL(previewUrl.value);
    previewUrl.value = '';
  }
  return true;
};

/** 上传视频文件 */
const uploadVideoFile = async () => {
  if (!form.value.id) {
    proxy?.$modal.msgWarning('请先保存视频基本信息');
    return;
  }
  let fileItem: UploadUserFile | undefined = undefined;
  if (uploadFile.value.length === 0) {
    proxy?.$modal.msgError('请选择视频文件');
    return;
  }
  fileItem = uploadFile.value[0];
  if (fileItem.size != undefined) {
    const isLimtfile = fileItem.size / 1024 / 1024 < 1000;
    if (!isLimtfile) {
      proxy?.$modal.msgError('文件大小不能超过1000MB!');
      return;
    }
  }
  uploadingFile.value = true;
  try {
    // 如果存在旧附件，先删除它
    if (form.value.attId) {
      // try {
      //   await delAttachments(form.value.attId, AttachBusCodeConstant.VIDEO_FILE_UPLOAD.code);
      //   // 删除成功后清空attId，标记为新增状态
      //   form.value.attId = undefined;
      // } catch (error) {
      //   // 删除失败时，仍然尝试上传新文件，但保持更新状态
      //   proxy?.$modal.msgWarning('删除旧附件失败，将尝试替换现有文件');
      // }
    }

    // 使用通用附件上传API
    const file = uploadFile.value[0].raw!;
    const formData = new FormData();
    formData.append('files', file);
    formData.append('busDataType', 'VIDEO_FILE');
    formData.append('uid', `video_${Date.now()}_${secureRandom().toString(36).substr(2, 9)}`); // 确保唯一性

    // 修复上传参数逻辑
    const isUpdate = !!form.value.attId;
    formData.append('markedUpdate', isUpdate ? 'true' : 'false');
    formData.append('markedAdd', isUpdate ? 'false' : 'true');
    // formData.append('busCode', AttachBusCodeConstant.VIDEO_FILE_UPLOAD.code);
    // formData.append('dataId', form.value.id?.toString() || '0');

    const res = await sysUploadFile(formData);

    if (res.code === 200 && res.data && res.data.length > 0) {
      const fileInfo = res.data[0];

      // 更新表单状态
      form.value.state = '1'; // 上传成功
      form.value.attId = fileInfo.attId || fileInfo.id; // 保存新的附件ID

      // 更新附件信息显示
      Object.assign(attachInfo, {
        attId: fileInfo.attId || fileInfo.id,
        fileName: fileInfo.fileName || '',
        originalName: fileInfo.originalName || '',
        fileSuffix: fileInfo.fileSuffix || '',
        fileSize: fileInfo.fileSize || 0,
        url: fileInfo.url || '',
        service: fileInfo.service || ''
      });

      // 更新数据库中的状态和附件ID
      await updateVideoInfo({
        ...form.value,
        attId: form.value.attId
      });

      // 清空上传文件列表
      uploadFile.value = [];
      uploadRef.value?.clearFiles();
      showUploadArea.value = false;

      proxy?.$modal.msgSuccess('视频上传成功');
      emit('save');

      // 上传成功后关闭抽屉
      setTimeout(() => {
        visibleProxy.value = false;
      }, 1000);
    } else {
      throw new Error('上传返回数据异常');
    }
  } catch (error) {
    form.value.state = '2'; // 上传失败
    await updateVideoInfo(form.value);
    proxy?.$modal.msgError('上传视频文件失败：' + (error as Error).message);
  } finally {
    uploadingFile.value = false;
  }
};

/** 下载视频文件 */
const handleDownloadVideo = async () => {
  if (!form.value.id) {
    proxy?.$modal.msgWarning('没有可下载的文件');
    return;
  }

  try {
    downloadLoading.value = true;

    // 通过视频ID和业务编码获取附件信息进行下载
    // 这里可能需要先查询附件ID，或者后端提供专门的视频下载接口
    proxy?.$modal.msgWarning('下载功能需要后端提供专门的视频下载接口');
  } catch (error) {
    proxy?.$modal.msgError('下载失败');
  } finally {
    downloadLoading.value = false;
  }
};

/** 更换视频文件 */
const handleReplaceVideo = async () => {
  try {
    replacingFile.value = true;

    // 显示上传区域
    showUploadArea.value = true;

    // 清空当前选择的文件
    uploadFile.value = [];
    uploadRef.value?.clearFiles();

    proxy?.$modal.msgSuccess('请选择新的视频文件进行替换');
  } catch (error) {
    proxy?.$modal.msgError('更换文件失败');
  } finally {
    replacingFile.value = false;
  }
};

/** 保存基本信息 */
const saveBasicInfo = async () => {
  const valid = await videoFormRef.value?.validate();
  if (!valid) return;
  buttonLoading.value = true;
  try {
    const res = await addVideoInfo(form.value);
    if (res.data?.videoId) {
      form.value.id = res.data.videoId;
      proxy?.$modal.msgSuccess('基本信息保存成功，请上传视频文件');

      // 如果是新增模式且没有选择文件，则刷新列表
      if (!uploadFile.value.length) {
        emit('save');
      }
    } else {
      throw new Error('保存返回数据异常');
    }
  } catch (error) {
    proxy?.$modal.msgError('保存基本信息失败：' + (error as Error).message);
  } finally {
    buttonLoading.value = false;
  }
};

/** 更新基本信息 */
const updateBasicInfo = async () => {
  const valid = await videoFormRef.value?.validate();
  if (!valid) return;

  buttonLoading.value = true;
  try {
    await updateVideoInfo({
      ...form.value,
      attId: form.value.attId
    });
    proxy?.$modal.msgSuccess('更新成功');
    emit('save');
    visibleProxy.value = false;
  } catch (error) {
    proxy?.$modal.msgError('更新失败');
  } finally {
    buttonLoading.value = false;
  }
};

/** 视频加载完成 */
const onVideoLoaded = () => {
  const video = previewVideoRef.value;
  if (video) {
    videoInfo.duration = video.duration;
    videoInfo.width = video.videoWidth;
    videoInfo.height = video.videoHeight;

    // 自动设置时长（如果用户没有手动输入）
    if (!form.value.duration && videoInfo.duration) {
      form.value.duration = formatDuration(videoInfo.duration);
    }
  }
};

/** 视频加载错误 */
const onVideoError = () => {
  proxy?.$modal.msgError('视频加载失败，请检查文件格式');
};

/** 格式化时长 */
const formatDuration = (seconds: number): string => {
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const secs = Math.floor(seconds % 60);

  if (hours > 0) {
    return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
  } else {
    return `${minutes}:${secs.toString().padStart(2, '0')}`;
  }
};

/** 获取当前视频URL */
const getCurrentVideoUrl = async () => {
  if (form.value.id) {
    try {
      const res = await queryVideoUrl({ id: form.value.id } as UserVideoPlayVO);
      currentVideoUrl.value = res.msg;
    } catch (error) {
    }
  }
};

/** 取消按钮 */
const cancel = () => {
  visibleProxy.value = false;
};

/** 表单重置 */
const resetForm = () => {
  form.value = { ...initFormData };
  uploadFile.value = [];
  videoFormRef.value?.resetFields();
  uploadRef.value?.clearFiles();
  showUploadArea.value = false;

  // 清除预览相关
  if (previewUrl.value) {
    URL.revokeObjectURL(previewUrl.value);
    previewUrl.value = '';
  }
  currentVideoUrl.value = '';
  Object.assign(videoInfo, { duration: 0, width: 0, height: 0 });

  // 重置附件信息
  Object.assign(attachInfo, {
    attId: '',
    fileName: '',
    originalName: '',
    fileSuffix: '',
    fileSize: 0,
    url: '',
    service: ''
  });
};

// 监听抽屉可见性、编辑类型和行数据变化
watch(
  [() => props.visible, () => props.editType, () => props.rowData],
  async ([visible, type, data]) => {
    if (visible) {
      resetForm();

      if (type === 'edit' && data) {
        // 修改操作 - 填充表单数据
        Object.assign(form.value, {
          id: data.id,
          branchType: data.branchType,
          menuId: data.menuId,
          duration: data.duration,
          description: data.description,
          state: data.state,
          attId: data.attId // 确保attId被正确设置
        });
        // 获取视频URL用于预览
        await getCurrentVideoUrl();
      } else {
        // 新增模式，确保attId为空
        form.value.attId = undefined;
      }
    }
  },
  { immediate: true }
);

// 组件卸载时清理URL对象
onBeforeUnmount(() => {
  if (previewUrl.value) {
    URL.revokeObjectURL(previewUrl.value);
  }
});
</script>

<style scoped>
.existing-file-info {
  margin-bottom: 16px;
}

.file-card {
  border: 1px solid #e4e7ed;
  border-radius: 8px;
}

.file-info-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
}

.file-details {
  display: flex;
  align-items: center;
  flex: 1;
}

.file-icon {
  font-size: 24px;
  color: #409eff;
  margin-right: 12px;
}

.file-text {
  flex: 1;
}

.file-name {
  font-weight: 500;
  color: #303133;
  margin-bottom: 4px;
}

.file-meta {
  font-size: 12px;
  color: #909399;
}

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

.selected-file-card {
  background-color: #f0f9ff;
  border: 1px dashed #409eff;
}

.selected-file-info {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
}

.upload-area {
  width: 100%;
}

.video-preview {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 10px;
  background-color: #f5f7fa;
}

.video-info {
  display: flex;
  gap: 8px;
}

:deep(.el-tree-select) {
  width: 100%;
}

:deep(.el-upload) {
  width: 100%;
}

:deep(.el-upload__tip) {
  line-height: 1.4;
}
</style>
