<template>
    <!-- 新增编辑视频 -->
    <div class="modify-video-page-wrap">
        <t-form :data="form" :rules="rules" ref="formRules">
            <t-form-item label="所属分类" name="ClassifyId">
                <t-cascader placeholder="选择所属分类" 
                    v-model="form.ClassifyId"
                    :options="classifyList"
                    style="width: 300px;"
                    clearable
                    :keys="{
                      emitPath:false,
                      label:'ClassifyName',
                      value:'ClassifyId',
                      children:'Children'}">
                </t-cascader>
            </t-form-item>
            <t-form-item label="视频名称" name="Title">
                <t-input style="width: 300px;" v-model="form.Title" placeholder="请输入视频名称"></t-input>
            </t-form-item>
            <t-form-item label="视频简介" name="Introduce">
                <t-textarea  v-model="form.Introduce" 
                placeholder="请输入视频简介"
                maxlength="50" show-word-limit :autosize="{ minRows: 5, maxRows: 5 }"></t-textarea >
            </t-form-item>
            <t-form-item label="上传封面" name="CoverImg">
              <div style="display: block;">
                  <t-upload accept="image/*" 
                      :http-request="handleUploadImg" :show-file-list="false" :disabled="isImageUploading">
                      <t-button theme="primary" :loading="isImageUploading">点击上传</t-button>
                      <span style="color:#999999;margin-left: 5px;" @click.stop>建议尺寸比例3:2，支持png、jpg、gif、jpeg格式</span>
                  </t-upload>
                  <div class="img-box">
                      <img :src="form.CoverImg" v-if="form.CoverImg">
                      <span v-else style="color:#999999;line-height: 100px;">请上传封面图</span>
                  </div>
              </div>
            </t-form-item>
            <t-form-item label="上传视频" name="VideoUrl">
              <div style="display: block;">
                  <t-upload accept=".mp4" 
                      :request-method="handleUploadVideo" :show-file-list="false" :disabled="isVideoUploading">
                      <t-button theme="primary" :loading="isVideoUploading">点击上传</t-button>
                      <span style="color:#999999;margin-left: 5px;" @click.stop>仅支持mp4格式</span>
                  </t-upload>
                  
                  <div class="img-box">
                      <t-progress type="circle" :percentage="percentage" width="40" v-if="isVideoUploading"></t-progress>
                      <span v-if="form.VideoUrl&&!form.VideoId" class="duration">{{timeDuration}}</span>
                      <img :src="form.CoverImg" v-if="form.VideoUrl" @click="handlePreviewVideo">
                      <span v-else style="color:#999999;line-height: 100px;">请上传视频</span>
                  </div>
              </div>
                
            </t-form-item>
            <t-form-item label="视频标签" name="TagIds">
                <t-button variant="text" theme="primary" @click="isModifyDialogShow = true">选择标签</t-button>
                <div class="tag-list" :key="tagIdKey">
                    <span class="tag-item" v-for="tag in form.TagIds" :key="tag.TagId">
                        <span>{{tag.TagName}}</span>
                        <span @click.stop="removeTag(tag)"><i class="t-icon-close"></i></span>
                    </span>
                </div>
            </t-form-item>
        </t-form>
        <div class="btn-box">
            <t-button variant="outline" plain @click="changeRoute">取消</t-button>
            <t-button theme="primary" @click="modifyVideo" :loading="isImageUploading||isVideoUploading">保存</t-button>
            <t-button theme="primary" @click="publishVideo" :loading="isImageUploading||isVideoUploading">发布</t-button>
        </div>
        <!-- 选择标签弹窗 -->
        <AddTags 
            :isModifyDialogShow="isModifyDialogShow"
            :Tags="form.TagIds"
            :tagList="tagList"
            :getTagList="getTagList"
            @modify="modifyTags"
            @close="isModifyDialogShow=false"
        />
        <!-- 预览视频弹窗 -->
        <t-dialog
            :visible.sync="previewPop"
            :modal-append-to-body='false'
            width="60vw"
            :title="previewPopTitle"
            @close="endingPreview"
        >
         <video style="width: 100%;height: 100%;max-height: 70vh;outline: none;" 
         controls :src="previewVideoUrl" autoplay ref="previewVideo">
            您的浏览器暂不支持,请更换浏览器
         </video>   
        </t-dialog>
    </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import MD5 from 'js-md5';
import { VideoInterface, TagInterface, ClassifyInterface } from '@/api/modules/trainingApi';
import AddTags from './components/addTags.vue';
import _ from 'lodash';
import { useRoute, useRouter } from 'vue-router'

const router=useRouter()
const route=useRoute()
const form = ref({
  Title: '',
  Introduce: '',
  ClassifyId: '',
  TagIds: [],
  CoverImg: '',
  VideoUrl: ''
});

const rules = {
  ClassifyId: [{ required: true, message: '请选择所属分类' }],
  Title: [{ required: true, message: '请输入视频名称' }],
  CoverImg: [{ required: true, message: '请选择视频封面' }],
  VideoUrl: [{ required: true, message: '请上传视频' }],
  TagIds: [{
    required: true,
    validator: (rule, value, callback) => {
      if (!value.length) {
        return callback(new Error("请至少选择一个标签"));
      } else {
        return callback();
      }
    }
  }]
}

