<template>
    <div
        class="study-document"
        v-loading="loading"
        element-loading-text="文件加载中，请耐心等待..."
        element-loading-background="rgba(0, 0, 0, 1)"
        ref="studyDocument"
    >
        <div class="pdf-content" ref="pdfContent">
            <div class="loading-wrapper" v-if="loadedRatio !== 100">
                <el-progress
                    type="circle"
                    :stroke-width="10"
                    :percentage="loadedRatio"
                ></el-progress>
            </div>
            <pdf
                class="pdf-preview"
                ref="pdfViewer"
                :src="pdfSrc"
                :page="pageNumber"
                v-show="loadedRatio === 100"
                @progress="progressLoad"
                @num-pages="totalPagesChanged"
                @error="pdfError"
                @loaded="pdfLoaded"
            />
        </div>
        <div
            :class="[
                'bottom-content',
                isFullscreenRequested ? 'bottom-content-screen' : '',
            ]"
        >
            <template v-if="type !== 'read'"
                >任务总时长：<span class="blue-text">{{
                    totalDuration || ''
                }}</span
                >， </template
            >当前页：<span class="blue-text">{{ pageNumber || 0 }}页</span>，
            总页数：<span class="blue-text">{{ totalPages || 0 }}页</span
            >，<template v-if="type !== 'read'">
                学习进度：<span class="blue-text">{{
                    learningDuration || ''
                }}</span></template
            >
        </div>
        <div class="btn-content">
            <el-button
                title="上一页"
                type="primary"
                icon="el-icon-arrow-up"
                circle
                @click="goToPreviousPage"
                :disabled="pageNumber === 1"
            />
            <el-button
                title="下一页"
                type="primary"
                icon="el-icon-arrow-down"
                circle
                @click="goToNextPage"
                :disabled="pageNumber === totalPages"
            />
            <el-button
                :title="isFullscreenRequested ? '取消全屏' : '全屏'"
                type="primary"
                icon="el-icon-full-screen"
                circle
                :plain="!isFullscreenRequested"
                @click="toggleFullScreen"
            />
            <el-button
                title="放大"
                type="primary"
                icon="el-icon-zoom-in"
                circle
                :disabled="scale === 200"
                @click="handleScale('bigger')"
            />
            <el-button
                title="缩小"
                type="primary"
                icon="el-icon-zoom-out"
                circle
                :disabled="scale === 20"
                @click="handleScale('smaller')"
            />
        </div>
    </div>
</template>

<script>
import pdf from 'vue-pdf'
// import pdfvuer from 'pdfvuer'
import {onlinePreview} from '@/api/systemInterface'
import _ from 'lodash'
import moment from 'moment'
import 'moment-duration-format'
import screenfull from 'screenfull'
import {mapActions, mapState} from 'vuex'

