<template>
    <div v-show="is_pdf">
        <el-row>
            <el-button-group>
                <el-button type="primary" :icon="ArrowLeft" @click="prePage">上一页</el-button>
                <el-button type="primary" @click="nextPage">
                    下一页<el-icon class="el-icon--right">
                        <ArrowRight />
                    </el-icon>
                </el-button>
            </el-button-group>
            <div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
            <el-container>
                <el-input type="number" v-model="pdf_page"></el-input>
                <el-button type="primary" @click="SetPdfPage" plain>页面跳转</el-button>
            </el-container>
        </el-row>
    </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted, watchEffect } from 'vue'
import { createLoadingTask } from "vue3-pdfjs/esm";
import { useCanvasImgStore } from '../store/CanvasImg';
import { usePdfProperty } from '../store/PdfProperty';
import { storeToRefs } from 'pinia'
import { fabric } from 'fabric';


import {
    ArrowLeft,
    ArrowRight
} from '@element-plus/icons-vue'

const c_img = useCanvasImgStore();
const { show_image, show_canvas, hide_canvas, fabric_canvas, input_file } = storeToRefs(c_img);
const pdf_property = usePdfProperty();
const { is_pdf, pdf_source, old_pdf_source } = storeToRefs(pdf_property);

const state = reactive({
    source: "", //预览pdf文件地址
    pageNum: 1, //当前页面
    numPages: 0, // 总页数
});

const pdf_page = ref(1);
const pdf_img: any = ref("")
let loadingTask: any;

onMounted(async () => {
    show_image.value = document.getElementById("show_img") as HTMLImageElement;
    show_canvas.value = document.getElementById("show_canvas") as HTMLCanvasElement;
    hide_canvas.value = document.getElementById("hide_canvas") as HTMLCanvasElement;
});

function prePage() {
    if (state.pageNum > 1) {
        state.pageNum -= 1;
        getPdfImage(state.pageNum);
    }
}

function nextPage() {
    if (state.pageNum < state.numPages) {
        state.pageNum += 1;
        getPdfImage(state.pageNum);
    }
}

function SetPdfPage() {
    if (pdf_page.value >= 1 && pdf_page.value <= state.numPages) {
        state.pageNum = Number(pdf_page.value);
        getPdfImage(state.pageNum);
    } else {
        alert('输入的pdf页面无效！')
    }
}

function blobToFile(blob: any, fileName: any) {
    blob.lastModifiedDate = new Date();
    blob.name = fileName;
    return blob;
}

async function convertCanvasToFile(canvas: HTMLCanvasElement, fileName: any) {
    // 将 Canvas 转为 Blob 对象
    const blob = await new Promise(resolve => canvas.toBlob(blob => {
        resolve(blob);
    }, pdf_img.value.type, 1.0));
    // 手动构造 File 对象
    let file = null;
    try {
        file = new File([pdf_img.value], fileName, { type: pdf_img.value.type });
    } catch (e) {
        // Safari 浏览器不支持直接通过 new File() 创建文件对象，需要手动构造
        const rawFile = blobToFile(blob, fileName);
        file = Object.assign(rawFile, { lastModifiedDate: new Date(), name: fileName });
    }
    return file;
}

function getPdfImage(index: number) {
    loadingTask.promise.then((pdf: any) => {
        state.numPages = pdf.numPages;
        pdf.getPage(index).then((page: any) => {
            const viewport = page.getViewport({ scale: 2.0 })
            hide_canvas.value.height = viewport.height;
            hide_canvas.value.width = viewport.width;
            show_canvas.value.height = viewport.height;
            show_canvas.value.width = viewport.width;
            const destWidth = 398;
            hide_canvas.value.style.width = destWidth + 'px';

            hide_canvas.value.style.height = destWidth * (viewport.height / viewport.width) + 'px';
            show_canvas.value.style.width = destWidth + 'px';

            show_canvas.value.style.height = destWidth * (viewport.height / viewport.width) + 'px';
            const ctx = hide_canvas.value.getContext('2d');
            page.render({
                canvasContext: ctx,
                viewport,
            });
            hide_canvas.value.toBlob(function (blob: any) {
                pdf_img.value = dataURLtoBlob(hide_canvas.value.toDataURL('images/png', 1.0))
                show_image.value.src = hide_canvas.value.toDataURL('images/png', 1.0);
                show_image.value.onload = () => {
                    show_canvas.value.width = show_image.value.width;
                    show_canvas.value.height = show_image.value.height;
                    convertCanvasToFile(hide_canvas.value, "pdf.png").then(result => {
                        if (is_pdf.value == true) {
                            input_file.value = result;
                        }
                    });
                    if (fabric_canvas.value != null) {
                        fabric_canvas.value.dispose();
                        fabric_canvas.value = null;
                    }
                    fabric_canvas.value = new fabric.Canvas(show_canvas.value);
                    fabric_canvas.value.clear()
                }
            });
        })
    });
}

function dataURLtoBlob(dataURL: any) {
    var arr = dataURL.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], { type: mime });
}

function initPdf(source: any) {
    state.pageNum = 1;
    state.source = source;
    loadingTask = createLoadingTask(state.source);
    getPdfImage(state.pageNum);
}

watchEffect(() => {
    if (old_pdf_source.value != pdf_source.value && is_pdf.value == true) {
        old_pdf_source.value = pdf_source.value;
        state.source = pdf_source.value; // 更新 source 变量
        initPdf(pdf_source.value); // 调用 initPdf 方法重新加载 PDF 文件
    }
});
</script>