const tagIdKey = ref(0);
const isModifyDialogShow = ref(false);

const isImageUploading = ref(false);
const isVideoUploading = ref(false);
const percentage = ref(0);
const timeDuration = ref('');
const previewVideoUrl = ref('');
const previewPop = ref(false);
const previewPopTitle = ref('');
const tagList = ref([]);
const classifyList = ref([]);
const previewVideo = ref(null);
const formRules = ref(null);

// 定义全局变量
let ALOSSINS = null;
let ALOSSAbortCheckpoint = null;


// 获取分类列表
const getClassifyList = async (type = '') => {
  try {
    const res = await ClassifyInterface.getClassifyList({});
    if (res.Ret !== 200) return;
    classifyList.value = (res.Data && res.Data.List) || [];
    filterNodes(classifyList.value);
    classifyList.value = classifyList.value.map(item => {
      if (!item.Children) {
        item.disabled = true;
      }
      return item;
    });
  } catch (error) {
    console.error('获取分类列表失败:', error);
  }
};

// 过滤节点
const filterNodes = (arr) => {
  if (arr.length) {
    arr.forEach(item => {
      if (item.Children && item.Children.length) {
        filterNodes(item.Children);
      }
      if (item.Children && !item.Children.length) {
        delete item.Children;
      }
    });
  }
};

// 获取标签列表
const getTagList = async (keyword = '') => {
  try {
    const res = await TagInterface.getTagList({
      Keyword: keyword,
      PageSize: 1000,
      CurrentIndex: 1
    });
    if (res.Ret !== 200) return;
    tagList.value = (res.Data && res.Data.List) || [];
  } catch (error) {
    console.error('获取标签列表失败:', error);
  }
};

// 检查图片是否合法
const handleUploadImg = (file) => {
  isImageUploading.value = true;
  const { type } = file.file;
  if (!['image/png', 'image/jpeg'].includes(type)) {
    MessagePlugin.warning('仅支持png、jpg格式的图片');
    isImageUploading.value = false;
    return;
  }
  uploadImg(file);
};

// 上传图片
const uploadImg = (file) => {
  const formData = new FormData();
  formData.append('file', file.file);
  VideoInterface.bannerupload(formData).then(res => {
    isImageUploading.value = false;
    if (res.Ret !== 200) return;
    form.value.CoverImg = res.Data.ResourceUrl;
  });
};

// 检查视频是否合法，并获取视频时长
const handleUploadVideo = async (file) => {
  if (file.type !== 'video/mp4') {
    MessagePlugin.warning('上传失败，上传视频格式不正确');
    return;
  }
  const duration = await handleGetDuration(file);
  timeDuration.value = `${String(parseInt(duration / 60)).padStart(2, '0')}:${String(parseInt(duration % 60)).padStart(2, '0')}`;
  uploadVideo(file);
  isVideoUploading.value = true;
};

// 获取视频时长的Promise
const handleGetDuration = (file) => {
  console.log(file);
  
  return new Promise((resolve, reject) => {
    const fileUrl = URL.createObjectURL(file.raw);
    const audioEl = new Audio(fileUrl);
    audioEl.addEventListener('loadedmetadata', (e) => {
      const t = e.composedPath()[0].duration;
      resolve(t);
    });
  });
};

// 上传视频
const uploadVideo = async (file) => {
  const res = await VideoInterface.getOSSSign();
  if (res.Ret === 200) {
    handleUploadToOSS(file.raw, res.Data);
  }
};

// 上传到阿里云
const handleUploadToOSS = async (file, { AccessKeyId, AccessKeySecret, SecurityToken }) => {
  ALOSSINS = new OSS({
    region: 'oss-cn-shanghai',
    accessKeyId: AccessKeyId,
    accessKeySecret: AccessKeySecret,
    stsToken: SecurityToken,
    bucket: 'hzchart',
    endpoint: 'hzstatic.hzinsights.com',
    cname: true,
    timeout: 600000000000
  });

  const t = new Date().getTime().toString();
  const temName = `static/yb/video/${MD5(t)}.${file.type.split('/')[1]}`;
  const options = {
    progress: (p, cpt, res) => {
      ALOSSAbortCheckpoint = cpt;
      percentage.value = parseInt(p * 100);
    },
    parallel: 10,
    partSize: 1024 * 1024 * 10
  };

  try {
    console.log(temName, file, { ...options });
    
    const res = await ALOSSINS.multipartUpload(temName, file, { ...options });
    console.log('上传结果', res);
    if (res.res.status === 200) {
      form.value.VideoUrl = `https://hzstatic.hzinsights.com/${res.name}`;
      percentage.value = 0;
      ALOSSAbortCheckpoint = null;
      isVideoUploading.value = false;
    }
  } catch (error) {
    if (error.name !== 'cancel') {
      MessagePlugin.warning('上传失败，请刷新重试');
    }
    percentage.value = 0;
    ALOSSAbortCheckpoint = null;
    isVideoUploading.value = false;
  }
};

