<!--
* @FileDescription: 教程播放
* @Author: 黄琪勇
* @Date:2024-04-03 17:31:41
-->
<template>
   <div class="coursewarePlay" :class="[!isShowController && 'hideController', fileType === 'SONG' && 'fileType_song']">
      <div class="coursewarePlayCon" @mousemove="handleMousemove" @click="handleClick" @touchstart="handleClick">
         <videoPlay
            v-show="fileType === 'VIDEO'"
            ref="videoPlayDom"
            @ended="handleChangeCourseware(1)"
            @playbackRate="showController"
            :disableEvents="true"
            :isShowController="isShowController"
         />
         <div class="imgPlayBox" v-if="fileType === 'IMG'">
            <ElImage :hide-on-click-modal="true" fit="contain" :src="activeCourseware?.content" class="imgPlay" />
         </div>
         <div class="songPlayBox" v-if="fileType === 'SONG'">
            <iframe class="songIframe" @mousemove="handleMousemove" :src="songPlaySrc" frameborder="0"></iframe>
         </div>
      </div>
      <div class="leftTools posTools">
         <div v-if="activeCoursewareIndex > 0" class="posBtn" @click="handleChangeCourseware(-1)">
            <img src="@/img/coursewarePlay/shang.png" />
            <div>上一个</div>
         </div>
         <div v-if="activeCoursewareIndex < flattenCoursewareList.length - 1" class="posBtn" @click="handleChangeCourseware(1)">
            <img src="@/img/coursewarePlay/xia.png" />
            <div>下一个</div>
         </div>
      </div>
      <div class="rightTools posTools">
         <div
            class="posBtn"
            @click="
               () => {
                  handleVideoPause()
                  whitePenShow = true
               }
            "
         >
            <img src="@/img/coursewarePlay/baiban.png" />
            <div>白板</div>
         </div>
         <div
            class="posBtn"
            @click="
               () => {
                  handleVideoPause()
                  penShow = true
               }
            "
         >
            <img src="@/img/coursewarePlay/pizhu.png" />
            <div>批注</div>
         </div>
         <div class="posBtn" @click="drawerShow = true">
            <img src="@/img/coursewarePlay/zhishidian.png" />
            <div>知识点</div>
         </div>
         <div class="posBtn" @click="handleCoursewareEnd">
            <img src="@/img/coursewarePlay/jieshu.png" />
            <div>结束</div>
         </div>
      </div>
      <div
         v-if="activeCoursewareResourceId"
         @click="
            () => {
               handleVideoPause()
               handleGoPracticeBtn(activeCoursewareResourceId!)
            }
         "
         class="goPracticeBtn"
      ></div>
      <div class="topTools">
         <div class="leftMenu">
            <img @click="handleGoBack" class="backImg" src="@/img/coursewarePlay/back.png" />
            <playRecordTime
               v-if="route.query.modeId && coursewareTotalTime && userStoreHook.roles === 'GYT'"
               :modeId="route.query.modeId as string"
               :coursewareTotalTime="coursewareTotalTime"
            />
         </div>
         <div class="midMenu">{{ activeCourseware?.parentData.name || "" }}</div>
         <div class="rightMenu"></div>
      </div>
      <el-drawer class="elDrawer" v-model="drawerShow" :show-close="false">
         <template #header="{ close }">
            <img class="directory" src="@/img/coursewarePlay/kcml.png" />
            <div class="tit">课程目录</div>
            <img class="close" @click="close" src="@/img/coursewarePlay/close.png" />
         </template>
         <ElScrollbar class="elScrollbar">
            <courseCollapse :activeCollapse="activeCourseware" :courseList="coursewareList" @handleClick="handleCourseClick" />
         </ElScrollbar>
      </el-drawer>
      <pen
         :close="
            () => {
               penShow = false
            }
         "
         v-model="penShow"
      />
      <pen
         :is-white="true"
         :close="
            () => {
               whitePenShow = false
            }
         "
         v-model="whitePenShow"
      />
   </div>
</template>

<script setup lang="ts">
import videoPlay from "./videoPlay"
import { getLessonCourseDetail_gym, getLessonCoursewareDetail_gyt, getLessonCourseDetail_klx } from "@/api/cloudTextbooks.api"
import { checkWebCourse_gyt } from "@/api/coursewarePlay.api"
import { httpAjaxErrMsg, httpAjaxLoadingErrMsg } from "@/plugin/httpAjax"
import userStore from "@/store/modules/user"
import { useRoute, useRouter } from "vue-router"
import { shallowRef, ref, computed, onUnmounted, onMounted, watch, nextTick } from "vue"
import { ElMessageBox } from "element-plus"
import courseCollapse from "./components/courseCollapse"
import pen from "./components/pen"
import playRecordTime from "./components/playRecordTime"
import useDialogConfirm from "@/hooks/useDialogConfirm"
import { getRecentCourseSchedule_gym } from "@/api/homePage.api"
import { getToken } from "@/libs/auth"
import { URL_TEACH_GYT, URL_TEACH_GYM, URL_TEACH_KLX } from "@/config"
import { handleFullscreen } from "@/libs/fullscreen"