export default {
    name: 'StudyDocument',
    props: {
        // 资料信息
        dataInformation: {
            default: () => ({}),
            type: Object,
        },

        type: {
            default: '',
            type: String,
        },
    },
    components: {pdf},

    data() {
        return {
            isFullscreenRequested: false, // 记录全屏请求的状态
            pdfSrc: '', // 替换为您的 PDF 文件路径
            pageNumber: 1,
            totalPages: 0,
            loading: true,
            intervalTimer: null,
            hourMinuteSecondTimer: null,
            studyTime: 0,
            isFinished: false, // 是否学习完成
            scale: 100,
            timer: null,
            // 加载进度
            loadedRatio: 0,
            // 文件大小
            totalSize: 0,
            scrollTop: 0,
        }
    },
    computed: {
        actionUrl: (_) => window.context.portal,
        totalDuration() {
            return moment
                .duration(this.dataInformation.videoTime, 'seconds')
                .format('HH:mm:ss', {trim: false})
        },
        learningDuration() {
            return moment
                .duration(this.studyTime, 'seconds')
                .format('HH:mm:ss', {trim: false})
        },
        // 绑定 Vuex 状态到组件的计算属性
        ...mapState({
            userId: (state) => state?.user?.currentUserDetail?.user?.id || '',
        }),
    },
    watch: {
        dataInformation: {
            handler(newVal, oldVal) {
                this.loading = true
                if (oldVal?.fileId) {
                    this.clearWebSocket()
                    clearInterval(this.hourMinuteSecondTimer)
                    clearInterval(this.intervalTimer)
                    this.sendLearningDuration((_) => {
                        this.studyTime = this.dataInformation.studyTime || 0
                        this.isFinished =
                            this.studyTime === this.dataInformation.videoTime
                        this.getPdfSrc(newVal.fileId)
                    }, oldVal)
                } else {
                    this.studyTime = this.dataInformation.studyTime || 0
                    this.isFinished =
                        this.studyTime === this.dataInformation.videoTime
                    this.getPdfSrc(newVal.fileId)
                }
            },
            immediate: true,
            deep: true,
        },
    },
    mounted() {
        // 添加全屏状态变化监听器、键盘事件监听器和禁用右键菜单
        if (screenfull.isEnabled) {
            screenfull.on('change', this.handleFullScreenChange)
        }
        // this.$refs.pdfContent.addEventListener('wheel', this.handleWheel)
        this.throttledHandleWheel = _.throttle(this.handleWheel, 500, {
            trailing: false,
        })
        this.$refs.pdfContent.addEventListener(
            'wheel',
            this.throttledHandleWheel
        )
    },
    methods: {
        // 绑定 Vuex actions 到组件的方法
        ...mapActions([
            'startWebSocket',
            'sendWebSocketMessage',
            'clearWebSocket',
            'reconnectWebSocket',
        ]),

        totalPagesChanged(numPages) {
            this.totalPages = numPages
        },

        // 获取pdf都中
        async getPdfSrc(fileId = '') {
            if (!fileId)
                return this.$message.error('文件错误，请联系管理员解决')
            try {
                const {pdfUrl, fileSize = 0} = await onlinePreview(fileId)
                this.totalSize = fileSize
                if (pdfUrl) {
                    this.pdfSrc = this.actionUrl + pdfUrl
                    this.pageNumber = this.dataInformation.presentPage || 1
                    if (!this.isFinished) {
                        this.startWebSocket()
                        this.hourMinuteSecondTimer = setInterval(() => {
                            if (
                                this.studyTime >= this.dataInformation.videoTime
                            ) {
                                this.isFinished = true
                                this.sendLearningDuration()
                                clearInterval(this.hourMinuteSecondTimer)
                                clearInterval(this.intervalTimer)
                            } else {
                                this.studyTime += 1
                            }
                        }, 1000)
                        this.intervalTimer = setInterval(
                            () =>
                                !this.isFinished && this.sendLearningDuration(),
                            5000
                        )
                    }
                } else {
                    this.$message.error('文件错误，请联系管理员解决')
                }
            } catch {
                this.$message.error('文件错误，请联系管理员解决')
            } finally {
                this.loading = false
            }
        },

        // 发送视频时长的函数
        async sendLearningDuration(callback, dataInformation) {
            try {
                dataInformation = dataInformation || this.dataInformation
                const {id: studyFileId, videoTime} = dataInformation
                await this.sendWebSocketMessage(
                    JSON.stringify({
                        messageType: 'train',
                        sender: this.userId,
                        message: {
                            studyFileId,
                            studyTime: this.studyTime,
                            videoTime,
                            presentPage: this.pageNumber,
                        },
                    })
                )
            } catch {
            } finally {
                callback && callback()
            }
        },

        goToPreviousPage() {
            if (this.pageNumber > 1) {
                this.pageNumber--
                this.$refs.pdfContent.scrollTop = 0
            }
        },

        goToNextPage() {
            if (this.pageNumber < this.totalPages) {
                this.pageNumber++
                this.$refs.pdfContent.scrollTop = 0
            }
        },

        progressLoad(status) {
            this.loadedRatio = parseInt(
                ((status.loaded / this.totalSize) * 100).toFixed(0)
            )

            if (this.loadedRatio === 100) {
                this.currentPage = this.dataInformation.presentPage || 1
            }
        },

        // pdf错误
        pdfError() {
            this.pageNumber = 1
            this.studyTime = 0
            this.clearWebSocket()
            clearInterval(this.hourMinuteSecondTimer)
            clearInterval(this.intervalTimer)
        },

        // pdf加载中
        pdfLoaded() {
            this.pageNumber = this.dataInformation.presentPage || 1
        },

        // 根据参数请求或退出全屏，默认请求全屏
        toggleFullScreen() {
            this.isFullscreenRequested = !this.isFullscreenRequested
            if (screenfull.isEnabled) {
                if (this.isFullscreenRequested) {
                    screenfull.request(this.$refs.studyDocument)
                } else {
                    screenfull.exit()
                }
            }
        },

        // 全屏改变事件
        handleFullScreenChange() {
            this.isFullscreenRequested = screenfull.isFullscreen
        },

        // 缩放
        handleScale(type) {
            if (type === 'bigger') {
                this.scale += 20
                if (this.scale > 200) this.scale = 200
            } else {
                this.scale -= 20
                if (this.scale < 20) this.scale = 20
            }
            this.$nextTick(() => {
                this.$refs.pdfViewer.$el.style.width =
                    parseInt(this.scale) + '%'
            })
        },
        //滚动翻页
        handleWheel(e) {
            const {scrollTop, clientHeight, scrollHeight} =
                this.$refs.pdfContent

            const tolerance = 2
            //下滑下一页
            if (
                Math.abs(scrollTop + clientHeight - scrollHeight) <=
                    tolerance &&
                e.deltaY > 0
            ) {
                this.goToNextPage()
            }
            //上滑上一页
            if (scrollTop == 0 && e.deltaY < 0) {
                this.goToPreviousPage()
                this.scrollTop = 2
            }
        },
    },
    beforeDestroy() {
        clearInterval(this.intervalTimer) // 清除旧的定时器
        clearInterval(this.hourMinuteSecondTimer) // 清除旧的定时器
        // 发送视频时长的函数
        this.sendLearningDuration((_) => {
            // 在组件销毁前清除 WebSocket 连接
            this.clearWebSocket()
        })
        screenfull.off('change', this.handleFullScreenChange)
        if (this.throttledHandleWheel) {
            this.$refs.pdfContent.removeEventListener(
                'wheel',
                this.throttledHandleWheel
            )
        }
    },
}
</script>

