<template>
  <div class="fixedToolBar">
    <ElDropdown placement="bottom">
      <!-- 其中包含的功能有分页，页数跳转，文件下载 -->
      <i class="fa fa-download cursor-pointer download" hover-color="var(--el-color-primary)"></i>
      <template #dropdown>
        <ElDropdownMenu>
          <ElDropdownItem @click="downloadFile('pdf')">下载PDF文件</ElDropdownItem>
          <ElDropdownItem @click="downloadFile('word')">下载WORD文件</ElDropdownItem>
        </ElDropdownMenu>
      </template>
    </ElDropdown>
  </div>
  <div class="pdf-viewer" :loading="loading">
    <div class="sidebar">
      <ul>
        <li v-for="(page,pageIndex) in pagesInfo" :key="page.number" @click="navigateToPage(page.number)">
          <a>
            <img :src="page.thumbnail" alt="Page Thumbnail" :class="pageIndex===currentPage?'thumbnail active':'thumbnail'" />
            <span>{{ pageIndex+1 }}</span>
          </a>
        </li>
      </ul>
    </div>
    <div class="pdf-container" @scroll="handleScroll">
      <!-- <input type="file" @change="handleFileChange" accept="application/pdf" /> -->
      <div ref="pdfContainer" class="pdf-pages"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted  } from 'vue';
import * as pdfjsLib from 'pdfjs-dist';
import 'pdfjs-dist/build/pdf.worker.entry';
import { useRoute } from 'vue-router';
import { ElMessage,ElDropdown,ElDropdownMenu,ElDropdownItem } from 'element-plus';
import {queryFileFlowRepTemplateApi,exportTemplateApi} from '@/api/reporting/RepTemplate/RepTemplate';

onMounted(() => {
  window.addEventListener('scroll', handleScroll);
});

onUnmounted(() => {
  window.removeEventListener('scroll', handleScroll);
});

// 设置 worker 源
pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.entry';

let loading = ref(false);//界面的加载loading
const pdfContainer = ref(null);
const pdfDocument = ref(null);
const pdfInfo = ref({});
const pagesInfo = ref([]);
let currentPage = ref(0);//设置当前页在的索引页
let pageHeight = ref(0);//获取单个canvas的高度
const route = useRoute();
// 也可以直接是在线地址
//获取当前预览文件参数的信息
const pageQuery = ref(route || null); 
const params = pageQuery.value?.query?.fileData;
//是否能够预览的状态显示
const downLoadErrorMsg = {
  "1001":"预览失败,文件路径不存在",
  "1002":"预览失败,未找到文件信息",
  "1003":"预览失败,请联系管理员",
}
let BlobFile = ref(null);//文件的blob文件信息
//渲染左侧的缩略图
const generateThumbnails = async () => {
  if (!pdfDocument.value) return;

  const numPages = pdfDocument.value.numPages;
  const thumbnails = [];

  for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) {
    const page = await pdfDocument.value.getPage(pageNumber);
    const viewport = page.getViewport({ scale: 0.5 }); // 缩略图比例

    // 创建一个新的 canvas 元素
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');

    canvas.height = viewport.height;
    canvas.width = viewport.width;
    
    const renderContext = {
      canvasContext: context,
      viewport: viewport
    };

    await page.render(renderContext).promise;

    // 将 canvas 转换为 base64 图片
    const thumbnail = canvas.toDataURL('image/png');
    thumbnails.push({ number: pageNumber, thumbnail });
  }

  pagesInfo.value = thumbnails;
};
//渲染全部界面
const renderAllPages = async () => {
  if (!pdfDocument.value) return;

  const numPages = pdfDocument.value.numPages;
  for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) {
    await renderPage(pageNumber);
  }
};
//渲染单个界面
const renderPage = async (pageNumber) => {
  if (!pdfDocument.value) return;

  const page = await pdfDocument.value.getPage(pageNumber);
  const viewport = page.getViewport({ scale: 1.5 });
  
  // 创建一个新的 canvas 元素
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');

  canvas.height = viewport.height;
  canvas.width = viewport.width;
  canvas.style.margin = '10px 0';
  pageHeight.value = viewport.height + 10;
  // 将 canvas 添加到容器中
  pdfContainer.value.appendChild(canvas);

  const renderContext = {
    canvasContext: context,
    viewport: viewport
  };

  await page.render(renderContext).promise;
};
//点击缩略图进行界面的定位
const navigateToPage = (pageNumber) => {
  const pageElements = pdfContainer.value.querySelectorAll('canvas');
  pageElements.forEach((element, index) => {
    if (index + 1 === pageNumber) {
      element.scrollIntoView({ behavior: 'smooth' });
    }
  });
  // 更新当前页索引
  currentPage.value = pageNumber - 1;
};

//监听滚动事件，设置currentPage的值
const handleScroll = (event) => {
  const scrollElement = event.target;
  const scrollHeight = scrollElement.scrollHeight;
  const scrollTop = scrollElement.scrollTop;
  currentPage.value = Math.round((scrollTop) / (pageHeight.value + 70));
};

