import { DOCS_PAGE_GAP_PX } from "@/lib/drive/docs-page-layout-constants"
import type { DocsExportSnapshot } from "@/lib/drive/docs-export-snapshot"
import { prepareDocsPrintEnvironment } from "@/lib/drive/docs-print"
import { exportFileName } from "@/lib/drive/docs-export-download"

function downloadBlob(blob: Blob, fileName: string) {
  const url = URL.createObjectURL(blob)
  const anchor = document.createElement("a")
  anchor.href = url
  anchor.download = fileName
  anchor.click()
  URL.revokeObjectURL(url)
}

export async function exportDocsToPdf(snapshot: DocsExportSnapshot): Promise<void> {
  const cleanup = await prepareDocsPrintEnvironment(snapshot, "pdf-capture")

  try {
    const stack = snapshot.getPageStackElement()
    if (!stack) throw new Error("Page stack introuvable")

    const canvasHost = stack.closest(".ultidrive-docs-canvas") as HTMLElement | null
    if (!canvasHost) throw new Error("Canvas introuvable")

    const pageHeight = Number(stack.dataset.docsPageHeight ?? snapshot.pageLayout.heightPx)
    const pageWidth = Number(stack.dataset.docsPageWidth ?? snapshot.pageLayout.widthPx)
    const pageCount = snapshot.pageCount

    const [{ default: html2canvas }, { jsPDF }] = await Promise.all([
      import("html2canvas"),
      import("jspdf"),
    ])

    const pdf = new jsPDF({
      orientation: pageWidth > pageHeight ? "landscape" : "portrait",
      unit: "mm",
      format: [
        snapshot.pageLayout.format.widthMm,
        snapshot.pageLayout.format.heightMm,
      ],
    })

    const hostRect = canvasHost.getBoundingClientRect()
    const stackRect = stack.getBoundingClientRect()

    for (let pageIndex = 0; pageIndex < pageCount; pageIndex += 1) {
      const yOffset = pageIndex * (pageHeight + DOCS_PAGE_GAP_PX)
      const canvas = await html2canvas(canvasHost, {
        backgroundColor: "#ffffff",
        scale: 2,
        useCORS: true,
        logging: false,
        width: pageWidth,
        height: pageHeight,
        x: stackRect.left - hostRect.left,
        y: stackRect.top - hostRect.top + yOffset,
        windowWidth: canvasHost.scrollWidth,
        windowHeight: canvasHost.scrollHeight,
      })

      const imgData = canvas.toDataURL("image/jpeg", 0.92)
      if (pageIndex > 0) pdf.addPage()
      pdf.addImage(
        imgData,
        "JPEG",
        0,
        0,
        snapshot.pageLayout.format.widthMm,
        snapshot.pageLayout.format.heightMm
      )
    }

    const blob = pdf.output("blob")
    downloadBlob(blob, exportFileName(snapshot.sourceName, "pdf"))
  } finally {
    cleanup()
  }
}