<style lang="scss" scoped>
@import '~@/assets/css/element-variables';

.study-document {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  row-gap: 20px;
  position: relative;

  .pdf-content {
    width: 100%;
    flex: 1;
    padding: 0 25%;
    box-sizing: border-box;
    background-color: $--system-box-color2;
    overflow: auto;

    ::v-deep canvas {
      margin: 50px 0;
    }
    .loading-wrapper {
        width: 100% !important;
        height: 100% !important;
        display: flex;
        justify-content: center;
        align-items: center;
    }
  }

  .bottom-content {
    flex-shrink: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 16px;
    font-weight: bold;
    vertical-align: bottom;
    line-height: 1.5;

    .blue-text {
      color: $--color-primary;
      font-size: 16px;
      font-weight: bold;
      vertical-align: middle;
    }

    &.bottom-content-screen {
      color: $--system-table-text-color;
    }
  }

  .btn-content {
    position: absolute;
    display: flex;
    flex-direction: column;
    row-gap: 20px;
    top: 40%;
    transform: translateY(-50%);
    right: 2%;

    ::v-deep .el-button {
      margin: 0;
      width: 50px;
      height: 50px;
      padding: 0;

      i {
        font-size: 24px;
      }
    }
  }
}
.pdf-preview {
  height: 100vh;
}
.pdf-preview canvas {
  height: 100% !important;
}
</style>