// 删除所选标签
const removeTag = (tag) => {
  const index = form.value.TagIds.findIndex(i => i.TagId === tag.TagId);
  if (index !== -1) {
    form.value.TagIds.splice(index, 1);
  }
  tagIdKey.value++;
};

// 改变所选标签
const modifyTags = (tags) => {
  form.value.TagIds = _.cloneDeep(tags);
  isModifyDialogShow.value = false;
};

// 获取视频信息
const getVideoDetail = () => {
  const { VideoId } = route.query;
  if (!Number(VideoId)) return;
  VideoInterface.getVideoDetail({ VideoId: Number(VideoId) }).then(res => {
    if (res.Ret !== 200) return;
    form.value = res.Data || {};
    if (form.value.Classify) {
      const classifyArr = getDataClassify(form.value.Classify);
      form.value.ClassifyId = classifyArr[classifyArr.length - 1];
      delete form.value.Classify;
    }
    if (form.value.Tags) {
      form.value.TagIds = form.value.Tags;
      delete form.value.Tags;
    }
  });
};

// 获取视频分类路径
const getDataClassify = (classify, classifyArr = []) => {
  classifyArr.push(classify.ClassifyId);
  if (classify.Children && classify.Children.length) {
    return getDataClassify(classify.Children[0], classifyArr);
  }
  return classifyArr;
};

// 添加/编辑视频
const modifyVideo = async (type = 'modify') => {
  const valid = await formRules.value.validate()
  if (valid !== true) return
  let res = null;
  const params = { ...form.value, TagIds: form.value.TagIds.map(t => t.TagId) };
  if (!form.value.VideoId) {
    res = await VideoInterface.addVideo(params);
  } else {
    res = await VideoInterface.editVideo(params);
  }
  if (res.Ret !== 200) return;
  if (type !== 'publish') {
    MessagePlugin.success(`${form.value.VideoId ? '编辑' : '添加'}成功`);
    changeRoute();
  }
  if (!form.value.VideoId) {
    form.value.VideoId = res.Data || '';
  }
};

// 发布视频
const publishVideo = async () => {
  let res = {};
  await modifyVideo('publish');
  if (form.value.VideoId) {
    res = await VideoInterface.publishVideo({ VideoId: Number(form.value.VideoId), PublishState: 1 });
    if (res.Ret !== 200) return;
    MessagePlugin.success('发布成功');
  }
  changeRoute();
};

// 改变路由
const changeRoute = () => {
  if (ALOSSAbortCheckpoint) {
    console.log('终止上传');
    ALOSSINS.abortMultipartUpload(ALOSSAbortCheckpoint.name, ALOSSAbortCheckpoint.uploadId);
  }
  router.push('/training/trainingVideo');
};

// 预览视频
const handlePreviewVideo = () => {
  if (isVideoUploading.value || !form.value.VideoUrl) return;
  previewVideo.play();
  previewPopTitle.value = form.value.Title || '暂无标题';
  previewVideoUrl.value = form.value.VideoUrl;
  previewPop.value = true;
};

// 结束预览弹窗关闭回调 -- 暂停视频
const endingPreview = () => {
  previewVideo.pause();
};

// 生命周期钩子 - 组件挂载时执行
onMounted(() => {
  getClassifyList('leaf');
  getTagList();
  getVideoDetail();
});
</script>

<style lang="scss">
.modify-video-page-wrap{
    .t-textarea__inner{
        resize: none;
    }
    .t-form-item{
            .t-form-item__content{
                display: flex;
                flex-direction: column;
                align-items:flex-start;
            }
        }
}
</style>
<style scoped lang="scss">
.modify-video-page-wrap{
    box-sizing: border-box;
    padding:40px;
    background-color: #fff;
    border-radius: 4px;
    .t-form{
        .t-input,.t-select,.t-textarea{
            width:500px;
        }
        .img-box{
            /* background-color: #D9D9D9; */
            border:1px dashed #d9d9d9;
            width:150px;
            height:100px;
            text-align: center;
            margin-top: 10px;
            position: relative;
            line-height: normal;
            img{
                width:100%;
                height:100%;
            }
            .duration{
                position:absolute;
                right:0;
                bottom:0;
                background-color: black;
                color:#fff;
                padding:4px;
            }
            .t-progress{
                position: absolute;
                left:50%;
                top:50%;
                transform: translate(-50%,-50%);
                background-color: white;
                border-radius: 50%;
            }
        }
        .tag-list{
            display: flex;
            gap:10px;
            line-height:0;
            .tag-item{
                cursor: pointer;
                text-align: center;
                box-sizing: border-box;
                padding:12px;
                min-width:78px;
                color: #409EFF;
                background-color: #EAF3FE;
                border:1px solid #409EFF;
                border-radius: 2px;
            }
        }
    }
    .btn-box{
      margin-top: 20px;
        text-align: center;
        .t-button{
            margin-right: 50px;
            width:120px;
            text-align: center;
        }
    }
}
</style>
