import * as pdfjsLib from "pdfjs-dist"
import pdfWorkerSrc from "pdfjs-dist/build/pdf.worker.mjs?url"

import { PAGE_WIDTH } from "../../../utils/exam-canvas/model"

pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorkerSrc

export interface PdfPageImage {
  pageNumber: number
  src: string
  width: number
  height: number
}

export async function loadPdfPageImages(
  pdfBytes: ArrayBuffer,
  targetWidth = PAGE_WIDTH,
  onPageReady?: (pages: PdfPageImage[]) => void,
): Promise<PdfPageImage[]> {
  const pdf = await pdfjsLib.getDocument({ data: new Uint8Array(pdfBytes) }).promise
  const pages: PdfPageImage[] = []
  // Reuse a single canvas across all pages to avoid allocating ~120 MB of canvas memory
  // for a typical 36-page exam paper.
  const canvas = document.createElement("canvas")

  for (let pageNumber = 1; pageNumber <= pdf.numPages; pageNumber += 1) {
    const page = await pdf.getPage(pageNumber)
    const baseViewport = page.getViewport({ scale: 1 })
    const scale = targetWidth / baseViewport.width
    const viewport = page.getViewport({ scale })
    canvas.width = Math.ceil(viewport.width)
    canvas.height = Math.ceil(viewport.height)
    const context = canvas.getContext("2d")
    if (!context) throw new Error("Unable to create PDF render canvas")
    context.clearRect(0, 0, canvas.width, canvas.height)
    await page.render({ canvasContext: context, viewport }).promise
    pages.push({
      pageNumber,
      src: canvas.toDataURL("image/png"),
      width: canvas.width,
      height: canvas.height,
    })
    onPageReady?.([...pages])
  }

  return pages
}
