/**
 * PDF conversion utilities loaded on demand so headless startup
 * does not require ESM-only pdf-to-img at module load time.
 */
import { createRequire } from 'node:module'
import { pathToFileURL } from 'node:url'

const require = createRequire(import.meta.url)

// Dynamic import() from pkg snapshot bytecode throws "Invalid host defined options"
// (nodejs/node#43663). Use require() for CJS packages in pkg; ESM packages need
// --no-bytecode on the pkg build so file-URL import() works.
async function importPackage(name) {
  const packagePath = require.resolve(name)

  if (typeof process.pkg !== 'undefined') {
    try {
      return require(packagePath)
    } catch (error) {
      if (error?.code !== 'ERR_REQUIRE_ESM') {
        throw error
      }
    }
  }

  return import(pathToFileURL(packagePath).href)
}

function resolveDefault(module) {
  return module?.default ?? module
}

export async function convertPDFToImage(pdfInput, options = {}) {
  const [pdfToImgModule, sharpModule] = await Promise.all([
    importPackage('pdf-to-img'),
    importPackage('sharp')
  ])
  const { pdf } = pdfToImgModule
  const sharp = resolveDefault(sharpModule)

  try {
    const { width, height, page_numbers, scale = 2, ...pdfOnlyOptions } =
      options

    const pdfOptions = {
      scale,
      ...pdfOnlyOptions
    }

    const document = await pdf(pdfInput, pdfOptions)
    const outputImages = []

    if (
      page_numbers &&
      Array.isArray(page_numbers) &&
      page_numbers.length > 0
    ) {
      for (const pageNum of page_numbers) {
        let image = await document.getPage(pageNum)

        if (width || height) {
          const resizeOptions = {}
          if (width) resizeOptions.width = width
          if (height) resizeOptions.height = height
          image = await sharp(image).resize(resizeOptions).toBuffer()
        }

        outputImages.push(image)
      }
    } else {
      for await (const image of document) {
        let processedImage = image

        if (width || height) {
          const resizeOptions = {}
          if (width) resizeOptions.width = width
          if (height) resizeOptions.height = height
          processedImage = await sharp(image)
            .resize(resizeOptions)
            .toBuffer()
        }

        outputImages.push(processedImage)
      }
    }

    return outputImages
  } catch (error) {
    console.error('Error converting PDF to image:', error)
    throw error
  }
}