//获取到的blob数据转换为file文件
const TurnBlobForRender = async (data) => {
  if(!data){return}
  const convertedFile = new File([data], { type: 'application/pdf' });
  const fileReader = new FileReader();
    fileReader.onload = async (e) => {
      console.log(e,"文件信息");
      const typedArray = new Uint8Array(e.target.result);
      try {
        pdfDocument.value = await pdfjsLib.getDocument({ data: typedArray }).promise;
        await generateThumbnails();
        renderAllPages();
        currentPage.value = 0;//初始化当前页为第一页
        let loading = ref(false);
      } catch (error) {
        let loading = ref(false);
        console.error('Error loading PDF:', error);
      }
    };
    fileReader.onerror = (error) => {
      console.error('Error reading file:', error);
    };
    fileReader.readAsArrayBuffer(convertedFile);
};
//从后台获取文件流
const fetchDocFile = async () => {
  let loading = ref(true);
  // 这里假设你有一个 API 可以返回 DOCX 文件的 ArrayBuffer
  const response = await queryFileFlowRepTemplateApi(params);
  const { data, headers } = response;
  if(headers['status'] == 500){// 说明此时下载文件有错误，需要获取WARN和ERROR的值
    const code = headers['error']?headers['error'].substring(headers['error'].length-4):'1003';
    console.log(code)
    switch(code){
      case "1001":
      case "1002":
        ElMessage.error(downLoadErrorMsg[code]);
        break;
      default:
        ElMessage.error(downLoadErrorMsg['1003']);
        break;
    }
    let loading = ref(false);
    return;
  }
  BlobFile.value = response;
  TurnBlobForRender(data);
};
fetchDocFile();//进入界面需要获取blob文件流

const handleFileChange = async (event) => {
  const file = event.target.files[0];
  if (file) {
    if (!file.type.startsWith('application/pdf')) {
      console.error('Invalid file type. Only PDF files are allowed.');
      return;
    }

    if (file.size > 5 * 1024 * 1024) { // 限制文件大小为5MB
      console.error('File size exceeds the limit of 5MB.');
      return;
    }
    const fileReader = new FileReader();
    fileReader.onload = async (e) => {
      console.log(e,"文件信息");
      const typedArray = new Uint8Array(e.target.result);
      try {
        pdfDocument.value = await pdfjsLib.getDocument({ data: typedArray }).promise;
        await generateThumbnails();
        renderAllPages();
        currentPage.value = 0;//初始化当前页为第一页
      } catch (error) {
        console.error('Error loading PDF:', error);
      }
    };
    fileReader.onerror = (error) => {
      console.error('Error reading file:', error);
    };
    fileReader.readAsArrayBuffer(file);
  }
};

//下载文件
const downloadFile = (type) => {
  switch (type) {
    case 'pdf':
      const { data, headers } = BlobFile.value;
      const fileName = headers['content-disposition']?.replace(/\w+;\s*filename=(.*)/, '$1');
      const blob = new Blob([data], {
        type: headers['content-type']
      })
      const dom = document.createElement('a');
      const _url = window.URL.createObjectURL(blob);
      dom.href = _url;
      dom.download = decodeURI(fileName);
      dom.style.display = 'none';
      document.body.appendChild(dom);
      dom.click();
      dom.parentNode.removeChild(dom);
      window.URL.revokeObjectURL(_url);
      break;
    case 'word':
      exportTemplateApi({pId:params,type:'word'});
      break;
  }
};


</script>

<style scoped>
.pdf-viewer {
  display: flex;
  height: calc(100vh - 50px);
  background-color: rgba(0, 0, 0, 0.7);
  padding-top:10px;
}
.fixedToolBar{
    /* position: fixed;
    top: 0;
    left: 0; */
    width:100%;
    height:50px;
    line-height:50px;
    background-color: #635f5f;
    color:#fff;
    /* z-index:999; */
  }
  .download{
    outline: none;
    position: fixed;
    color:#fff;
    font-size:1.3rem;
    top:13px;
    right:15px;
    z-index:1000;
  }
.sidebar {
  width: 250px;
  padding: 20px;
  border-right: 1px solid #ccc;
  overflow-y: auto;
}

.sidebar h3 {
  margin-bottom: 10px;
}

.sidebar ul {
  list-style-type: none;
  padding: 0;
}

.sidebar li {
  text-align: center;
  width: 120px;
  margin:20px auto;
}

.sidebar a {
  text-decoration: none;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  flex-direction: column;
}

.sidebar img.thumbnail {
  width: 120px;
  border: 1px solid #ddd;
}

.pdf-container {
  flex-grow: 1;
  padding: 20px;
  overflow-y: auto;
}

.pdf-pages {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.sidebar img.active{
  border:5px solid rgb(153, 196, 238)!important;
}
</style>