// ==================== ZUGFeRD PDF/A-3 EMBEDDING ====================
// Nimmt ein bestehendes PDF (pdfkit, mit eingebetteten Fonts) und macht daraus
// ein hybrides ZUGFeRD-PDF: factur-x.xml als AF /Data einbetten, sRGB-
// OutputIntent, XMP-Metadaten (PDF/A-3B + Factur-X-Extension-Schema).
//
// WICHTIG: Vor produktivem Einsatz gegen einen ZUGFeRD-/Factur-X-Validator
// prüfen. Feinheiten der PDF/A-3-Konformität (z.B. Trailer-ID, XMP-Details)
// können nach dem ersten Validator-Lauf noch nachgezogen werden müssen.

import fs from 'fs';
import path from 'path';
import { PDFDocument, AFRelationship, PDFName, PDFString } from 'pdf-lib';

const ICC_PATH = path.join(process.cwd(), 'assets', 'icc', 'sRGB_IEC61966_2_1.icc');

function xmpDate(d: Date): string {
  return d.toISOString().replace(/\.\d{3}Z$/, 'Z');
}

function buildXmp(title: string, date: Date): string {
  const d = xmpDate(date);
  return `<?xpacket begin="﻿" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/">
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description rdf:about="" xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/">
      <pdfaid:part>3</pdfaid:part>
      <pdfaid:conformance>B</pdfaid:conformance>
    </rdf:Description>
    <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
      <dc:title><rdf:Alt><rdf:li xml:lang="x-default">${title.replace(/[<>&]/g, '')}</rdf:li></rdf:Alt></dc:title>
    </rdf:Description>
    <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/">
      <xmp:CreatorTool>OpenCRM</xmp:CreatorTool>
      <xmp:CreateDate>${d}</xmp:CreateDate>
      <xmp:ModifyDate>${d}</xmp:ModifyDate>
    </rdf:Description>
    <rdf:Description rdf:about="" xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#">
      <pdfaExtension:schemas>
        <rdf:Bag>
          <rdf:li rdf:parseType="Resource">
            <pdfaSchema:schema>Factur-X PDFA Extension Schema</pdfaSchema:schema>
            <pdfaSchema:namespaceURI>urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#</pdfaSchema:namespaceURI>
            <pdfaSchema:prefix>fx</pdfaSchema:prefix>
            <pdfaSchema:property>
              <rdf:Seq>
                <rdf:li rdf:parseType="Resource"><pdfaProperty:name>DocumentFileName</pdfaProperty:name><pdfaProperty:valueType>Text</pdfaProperty:valueType><pdfaProperty:category>external</pdfaProperty:category><pdfaProperty:description>Name des eingebetteten XML</pdfaProperty:description></rdf:li>
                <rdf:li rdf:parseType="Resource"><pdfaProperty:name>DocumentType</pdfaProperty:name><pdfaProperty:valueType>Text</pdfaProperty:valueType><pdfaProperty:category>external</pdfaProperty:category><pdfaProperty:description>INVOICE</pdfaProperty:description></rdf:li>
                <rdf:li rdf:parseType="Resource"><pdfaProperty:name>Version</pdfaProperty:name><pdfaProperty:valueType>Text</pdfaProperty:valueType><pdfaProperty:category>external</pdfaProperty:category><pdfaProperty:description>Version des Factur-X-Profils</pdfaProperty:description></rdf:li>
                <rdf:li rdf:parseType="Resource"><pdfaProperty:name>ConformanceLevel</pdfaProperty:name><pdfaProperty:valueType>Text</pdfaProperty:valueType><pdfaProperty:category>external</pdfaProperty:category><pdfaProperty:description>Konformitaetslevel</pdfaProperty:description></rdf:li>
              </rdf:Seq>
            </pdfaSchema:property>
          </rdf:li>
        </rdf:Bag>
      </pdfaExtension:schemas>
    </rdf:Description>
    <rdf:Description rdf:about="" xmlns:fx="urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#">
      <fx:DocumentType>INVOICE</fx:DocumentType>
      <fx:DocumentFileName>factur-x.xml</fx:DocumentFileName>
      <fx:Version>1.0</fx:Version>
      <fx:ConformanceLevel>EN 16931</fx:ConformanceLevel>
    </rdf:Description>
  </rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>`;
}

export async function embedZugferd(
  basePdf: Buffer,
  xml: string,
  meta: { title: string; date: Date },
): Promise<Buffer> {
  const pdfDoc = await PDFDocument.load(basePdf);

  // 1) XML als Associated File (AF /Data) einbetten.
  await pdfDoc.attach(Buffer.from(xml, 'utf-8'), 'factur-x.xml', {
    mimeType: 'text/xml',
    description: 'Factur-X/ZUGFeRD Rechnungsdaten',
    afRelationship: AFRelationship.Data,
    creationDate: meta.date,
    modificationDate: meta.date,
  });

  // 2) Dokument-Info.
  pdfDoc.setTitle(meta.title);
  pdfDoc.setProducer('OpenCRM');
  pdfDoc.setCreator('OpenCRM');
  pdfDoc.setCreationDate(meta.date);
  pdfDoc.setModificationDate(meta.date);

  // 3) OutputIntent (sRGB) – Pflicht für PDF/A.
  const iccBytes = fs.readFileSync(ICC_PATH);
  const iccStream = pdfDoc.context.stream(iccBytes, { N: 3 });
  const iccRef = pdfDoc.context.register(iccStream);
  const outputIntent = pdfDoc.context.obj({
    Type: 'OutputIntent',
    S: 'GTS_PDFA1',
    OutputConditionIdentifier: PDFString.of('sRGB'),
    Info: PDFString.of('sRGB IEC61966-2.1'),
    DestOutputProfile: iccRef,
  });
  const oiRef = pdfDoc.context.register(outputIntent);
  pdfDoc.catalog.set(PDFName.of('OutputIntents'), pdfDoc.context.obj([oiRef]));

  // 4) XMP-Metadaten (unkomprimiert, /Metadata /XML).
  const xmp = buildXmp(meta.title, meta.date);
  const metadataStream = pdfDoc.context.stream(Buffer.from(xmp, 'utf-8'), {
    Type: 'Metadata',
    Subtype: 'XML',
  });
  const metaRef = pdfDoc.context.register(metadataStream);
  pdfDoc.catalog.set(PDFName.of('Metadata'), metaRef);

  // PDF/A: klassische XRef-Tabelle statt Object-Streams (validator-freundlicher).
  const out = await pdfDoc.save({ useObjectStreams: false });
  return Buffer.from(out);
}
