<!--
 * @Author: ysh
 * @Date: 2025-03-06 14:38:35
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2025-03-12 11:01:28
-->
<template>
  <div>
    <div v-if="boxShow">
      <div class="return-btn">
        <div>
          <el-button type="primary" size="mini" icon="el-icon-d-arrow-left"
            @click="$router.push({ path: '/oa/study/myStudy' })">返回我的学习</el-button>
        </div>
        <div class="mt20">
          学习进度：
          <el-progress :text-inside="true" :status="formatStatus(percentage)" text-color="#fff" :stroke-width="26"
            :percentage="percentage"></el-progress>
        </div>
        <div class="mt20" style="color:#E23D28;font-size:12px;line-height:30px;">
          tips:鼠标滚动过快将导致进度计算失败，请隔2秒滚动一次页面。若一直未到100%，请返回我的学习重新进入课程。
        </div>
      </div>
      <div id="pdf-container">
        <div id="viewer" class="pdfViewer"></div>
      </div>
    </div>
    <div class="mt20 text-center" v-else>
      抱歉，暂不支持手机端，请前往电脑端观看学习
    </div>
  </div>
</template>

<script>
import { listStudy, getStudy, delStudy, addStudy, updateStudy } from "@/api/oa/study/myStudy";
import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist/build/pdf'
import { PDFViewer } from 'pdfjs-dist/web/pdf_viewer'
// 设置 PDF.js 的 Web Worker 路径
GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min');
export default {
  async mounted() {
    if (this.$store.getters.device === 'mobile') {
      this.boxShow = false;
      return
    } else {
      this.boxShow = true;
    }
    await this.getData();
    this.initPDFViewer()
  },
  data() {
    return {
      baseUrl: process.env.VUE_APP_BASE_API,
      studyId: '',
      pdfPath: '',
      pdfViewer: null,
      resource: {},
      totalPages: 0, //总页数
      readPages: [], //已阅读页数
      lastPoint: 0,
      debounceTimer: null,
      observers: new Map(),
      isComplete: false,
      percentage: 0,
      boxShow: false,
    }
  },
  methods: {
    async getData() {
      this.studyId = this.$route.params.id;
      let resData = await getStudy(this.studyId);
      let data = resData.data;
      this.pdfPath = data.resource.sourcePath;
      this.lastPoint = parseFloat(data.lastPoint);
      this.resource = data.resource;
      if (Number(this.lastPoint) == 100) {
        this.isComplete = true;
        this.$message.success('文档已阅读完毕')
      }
    },
    // 初始化查看器
    async initPDFViewer() {
      this.pdfViewer = new PDFViewer({
        container: document.getElementById('pdf-container'),
        enhanceTextSelection: true,
        textLayerMode: 1
      })
      // 先绑定监听页面变化事件
      this.setupViewerEvents();
      // 加载文档
      const loadingTask = getDocument({
        url: `/dev-api/profile/upload/${this.pdfPath}`,
        cMapPacked: true
      })
      try {
        const pdfDocument = await loadingTask.promise
        this.pdfViewer.setDocument(pdfDocument);
        this.totalPages = pdfDocument.numPages;
        this.readPages = new Array(this.totalPages).fill(false);
        let curProgress = Math.round((this.lastPoint / 100) * this.totalPages);
        this.percentage = Math.round(curProgress / this.totalPages) * 100;
        for (let i = 0; i < curProgress; i++) {
          this.readPages[i] = true
        }
        this.$nextTick(() => {
          this.setupPageObservers();
        });
      } catch (err) {
        console.error('PDF加载失败:', err)
      }
      // 添加窗口缩放监听
      window.addEventListener("resize", this.handleResize);
    },
    handleResize() {
      if (this.pdfViewer) {
        this.pdfViewer.update();
      }
    },
    setupViewerEvents() {
      const eventBus = this.pdfViewer.eventBus;
      // 新增 pagesloaded 事件监听
      eventBus.on('pagesloaded', () => {
        this.scrollToLastPosition();
        this.setupPageObservers()
      });
    },
    scrollToLastPosition() {
      if (!this.lastPoint || !this.totalPages) return
      // 计算目标页码（向上取整）
      const pageNumber = Math.min(
        Math.ceil((this.lastPoint / 100) * this.totalPages),
        this.totalPages
      )
      // 查找对应的页面元素
      const pageElement = document.querySelector(
        `.page[data-page-number="${pageNumber}"]`
      )
      if (pageElement) {
        // 获取页面元素的垂直位置
        const pageTop = pageElement.offsetTop
        // 设置滚动位置（带20px顶部留白）
        document.getElementById('pdf-container').scrollTo({
          top: pageTop - 20,
          behavior: 'auto'
        })
      }
    },
    setupPageObservers() {
      // 清理旧观察者
      this.observers.forEach((observer, page) => {
        observer.disconnect();
        delete page.dataset.timer;
      });
      this.observers.clear();
      const pages = document.querySelectorAll('.page');
      pages.forEach(page => {
        const observer = new IntersectionObserver((entries) => {
          entries.forEach(entry => {
            const pageNumber = parseInt(page.dataset.pageNumber);
            if (entry.isIntersecting) {
              page.dataset.enterTime = Date.now();
              page.dataset.timer = setTimeout(() => {
                if (!this.readPages[pageNumber - 1]) {
                  this.$set(this.readPages, pageNumber - 1, true);
                  this.updateProgress();
                }
              }, 2000);
            } else {
              clearTimeout(page.dataset.timer);
              delete page.dataset.enterTime;
            }
          });
        }, { threshold: 0.5, root: this.pdfViewer.container });

        this.observers.set(page, observer);
        observer.observe(page);
      });
    },
    updateProgress() {
      if (!this.isComplete) {
        const readCount = this.readPages.filter(Boolean).length;
        const progress = Math.round(readCount / this.totalPages * 100);
        this.percentage = progress;
        // 防抖保存
        if (!this.debounceTimer) {
          this.debounceTimer = setTimeout(() => {
            this.saveProgress(progress);
            this.debounceTimer = null;
          }, 2000);
        }
      }
    },
    async saveProgress(progress) {
      try {
        if (parseFloat(progress) == 100) {
          this.$message.success('文档已阅读完毕！学时+' + this.resource.hours)
          progress = 100
        }
        await updateStudy(
          {
            studyId: this.studyId,
            lastPoint: progress,
            getHours: Math.round((this.resource.hours * progress) / 100),
            lastTime: this.parseTime(new Date(), '{y}-{m}-{d}')
          });
      } catch (error) {
        console.error('保存进度失败:', error);
      }
    },
    formatStatus(row) {
      if (!row) {
        row = 0
        return 'exception'
      }
      if (row <= 20) {
        return 'exception'
      } else if (row > 20 && row <= 50) {
        return 'warning'
      } else if (row > 50 && row <= 80) {
        return null
      } else {
        return 'success'
      }
    },
  },
  beforeDestroy() {
    // 清理观察者和定时器
    this.observers.forEach((observer, page) => {
      observer.disconnect();
      clearTimeout(page.dataset.timer);
    });
    window.removeEventListener("resize", this.handleResize);
  }

}
</script>

<style lang="scss" scoped>
@import '~pdfjs-dist/web/pdf_viewer.css';

/* 修改后 */
#pdf-container {
  position: relative;
  /* 改为相对定位，避免脱离文档流 */
  width: 100%;
  height: calc(100vh - 88px);
  /* 根据实际布局调整高度 */
  overflow: auto;
  background-color: #cdcdcd;
}

.pdfViewer .page {
  margin: 1em auto;
  border: 1px solid #ddd;
  box-shadow: 0 10px 10px rgba(0, 0, 0, 0.1);
}

.return-btn {
  position: absolute;
  left: 20px;
  top: 100px;
  z-index: 9999;
  width: 230px;
}
</style>