<template>
  <div class="modal">
    <div class="leftModalList">
      <div class="title"> 文件名称 </div>
      <div class="list">
        <a-tree
          v-model:selectedKeys="selectedKeys"
          showIcon
          defaultExpandAll
          :tree-data="props.fileList"
          :fieldNames="{ key: 'filePath', title: 'fileName' }"
        >
          <template #title="{ fileName, isDirectory, filePath, netPath }">
            <div @click="chooseFile(isDirectory, filePath, netPath)">
              <FolderOpenOutlined v-if="isDirectory" />
              <FileImageOutlined
                v-else-if="
                  filePath.includes('.jpg') ||
                  filePath.includes('.jpeg') ||
                  filePath.includes('.png')
                "
              />
              <FileWordOutlined v-else-if="filePath.includes('.doc')" />
              <FilePdfOutlined v-else-if="filePath.includes('.pdf')" />
              {{ fileName }}
            </div>
          </template>
        </a-tree>
      </div>
    </div>
    <div class="rightModalShow">
      <!-- 图片 -->
      <img
        v-if="nowFile.type == 'image'"
        :src="nowFile.url"
        :width="imageWidth"
        :height="imageHeight"
      />
      <!-- word -->
      <div class="docx-viewer" v-if="['word'].includes(nowFile.type)">
        <div v-if="loading">加载中...</div>
        <div v-else-if="error" style="color: red">
          {{ error }}
        </div>
        <div v-else v-html="wordHtmlContent"></div>
      </div>
      <!-- pdf -->
      <div class="pdfMenuList" v-if="['pdf'].includes(nowFile.type)">
        <canvas
          :class="menu.id == pdfPageNum ? 'menu_choose' : 'menu'"
          v-for="menu in pdfMenuList"
          :key="menu.id"
          :id="`menu${menu.id}`"
          style="border: 1px solid #000000; border-radius: 4px"
          @click="render(menu.id)"
        />
      </div>
      <div class="pdf-viewer" v-if="['pdf'].includes(nowFile.type)">
        <canvas id="pdf-canvas" style="border: 1px solid #ddd; border-radius: 4px"></canvas>
      </div>
    </div>
    <div class="page-tool" v-if="['pdf'].includes(nowFile.type)">
      <div class="page-tool-item-1" @click="lastPage">上一页</div>
      <div class="page-tool-item-1" @click="nextPage">下一页</div>
      <div class="page-tool-item-1">{{ pdfPageNum }}/{{ pdfTotalNums }}</div>
      <div class="page-tool-item" @click="pageZoomOut">放大</div>
      <div class="page-tool-item" @click="pageZoomIn">缩小</div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, reactive, watch, nextTick, onMounted } from 'vue';
  import * as mammoth from 'mammoth';
  import { createLoadingTask } from 'vue3-pdfjs/esm';
  import {
    FolderOpenOutlined,
    FileImageOutlined,
    FileWordOutlined,
    FilePdfOutlined,
  } from '@ant-design/icons-vue';
  const props = defineProps(['fileList']);
  const emits = defineEmits(['closeModal']);

  const nowFile: any = ref({});
  const selectedKeys: any = ref([]);
  onMounted(() => {
    let flag = true;
    props.fileList.forEach((item) => {
      if (flag && item.children.length > 0) {
        flag = false;
        let children = item.children[0];
        selectedKeys.value.push(children.filePath);
        chooseFile(children.isDirectory, children.filePath, children.netPath);
      }
    });
  });
  function chooseFile(isDirectory, filePath, netPath) {
    if (!isDirectory) {
      let type = '';
      if (filePath.includes('.jpg') || filePath.includes('.jpeg') || filePath.includes('.png')) {
        type = 'image';
      }
      if (filePath.includes('.doc')) {
        type = 'word';
      }
      if (filePath.includes('.pdf')) {
        type = 'pdf';
      }
      nowFile.value = {
        type: type,
        url: 'http://192.168.10.106:9641/' + netPath,
        // url: filePath,
      };
      watchUrl();
    }
  }

  function watchUrl() {
    if (nowFile.value.type == 'image') {
      const img = new Image();
      img.src = nowFile.value.url;
      img.onload = () => {
        if (img.height > 700) {
          imageHeight.value = 700;
          imageWidth.value = (700 / img.height) * img.width;
        }
      };
    }
    if (nowFile.value.type == 'word') {
      loadDocxFromUrl(nowFile.value.url);
    }
    if (nowFile.value.type == 'pdf') {
      loadPdfFromUrl(nowFile.value.url);
    }
  }

  // 图片
  const imageWidth = ref(1000);
  const imageHeight = ref(700);

  // word
  const wordHtmlContent = ref();
  const loading = ref(true);
  const error: any = ref(null);
  async function loadDocxFromUrl(docxUrl) {
    loading.value = true;
    error.value = null;
    try {
      // 1. 使用 fetch 获取 .docx 文件的 ArrayBuffer
      const response = await fetch(docxUrl);
      if (!response.ok) throw new Error('文件下载失败');
      const arrayBuffer = await response.arrayBuffer();
      // 2. 使用 mammoth 解析为 HTML
      const result = await mammoth.convertToHtml({ arrayBuffer });
      // 3. 获取转换后的 HTML 内容
      wordHtmlContent.value = result.value;
      // 可选：打印警告信息（如不支持的元素）
      if (result.messages.length > 0) {
        console.warn('mammoth 警告:', result.messages);
      }
    } catch (err) {
      error.value = '加载或解析文档失败：' + err.message;
    } finally {
      loading.value = false;
    }
  }

  // pdf --------------------------------------------------------------------------------
  let nowpdf: any = null;
  const pdfSource = ref();
  const pdfPageNum = ref(1);
  const pdfScale = ref(0.925);
  const pdfTotalNums = ref(0);

  // 目录
  const pdfMenuList: any = ref([]);

  function loadPdfFromUrl(pdfUrl) {
    pdfSource.value = nowFile.value.url;
    const loadingTask = createLoadingTask(pdfSource.value);
    loadingTask.promise.then((pdf) => {
      nowpdf = pdf;
      pdfTotalNums.value = pdf.numPages;
      render(1);
      setMenuList(pdf);
    });
  }

  async function setMenuList(pdf) {
    for (let i = 1; i < pdf.numPages; i++) {
      pdfMenuList.value.push({
        id: i,
      });
    }
    await nextTick(async () => {
      for (let i = 1; i < pdf.numPages; i++) {
        const page = await nowpdf.getPage(i);
        // 设置缩放
        const viewport = page.getViewport({ scale: 0.5 });
        // 获取 canvas
        const canvas = document.getElementById('menu' + i);
        const ctx = canvas.getContext('2d');
        // 设置 canvas 尺寸
        canvas.width = viewport.width;
        canvas.height = viewport.height;
        // 渲染页面
        await page.render({
          canvasContext: ctx,
          viewport,
        }).promise;
      }
    });
  }

  // pdf渲染
  async function render(num, id = 'pdf-canvas') {
    // 获取第 1 页
    const page = await nowpdf.getPage(num);
    pdfPageNum.value = num;
    // 调整目录滑动条的位置
    setScrollLeft();
    // 设置缩放
    const viewport = page.getViewport({ scale: pdfScale.value });
    // 获取 canvas
    const canvas = document.getElementById(id);
    const ctx = canvas.getContext('2d');
    // 设置 canvas 尺寸
    canvas.width = viewport.width;
    canvas.height = viewport.height;
    // 渲染页面
    await page.render({
      canvasContext: ctx,
      viewport,
    }).promise;
  }

  // 调整目录滑动条的位置
  function setScrollLeft() {
    const pdfMenuListDocument: any = document.querySelector('.pdfMenuList');
    if (pdfMenuListDocument) {
      let index = pdfMenuList.value.findIndex((item) => item.id == pdfPageNum.value);
      let length = pdfMenuList.value.length;
      if (index < 2) {
        pdfMenuListDocument.scrollTop = 0;
      } else if (index + 3 > length) {
        pdfMenuListDocument.scrollTop = 211 * length;
      } else {
        pdfMenuListDocument.scrollTop = 226 * (index - 1);
      }
    }
  }

  async function lastPage() {
    if (pdfPageNum.value > 1) {
      pdfPageNum.value -= 1;
      render(pdfPageNum.value);
    }
  }
  function nextPage() {
    if (pdfPageNum.value < pdfTotalNums.value) {
      pdfPageNum.value += 1;
      render(pdfPageNum.value);
    }
  }
  function pageZoomOut() {
    if (pdfScale.value < 2) {
      pdfScale.value += 0.075;
      render(pdfPageNum.value);
    }
  }
  function pageZoomIn() {
    if (pdfScale.value > 0.85) {
      pdfScale.value -= 0.075;
      render(pdfPageNum.value);
    }
  }
