<template>
  <el-dialog
    v-model="visible"
    :title="dialogTitle"
    width="80%"
    top="5vh"
    :destroy-on-close="true"
    @closed="onDialogClosed"
  >
    <div class="pdf-container" ref="pdfContainerRef">
      <canvas
        v-for="pageIndex in pdfPages"
        :id="`pdf-canvas-${pageIndex}`"
        :key="pageIndex"
      ></canvas>
    </div>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, nextTick } from "vue";
import * as PDFJS from "pdfjs-dist";
import pdfWorker from 'pdfjs-dist/build/pdf.worker.js?worker';

PDFJS.GlobalWorkerOptions.workerPort = new pdfWorker();

const visible = ref(false);
const dialogTitle = ref("PDF 预览");
const pdfDoc: { value: any } = ref(null);
const pdfPages = ref(0);
const pdfContainerRef = ref<HTMLElement | null>(null);
const pdfScale = ref(1.5);

// 渲染单页
const renderPage = async (num: number) => {
  if (!pdfDoc.value) return;
  const page = await pdfDoc.value.getPage(num);
  page.cleanup();

  if (pdfContainerRef.value) {
    pdfScale.value = pdfContainerRef.value.clientWidth / page.view[2];
  }

  const canvas = document.getElementById(`pdf-canvas-${num}`) as HTMLCanvasElement | null;
  if (canvas) {
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    const dpr = window.devicePixelRatio || 1;
    const bsr =
      (ctx as any).webkitBackingStorePixelRatio ||
      (ctx as any).mozBackingStorePixelRatio ||
      (ctx as any).msBackingStorePixelRatio ||
      (ctx as any).oBackingStorePixelRatio ||
      (ctx as any).backingStorePixelRatio ||
      1;
    const ratio = dpr / bsr;

    const viewport = page.getViewport({ scale: pdfScale.value });

    canvas.width = viewport.width * ratio;
    canvas.height = viewport.height * ratio;
    canvas.style.width = viewport.width + "px";
    canvas.style.height = viewport.height + "px";

    ctx.setTransform(ratio, 0, 0, ratio, 0, 0);

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

    await page.render(renderContext).promise;

    if (num < pdfPages.value) {
      renderPage(num + 1);
    }
  }
};

// 加载 PDF 文件
const loadFile = async (url: string) => {
  try {
    console.log("loadFile",url)
    const loadingTask = PDFJS.getDocument(url);
    const pdf = await loadingTask.promise;
    pdf.loadingParams.disableAutoFetch = true;
    pdf.loadingParams.disableStream = true;
    pdfDoc.value = pdf;
    pdfPages.value = pdf.numPages;

    await nextTick();
    renderPage(1);
  } catch (error) {
    console.warn("[PdfPreviewDialog] loadFile error:", error);
  }
};

// 关闭对话框时清理
const onDialogClosed = () => {
  pdfDoc.value?.destroy();
  pdfDoc.value = null;
  pdfPages.value = 0;
  pdfScale.value = 1.5;
};

// 暴露 open 方法
function open(title: string, url: string) {
  console.log(title, url);
  dialogTitle.value = title || "PDF 预览";
  visible.value = true;
  loadFile(url);
}

defineExpose({ open });

</script>

<style scoped>
.pdf-container {
  height: 70vh;
  overflow-y: auto;
  overflow-x: hidden;
}
canvas {
  display: block;
  margin: 8px auto;
  box-shadow: 0 0 5px rgb(0 0 0 / 0.15);
}
</style>
