// server-only — never import from client components
// This module uses pdfjs-dist legacy build in Node.js fake-worker mode (no browser worker).
// The client components (PdfViewer.tsx, PreviewModal.tsx) set workerSrc independently.

// @ts-ignore — legacy .mjs build; types re-exported from main pdfjs-dist declaration
import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist/legacy/build/pdf.mjs';
import { createCanvas } from '@napi-rs/canvas';
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';

// pdfjs-dist 5.x fake-worker mode: must point workerSrc to the actual worker file so
// _setupFakeWorkerGlobal can `await import(this.workerSrc)` in Node.js.
// Empty string is falsy → PDFWorker.workerSrc getter throws before the import runs.
GlobalWorkerOptions.workerSrc = `file://${join(process.cwd(), 'node_modules/pdfjs-dist/legacy/build/pdf.worker.mjs')}`;

/** A rendered page image, ready to send to GPT-4o vision. */
export interface PageImage {
  page: number;       // 1-indexed
  width: number;      // original PDF width in points (scale 1.0)
  height: number;     // original PDF height in points (scale 1.0)
  base64: string;     // JPEG base64 of the rendered page (no data: prefix)
}

// Legacy type alias kept for callers that still reference PageText
export type PageText = PageImage;

const RENDER_SCALE = 1.5;  // 72dpi × 1.5 = 108dpi — good for vision without huge payloads

export async function extractPdfText(filePath: string): Promise<PageImage[]> {
  const data = new Uint8Array(await readFile(filePath));
  const pdf = await getDocument({ data }).promise;
  const pages: PageImage[] = [];

  for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
    const page = await pdf.getPage(pageNum);
    const viewport = page.getViewport({ scale: RENDER_SCALE });

    // Create an @napi-rs/canvas and render the PDF page into it
    const canvas = createCanvas(Math.round(viewport.width), Math.round(viewport.height));
    const ctx = canvas.getContext('2d');

    // @ts-ignore — @napi-rs/canvas context is compatible at runtime but types diverge
    await page.render({ canvasContext: ctx, viewport }).promise;

    // Stamp a visible page number in the top-left corner so GPT-4o can correlate
    // each image to the correct page number when multiple images are sent in one prompt.
    const label = `PAGE ${pageNum}`;
    const fontSize = Math.round(viewport.height * 0.025);
    ctx.fillStyle = 'rgba(220,30,30,0.85)';
    ctx.fillRect(0, 0, fontSize * (label.length * 0.65), fontSize * 1.5);
    ctx.fillStyle = '#ffffff';
    ctx.font = `bold ${fontSize}px sans-serif`;
    ctx.fillText(label, 4, fontSize * 1.15);

    const jpegBuffer = canvas.toBuffer('image/jpeg' as never, 85);

    pages.push({
      page: pageNum,
      width: page.getViewport({ scale: 1.0 }).width,
      height: page.getViewport({ scale: 1.0 }).height,
      base64: jpegBuffer.toString('base64'),
    });
  }

  return pages;
}