const route = useRoute()
const router = useRouter()
const userStoreHook = userStore()
// 批注
const penShow = ref(false)
// 白板
const whitePenShow = ref(false)
/* 获取资源 */
const videoPlayDom = ref<InstanceType<typeof videoPlay>>()
const coursewareList = shallowRef<any[]>([]) // 知识点
const flattenCoursewareList = shallowRef<any[]>([]) // 扁平化coursewareList
// 选中的知识点
const activeCourseware = computed<undefined | Record<string, any>>(() => {
   return flattenCoursewareList.value[activeCoursewareIndex.value]
})
// 文件类型
const fileType = computed<"VIDEO" | "IMG" | "SONG">(() => {
   return activeCourseware.value?.typeCode || activeCourseware.value?.type
})
const songPlaySrc = computed<string>(() => {
   if (fileType.value !== "SONG") {
      return ""
   }
   //  GYM,GYT,KLX 区分   云教练
   const urlObj = {
      GYT: `${URL_TEACH_GYT}?id=${activeCourseware.value?.content}&modelType=practice&modeType=json&Authorization=${getToken()}&isYjt=1`,
      GYM: `${URL_TEACH_GYM}#/detail/${
         activeCourseware.value?.content
      }?Authorization=${getToken()}&platform=web&liveConfig=1&isHideBack=true&isYjt=1`,
      KLX: `${URL_TEACH_KLX}??Authorization=${getToken()}&id=${activeCourseware.value?.content}&isHideBack=true&limitModel=practice&isYjt=1`
   }
   return urlObj[userStoreHook.roles!]
})
const activeCoursewareIndex = ref(0)
const drawerShow = ref(false)
// 课程总时间
const coursewareTotalTime = ref(0)
// 监控播放
watch(activeCourseware, () => {
   handleVideoPause()
   fileType.value === "VIDEO" &&
      nextTick(() => {
         handlePlayVideo({
            src: activeCourseware.value?.content,
            name: activeCourseware.value?.name
         })
      })
   showController()
})
getCoursewareList()
function getCoursewareList() {
   //  GYM,GYT,KLX 区分   查询接口
   const LessonCoursewareDetailApi = {
      GYT: getLessonCoursewareDetail_gyt,
      GYM: getLessonCourseDetail_gym,
      KLX: getLessonCourseDetail_klx
   }
   httpAjaxErrMsg(LessonCoursewareDetailApi[userStoreHook.roles!], route.params.id as string).then(res => {
      if (res.code === 200) {
         const { lockFlag, knowledgePointList } = res.data || {}
         if (lockFlag) {
            ElMessageBox.alert("课件已锁定", "温馨提示", {
               confirmButtonText: "退出",
               type: "error"
            })
               .then(() => {
                  handleGoBack()
               })
               .catch(() => {
                  handleGoBack()
               })
            return
         }
         if ((knowledgePointList || []).length < 1) {
            ElMessageBox.alert("没有找到课件", "温馨提示", {
               confirmButtonText: "退出",
               type: "error"
            })
               .then(() => {
                  handleGoBack()
               })
               .catch(() => {
                  handleGoBack()
               })
            return
         }
         // 处理返回的数据
         handlePointList(knowledgePointList)
      }
   })
}
let flattenCoursewareListData: any = [] // 临时扁平化数据
function handlePointList(pointList: any[]) {
   coursewareList.value = filterPointList(pointList)
   // 如果url里面有materialId 代表指定资料播放
   if (route.query.materialId) {
      const index = flattenCoursewareListData.findIndex((item: any) => {
         return route.query.materialId === item.id + "" && route.query.knowledgePointId === item.knowledgePointId + ""
      })
      index > -1 && (activeCoursewareIndex.value = index)
   }
   flattenCoursewareList.value = flattenCoursewareListData
}
function filterPointList(pointList: any[], parentData?: { ids: string[]; name: string }): any[] {
   // 设置父级及以上id数组和父级name
   return pointList.map(point => {
      if (point.children) {
         return Object.assign(point, {
            children: filterPointList(point.children, { ids: [...(parentData?.ids || []), point.id], name: point.name })
         })
      } else {
         coursewareTotalTime.value += point.totalMaterialTimeSecond
         return Object.assign(point, {
            materialList: point.materialList.map((item: any) => {
               item.parentData = {
                  ids: [...(parentData?.ids || []), point.id],
                  name: point.name
               }
               flattenCoursewareListData.push(item)
               return item
            })
         })
      }
   })
}
function handleChangeCourseware(index: -1 | 1) {
   const newIndex = index + activeCoursewareIndex.value
   if (newIndex < 0 || newIndex > flattenCoursewareList.value.length - 1) {
      return
   }
   activeCoursewareIndex.value = newIndex
}
function handleCourseClick(value: any) {
   activeCoursewareIndex.value = flattenCoursewareList.value.findIndex((item: any) => {
      return value.id === item.id && value.knowledgePointId === item.knowledgePointId
   })
}
/* 播放器相关 */
// 视频播放或者暂停
function handleVideoPlay() {
   videoPlayDom.value?.handlePlay()
   showController()
}
// 视频快进快退
function handleVideoSpeedCurrentTime(type: "fast" | "slow") {
   videoPlayDom.value?.speedCurrentTime(type)
   showController()
}
// 视频暂停
function handleVideoPause() {
   videoPlayDom.value?.pauseVideo()
   showController()
}
// 播放视频
function handlePlayVideo({ src, name }: { src: string; name: string }) {
   videoPlayDom.value?.playVideo({
      src,
      name
   })
   showController()
}

