import { PDFDocument, AFRelationship } from 'pdf-lib';
import type { IPdf } from '../../interfaces/common.js';

/**
 * Class for embedding XML into PDF files
 */
export class PDFEmbedder {
  /**
   * Embeds XML into a PDF
   * @param pdfBuffer PDF buffer
   * @param xmlContent XML content to embed
   * @param filename Filename for the embedded XML
   * @param description Description for the embedded XML
   * @returns Modified PDF buffer
   */
  public async embedXml(
    pdfBuffer: Uint8Array | Buffer,
    xmlContent: string,
    filename: string = 'invoice.xml',
    description: string = 'XML Invoice'
  ): Promise<Uint8Array> {
    try {
      // Load the PDF
      const pdfDoc = await PDFDocument.load(pdfBuffer);

      // Convert the XML string to a Uint8Array
      const xmlBuffer = new TextEncoder().encode(xmlContent);

      // Make sure filename is lowercase (as required by documentation)
      filename = filename.toLowerCase();

      // Use pdf-lib's .attach() to embed the XML
      pdfDoc.attach(xmlBuffer, filename, {
        mimeType: 'text/xml',
        description: description,
        creationDate: new Date(),
        modificationDate: new Date(),
        afRelationship: AFRelationship.Alternative,
      });

      // Save the modified PDF
      const modifiedPdfBytes = await pdfDoc.save();

      return modifiedPdfBytes;
    } catch (error) {
      console.error('Error embedding XML into PDF:', error);
      throw error;
    }
  }

  /**
   * Creates an IPdf object with embedded XML
   * @param pdfBuffer PDF buffer
   * @param xmlContent XML content to embed
   * @param filename Filename for the embedded XML
   * @param description Description for the embedded XML
   * @param pdfName Name for the PDF
   * @param pdfId ID for the PDF
   * @returns IPdf object with embedded XML
   */
  public async createPdfWithXml(
    pdfBuffer: Uint8Array | Buffer,
    xmlContent: string,
    filename: string = 'invoice.xml',
    description: string = 'XML Invoice',
    pdfName: string = 'invoice.pdf',
    pdfId: string = `invoice-${Date.now()}`
  ): Promise<IPdf> {
    const modifiedPdfBytes = await this.embedXml(pdfBuffer, xmlContent, filename, description);

    return {
      name: pdfName,
      id: pdfId,
      metadata: {
        textExtraction: ''
      },
      buffer: modifiedPdfBytes
    };
  }
}
