import refreshTokenHelper from "../../utils/refreshTokenHelper"
import forceLogoutHelper from "../../utils/forceLogoutHelper"
import errorHandlingHelper from "../../utils/errorHandlingHelper"
import { PDFDocument } from 'pdf-lib'

const handleFunc = async (event: any, authToken: any = null) => {
  const config = useRuntimeConfig()
  const token = authToken ?? await getTokenHelper(event)
  const body = await readBody(event)
  const ids: number[] = body?.ids || []
  const type = body?.type || 'PDF'

  if (!ids.length) {
    return { status: 400, message: 'No invoice IDs provided' }
  }

  // Fetch all PDFs in parallel
  const pdfPromises = ids.map(async (id) => {
    try {
      const res: any = await event.context.fetch(`models/c_invoice/${id}/print?$report_type=${type}`, 'GET', token, null)
      return res?.reportFile || null
    } catch (err) {
      console.error(`Failed to fetch PDF for invoice ${id}:`, err)
      return null
    }
  })

  const pdfResults = await Promise.all(pdfPromises)
  const validPdfs = pdfResults.filter(pdf => pdf !== null)

  if (!validPdfs.length) {
    return { status: 404, message: 'No PDFs could be generated' }
  }

  // Merge all PDFs into one
  const mergedPdf = await PDFDocument.create()

  for (const base64Pdf of validPdfs) {
    try {
      const pdfBytes = Buffer.from(base64Pdf, 'base64')
      const pdf = await PDFDocument.load(pdfBytes)
      const pages = await mergedPdf.copyPages(pdf, pdf.getPageIndices())
      pages.forEach(page => mergedPdf.addPage(page))
    } catch (err) {
      console.error('Failed to merge PDF:', err)
    }
  }

  const mergedPdfBytes = await mergedPdf.save()
  const mergedBase64 = Buffer.from(mergedPdfBytes).toString('base64')

  return {
    reportFile: mergedBase64,
    totalInvoices: validPdfs.length,
    requestedInvoices: ids.length
  }
}

export default defineEventHandler(async (event) => {
  let data: any = {}

  try {
    data = await handleFunc(event)
  } catch(err: any) {
    try {
      let authToken: any = await refreshTokenHelper(event)
      data = await handleFunc(event, authToken)
    } catch(error) {
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      forceLogoutHelper(event, data)
    }
  }

  return data
})