// 全屏显示
handleFullscreen(true, false)
/* 按键事件相关 */
onMounted(() => {
   document.addEventListener("keydown", handleKeydown)
   document.addEventListener("contextmenu", preventDefaultContextmenu)
   showController()
})
onUnmounted(() => {
   document.removeEventListener("keydown", handleKeydown)
   document.removeEventListener("contextmenu", preventDefaultContextmenu)
})
function preventDefaultContextmenu(event: MouseEvent) {
   event.preventDefault()
}
function handleKeydown(e: KeyboardEvent) {
   const key = e.key
   if (key === " ") {
      // 视频类型的时候才触发
      fileType.value === "VIDEO" && handleVideoPlay()
   } else if (key === "ArrowLeft") {
      // 视频类型的时候才触发
      fileType.value === "VIDEO" && handleVideoSpeedCurrentTime("slow")
   } else if (key === "ArrowRight") {
      // 视频类型的时候才触发
      fileType.value === "VIDEO" && handleVideoSpeedCurrentTime("fast")
   } else if (key === "ArrowDown") {
      handleChangeCourseware(1)
   } else if (key === "ArrowUp") {
      handleChangeCourseware(-1)
   }
}
function handleMousemove() {
   showController()
}
function handleClick() {
   fileType.value === "VIDEO" && isShowController.value && handleVideoPlay()
   showController()
}
// 是否显示控制器
const isShowController = ref(true)
let _showTimer: any
function showController() {
   isShowController.value = true
   _showTimer && clearTimeout(_showTimer)
   _showTimer = setTimeout(hideController, 3000)
}
function hideController() {
   if (fileType.value === "VIDEO" && videoPlayDom.value?.playType === "pause") {
      return
   }
   isShowController.value = false
}
/* 结束课程 */
function handleGoBack() {
   // window.open("about:blank", "_self")
   // window.close()
   router.go(-1)
}
function handleCoursewareEnd() {
   if (route.query.modeId) {
      if (userStoreHook.roles === "GYM") {
         httpAjaxLoadingErrMsg(getRecentCourseSchedule_gym, route.query.modeId as string).then(res => {
            if (res.code === 200) {
               if (res.data?.signOutStatusEnum === 3) {
                  useDialogConfirm({
                     headImg: require("@/img/coursewarePlay/ts.png"),
                     text: `请确认是否结束课程，结束后请到APP进行签退。`,
                     btnShow: [true, true],
                     onOk() {
                        handleGoBack()
                     }
                  })
               } else {
                  handleGoBack()
               }
            }
         })
      } else if (userStoreHook.roles === "GYT") {
         httpAjaxLoadingErrMsg(checkWebCourse_gyt, route.query.modeId as string).then(res => {
            if (res.code === 200) {
               if (res.data?.signOut === false) {
                  useDialogConfirm({
                     headImg: require("@/img/coursewarePlay/ts.png"),
                     text: `请确认是否结束课程，结束后请到APP进行签退。`,
                     btnShow: [true, true],
                     onOk() {
                        handleGoBack()
                     }
                  })
               } else {
                  handleGoBack()
               }
            }
         })
      }
   } else {
      handleGoBack()
   }
}