</script>
<style lang="less" scoped>
  .modal {
    width: 100%;
    height: 100%;

    // // 页面不能被选中
    // -webkit-user-select: none; /* Safari */
    // -moz-user-select: none; /* Firefox */
    // -ms-user-select: none; /* IE/Edge */
    // user-select: none;

    display: inline-flex;
  }

  .leftModalList {
    position: relative;
    height: 100%;
    min-height: 800px;
    width: 20%;
    padding: 20px;
    margin: 20px;
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);

    .title {
      position: absolute;
      top: 0px;
      width: 100%;
      height: 10%;
      font-size: 15px;

      display: flex;
      align-items: center;
      justify-content: flex-start;
    }
    .list {
      margin-top: 40px;
      width: 100%;
      max-height: 720px;
      overflow-y: auto;
    }
  }
  .rightModalShow {
    position: relative;
    height: 100%;
    min-height: 800px;
    width: calc(80% - 100px);
    padding: 40px;
    margin: 20px;
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);

    display: flex;
    align-items: center;
    justify-content: center;

    overflow-y: auto;

    .pdfMenuList {
      position: absolute;
      top: 10px;
      left: 10px;
      height: calc(100% - 20px);
      width: 190px;
      display: block;

      overflow-y: auto;

      .menu_choose {
        width: 160px;
        height: 200px;
        margin: 10px;
        outline: 3px solid #b3e0f7;
      }

      .menu {
        width: 160px;
        height: 200px;
        margin: 10px;
      }
    }
  }

  .docx-viewer {
    font-family: Arial, sans-serif;
    line-height: 1.6;
    max-width: 1000px;
    max-height: 700px;
    width: 100%;
    height: 100%;
  }
  .pdf-viewer {
    font-family: Arial, sans-serif;
    line-height: 1.6;
    max-width: 1000px;
    max-height: 700px;
    width: 100%;
    height: 100%;

    display: flex;
    align-items: center;
    justify-content: center;
  }

  .pdf-preview {
    position: relative;
    height: 100vh;
    padding: 20px 0;
    box-sizing: border-box;
    background-color: #e9e9e9;
    overflow-y: auto;
  }
  .vue-pdf-embed {
    text-align: center;
    width: 515px;
    border: 1px solid #e5e5e5;
    margin: 0 auto;
    box-sizing: border-box;
  }

  .page-title {
    position: absolute;
    top: 10px;
    left: 10px;
    color: #000000;
    font-weight: 700;
  }

  .page-tool {
    // 页面不能被选中
    -webkit-user-select: none; /* Safari */
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* IE/Edge */
    user-select: none;

    position: absolute;
    bottom: 35px;
    right: -40px;
    display: flex;
    align-items: center;
    background: rgb(66, 66, 66);
    color: white;
    border-radius: 19px;
    z-index: 100;
    cursor: pointer;
    margin-left: 50%;
    transform: translateX(-50%);

    .page-tool-item-1 {
      padding: 8px 15px;
      padding-left: 10px;
      width: 70px;
      cursor: pointer;
    }
    .page-tool-item {
      padding: 8px 15px;
      padding-left: 10px;
      width: 60px;
      cursor: pointer;
    }
  }
</style>