// 去练习
const activeCoursewareResourceId = computed<string | undefined>(() => {
   const materialRefs = activeCourseware.value?.materialRefs
   return materialRefs ? (["GYM", "KLX"].includes(userStoreHook.roles!) ? materialRefs[0]?.resourceIdStr : materialRefs[0]?.resourceId) : undefined
})
function handleGoPracticeBtn(activeCoursewareResourceId: string) {
   //  GYM,GYT,KLX 区分   云教练
   const urlObj = {
      GYT: `${URL_TEACH_GYT}?id=${activeCoursewareResourceId}&modelType=practice&modeType=json&Authorization=${getToken()}&isYjt=1`,
      GYM: `${URL_TEACH_GYM}#/detail/${activeCoursewareResourceId}?Authorization=${getToken()}&platform=web&liveConfig=1&isYjt=1`,
      KLX: `${URL_TEACH_KLX}??Authorization=${getToken()}&id=${activeCoursewareResourceId}&limitModel=practice&isYjt=1`
   }
   window.open(urlObj[userStoreHook.roles!], "_blank")
}
</script>

<style lang="scss" scoped>
.coursewarePlay {
   width: 100%;
   height: 100%;
   position: relative;
   overflow: hidden;
   &.hideController {
      .leftTools {
         opacity: 0;
         transform: translate(-100%, -50%);
      }
      .rightTools {
         opacity: 0;
         transform: translate(100%, -50%);
      }
      .topTools {
         opacity: 0;
         transform: translateY(-100%);
      }
      .goPracticeBtn {
         transform: translatex(-135px);
      }
   }
   &.fileType_song.hideController {
      .leftTools {
         opacity: initial;
         transform: translateY(-50%);
      }
      .rightTools {
         opacity: initial;
         transform: translateY(-50%);
      }
      .goPracticeBtn {
         transform: initial;
      }
   }
   .coursewarePlayCon {
      width: 100%;
      height: 100%;
      overflow: hidden;
      .imgPlayBox {
         width: 100%;
         height: 100%;
         display: flex;
         justify-content: center;
         align-items: center;
         .imgPlay {
            width: 84%;
            height: 100%;
         }
      }
      .songPlayBox {
         width: 100%;
         height: 100%;
         .songIframe {
            display: block;
            width: 100%;
            height: 100%;
         }
      }
   }
   .topTools {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      background: linear-gradient(180deg, rgba(0, 0, 0, 0.6), transparent);
      transition: all 0.5s;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 20px 30px;
      .leftMenu {
         display: flex;
         align-items: center;
         .backImg {
            cursor: pointer;
            width: 22px;
            &:hover {
               opacity: $opacity-hover;
            }
         }
      }
      .midMenu {
         font-weight: 500;
         font-size: 20px;
         color: #ffffff;
      }
   }
   .posTools {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      transition: all 0.5s;
      &.leftTools {
         left: 12px;
      }
      &.rightTools {
         right: 12px;
      }
      .posBtn {
         background: rgba(0, 0, 0, 0.3);
         border-radius: 8px;
         padding: 12px 6px;
         font-weight: 500;
         font-size: 16px;
         color: #ffffff;
         display: flex;
         flex-direction: column;
         align-items: center;
         cursor: pointer;
         margin-bottom: 12px;
         &:hover {
            opacity: $opacity-hover;
         }
         &:last-child {
            margin-bottom: 0;
         }
         > img {
            margin-bottom: 5px;
            width: 34px;
            height: 34px;
         }
      }
   }
   .goPracticeBtn {
      position: absolute;
      left: 30px;
      bottom: 124px;
      width: 178px;
      height: 64px;
      background: url("@/img/coursewarePlay/goPracticeBtn.png") no-repeat;
      background-size: 100% 100%;
      cursor: pointer;
      transition: all 0.5s;
      &:hover {
         opacity: $opacity-hover;
      }
   }
   &:deep(.elDrawer.el-drawer) {
      width: 346px !important;
      .el-drawer__header {
         height: 54px;
         background: #ededed;
         padding: 0 20px;
         margin-bottom: 0;
         .directory {
            flex-grow: 0;
            flex-shrink: 0;
            width: 24px;
            height: 24px;
         }
         .tit {
            flex-grow: 1;
            margin-left: 10px;
            font-weight: 600;
            font-size: 18px;
            color: #333333;
         }
         .close {
            cursor: pointer;
            width: 14px;
            flex-shrink: 0;
            &:hover {
               opacity: $opacity-hover;
            }
         }
      }
      .el-drawer__body {
         padding: 0;
         overflow: hidden;
         & > .elScrollbar {
            .el-scrollbar__view {
               padding: 0 22px;
               width: 100%;
            }
            .el-scrollbar__wrap {
               overflow-x: hidden;
            }
         }
      }
   }
}
</style>
