/**
 * Branded LogYou contract (Fulfillment-Rahmenvertrag) PDF builder.
 * Layout/brand components (BRAND, header, footer, logos) are reused from
 * quotePdf.ts; all legal wording lives in contractTexts.ts.
 */
import { BRAND, buildBrandHeader, buildBrandFooter, getQuoteLogos } from './quotePdf'
import { CONTRACT_TEXTS, isContractSectionOn } from './contractTexts'

/** Signature data rendered into the customer signature block (digital signing). */
export interface ContractSignature {
  imageDataUrl: string
  name: string
  position?: string
  company?: string
  street?: string
  zip?: string
  city?: string
  country?: string
  ustId?: string
  email?: string
  phone?: string
  signedAt: string          // ISO datetime
  ip?: string
  userAgent?: string
  token?: string
  documents?: Array<{ title: string; filename: string; sha256: string; version?: number }>
  /** Exact wording of every checkbox the signer ticked, with timestamps (evidence). */
  acceptances?: Array<{ key: string; text: string; acceptedAt: string }>
}

const formatDateTimeLocal = (iso: string, language: string): string => {
  const d = new Date(iso)
  if (isNaN(d.getTime())) return iso
  const dd = String(d.getDate()).padStart(2, '0')
  const mm = String(d.getMonth() + 1).padStart(2, '0')
  const hh = String(d.getHours()).padStart(2, '0')
  const mi = String(d.getMinutes()).padStart(2, '0')
  return language === 'en' ? `${d.getFullYear()}-${mm}-${dd} ${hh}:${mi}` : `${dd}.${mm}.${d.getFullYear()} ${hh}:${mi}`
}

const fmt = (template: string, vars: Record<string, any>): string =>
  String(template).replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? ''))

const formatDateLocal = (iso: string, language: string): string => {
  if (!iso) return '—'
  const d = new Date(iso)
  if (isNaN(d.getTime())) return iso
  const dd = String(d.getDate()).padStart(2, '0')
  const mm = String(d.getMonth() + 1).padStart(2, '0')
  return language === 'en' ? `${d.getFullYear()}-${mm}-${dd}` : `${dd}.${mm}.${d.getFullYear()}`
}

export const sanitizeContractFilename = (company: string, language: string, date?: string): string => {
  const safe = String(company || 'Kunde')
    .replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue')
    .replace(/Ä/g, 'Ae').replace(/Ö/g, 'Oe').replace(/Ü/g, 'Ue')
    .replace(/ß/g, 'ss')
    .replace(/[^A-Za-z0-9-_ ]/g, '')
    .trim()
    .replace(/\s+/g, '-') || 'Kunde'
  const d = date || new Date().toISOString().slice(0, 10)
  const prefix = language === 'en' ? 'Contract' : 'Vertrag'
  return `${prefix}_LogYou_${safe}_${d}.pdf`
}

export const buildContractDocDefinition = (payload: any, logos: { light: string | null; dark: string | null }, signature: ContractSignature | null = null) => {
  const language = payload?.meta?.language === 'en' ? 'en' : 'de'
  const T = CONTRACT_TEXTS[language]
  const c = payload.customer || {}
  const a = payload.assumptions || {}
  const st = a.storage || {}
  const ct = payload.contract || {}
  // Per-contract section toggles (absent = on).
  const on = (key: string) => isContractSectionOn(ct.sections, key)
  const dateIso = payload?.meta?.date || new Date().toISOString().slice(0, 10)

  // Placeholder values substituted into the legal texts
  // Notice period: 0 = terminable any time to month end, no notice. The 1-month
  // special termination right in the first 3 months only makes sense with a
  // longer regular notice period.
  const noticeMonths = Number.isFinite(Number(ct.noticeMonths)) && ct.noticeMonths !== '' && ct.noticeMonths !== null && ct.noticeMonths !== undefined ? Number(ct.noticeMonths) : 0
  const noticeClause = language === 'en'
    ? (noticeMonths > 0 ? `with ${noticeMonths} month${noticeMonths === 1 ? '' : 's'}' notice` : 'at any time without notice period')
    : (noticeMonths > 0 ? `mit einer Frist von ${noticeMonths} Monat${noticeMonths === 1 ? '' : 'en'}` : 'jederzeit ohne Einhaltung einer Kündigungsfrist')
  const noticeSpecial = noticeMonths > 1
    ? (language === 'en'
        ? ' Within the first three (3) months after the contract start date, a special termination right applies with a notice period of one (1) month.'
        : ' Innerhalb der ersten drei (3) Monate ab Vertragsbeginn gilt ein Sonderkündigungsrecht mit einer Kündigungsfrist von einem (1) Monat.')
    : ''
  const vars = {
    company: c.company || '',
    noticeClause,
    noticeSpecial,
    offerDate: formatDateLocal(ct.offerDate || dateIso, language),
    noticeMonths,
    priceNoticeMonths: Number(ct.priceNoticeMonths) || 1,
    objectionWeeks: Number(ct.objectionWeeks) || 2,
    curePeriodDays: Number(ct.curePeriodDays) || 3,
    cutoffTime: ct.cutoffTime || '14:00',
    shrinkagePct: Number(ct.shrinkagePct) || 1
  }

  const sectionTitle = (text: string) => ({
    stack: [
      { canvas: [{ type: 'rect', x: 0, y: 0, w: 26, h: 3, color: BRAND.orange }] },
      { text: String(text).toUpperCase(), fontSize: 11.5, bold: true, color: BRAND.navy, characterSpacing: 0.4, margin: [0, 5, 0, 0], tocItem: true, tocStyle: { fontSize: 9, color: BRAND.text } }
    ],
    margin: [0, 18, 0, 8]
  })

  const renderBlock = (block: any, numberOffset: number = 0): any[] => {
    if (!block) return []
    if (block.t === 'p') {
      return [{ text: fmt(block.text, vars), margin: [0, 0, 0, 7], alignment: 'justify' }]
    }
    if (block.t === 'b') {
      return [{
        ul: block.items.map((item: string) => ({ text: fmt(item, vars), margin: [0, 0, 0, 5] })),
        markerColor: BRAND.orange,
        margin: [0, 0, 0, 7]
      }]
    }
    if (block.t === 'n') {
      // Each clause is individually unbreakable (heading stays with its text),
      // but the LIST is breakable — a fully-unbreakable section taller than one
      // page would be clipped by pdfmake.
      return block.items.map((item: any, idx: number) => ({
        unbreakable: true,
        stack: [
          ...(item.h ? [{ text: `${numberOffset + idx + 1}. ${fmt(item.h, vars)}`, bold: true, color: BRAND.navy, fontSize: 9.5, margin: [0, 0, 0, 2] }] : []),
          { text: item.h ? fmt(item.text, vars) : `${numberOffset + idx + 1}. ${fmt(item.text, vars)}`, alignment: 'justify' }
        ],
        margin: [0, 0, 0, 8]
      }))
    }
    return []
  }

  const renderSection = (section: any): any[] => {
    if (!section?.blocks?.length) return []
    const [first, ...rest] = section.blocks
    // Keep the title together with the first block (or, for numbered lists,
    // only the first clause) so headings never orphan at a page bottom while
    // the section itself stays breakable.
    if (first.t === 'n' && first.items.length > 1) {
      const [firstItem, ...restItems] = first.items
      return [
        { unbreakable: true, stack: [sectionTitle(section.title), ...renderBlock({ t: 'n', items: [firstItem] })] },
        ...renderBlock({ t: 'n', items: restItems }, 1),
        ...rest.flatMap((b: any) => renderBlock(b))
      ]
    }
    return [
      { unbreakable: true, stack: [sectionTitle(section.title), ...renderBlock(first)] },
      ...rest.flatMap((b: any) => renderBlock(b))
    ]
  }

  // ---- Cover ----
  const cover: any[] = [
    { text: T.docTitle, fontSize: 24, bold: true, color: BRAND.navy, alignment: 'center', margin: [0, 60, 0, 4] },
    { text: `${T.dateWord}: ${formatDateLocal(dateIso, language)}`, fontSize: 10, color: BRAND.grayText, alignment: 'center', margin: [0, 0, 0, 50] },
    { text: T.between, fontSize: 10, italics: true, color: BRAND.grayText, alignment: 'center', margin: [0, 0, 0, 10] },
    { text: T.logyouParty, fontSize: 11, bold: true, alignment: 'center' },
    { text: T.logyouRef, fontSize: 9, color: BRAND.grayText, alignment: 'center', margin: [0, 3, 0, 24] },
    { text: T.and, fontSize: 10, italics: true, color: BRAND.grayText, alignment: 'center', margin: [0, 0, 0, 10] },
    { text: c.company || '', fontSize: 12, bold: true, color: BRAND.navy, alignment: 'center' },
    ...(c.contactName ? [{ text: c.contactName + (c.signerPosition ? ` — ${c.signerPosition}` : ''), fontSize: 10, alignment: 'center', margin: [0, 2, 0, 0] }] : []),
    ...(c.street ? [{ text: c.street, fontSize: 10, alignment: 'center', margin: [0, 2, 0, 0] }] : []),
    ...((c.zip || c.city) ? [{ text: [c.zip, c.city].filter(Boolean).join(' '), fontSize: 10, alignment: 'center', margin: [0, 2, 0, 0] }] : []),
    { text: c.country || (language === 'en' ? 'Germany' : 'Deutschland'), fontSize: 10, alignment: 'center', margin: [0, 2, 0, 0] },
    ...(c.ustId ? [{ text: `${T.signatures.vatId}: ${c.ustId}`, fontSize: 9, color: BRAND.grayText, alignment: 'center', margin: [0, 2, 0, 0] }] : []),
    { text: T.customerRef, fontSize: 9, color: BRAND.grayText, alignment: 'center', margin: [0, 3, 0, 0] },
    // Table of contents (native pdfmake TOC with real page numbers)
    {
      toc: { title: { text: T.tocTitle, fontSize: 13, bold: true, color: BRAND.navy, margin: [0, 0, 0, 8] } },
      pageBreak: 'before'
    }
  ]

  // ---- Assumptions (dynamic) ----
  const L = T.assumptions.labels
  const storageUnits = language === 'en'
    ? { small: 'shelf M', large: 'shelf L', pallet: 'pallet space(s)' }
    : { small: 'Fachboden M', large: 'Fachboden L', pallet: 'Palettenstellplatz/-plätze' }
  const storageParts: string[] = []
  if (Number(st.shelfSmallQty) > 0) storageParts.push(`${st.shelfSmallQty}× ${storageUnits.small}`)
  if (Number(st.shelfLargeQty) > 0) storageParts.push(`${st.shelfLargeQty}× ${storageUnits.large}`)
  if (Number(st.palletQty) > 0) storageParts.push(`${st.palletQty}× ${storageUnits.pallet}`)
  if (Number(st.volumeM3) > 0) storageParts.push(`${st.volumeM3} m³`)

  const kvRow = (label: string, value: any) => [
    { text: label, color: BRAND.grayText, fontSize: 9 },
    { text: String(value || '—'), bold: true, fontSize: 9 }
  ]
  const assumptionsSection: any[] = [
    {
      unbreakable: true,
      stack: [
        sectionTitle(T.assumptions.title),
        { text: T.assumptions.intro, margin: [0, 0, 0, 8] },
        {
          table: {
            widths: [210, '*'],
            body: [
              kvRow(L.plannedStart, formatDateLocal(a.plannedStart, language)),
              kvRow(L.businessModel, a.businessModel),
              kvRow(L.shopSystem, a.shopSystem),
              kvRow(L.ordersPerMonth, a.ordersPerMonth),
              kvRow(L.avgPicks, a.avgPicksPerOrder),
              kvRow(L.skuCount, a.skuCount),
              kvRow(L.storage, storageParts.join(', ') || '—')
            ]
          },
          layout: {
            hLineWidth: () => 0,
            vLineWidth: () => 0,
            fillColor: (rowIndex: number) => (rowIndex % 2 === 0 ? BRAND.zebra : null),
            paddingLeft: () => 8,
            paddingRight: () => 8,
            paddingTop: () => 4,
            paddingBottom: () => 4
          },
          margin: [0, 0, 0, 8]
        },
        { text: T.assumptions.onboarding, bold: true, color: BRAND.navy, margin: [0, 2, 0, 8] }
      ]
    },
    { text: fmt(T.assumptions.integration, vars), alignment: 'justify', margin: [0, 0, 0, 7] }
  ]

  // ---- SLA (with optional express clause) ----
  const slaSection = JSON.parse(JSON.stringify(T.sla))
  if (ct.includeExpress) {
    slaSection.blocks[0].items.push(T.sla.express)
  }

  // ---- Payment (method variant) ----
  const paymentSection = {
    title: T.payment.title,
    blocks: [ct.paymentMethod === 'transfer' ? T.payment.transfer : T.payment.sepa, ...T.payment.common]
  }

  // ---- Marketing (variant) ----
  const marketingSection = {
    title: T.marketing.title,
    blocks: [ct.marketingVariant === 'approval' ? T.marketing.approval : T.marketing.consent]
  }

  // ---- Annexes: Annex 1/2 wording only when the matching attachment is part of
  // the send (payload.attachments), so the contract never references a document
  // the customer did not receive. Absent attachments meta = full annex list.
  const att = payload.attachments || null
  const annexSection = att
    ? {
        title: T.annex.title,
        blocks: T.annex.blocks.filter((b: any, idx: number) => !((idx === 0 && att.offer === false) || (idx === 1 && att.agb === false) || (idx === 2 && att.avv === false)))
      }
    : T.annex

  // ---- Custom special clauses (dynamic) ----
  const customClauses = (ct.customClauses || []).filter((cl: any) => String(cl?.text || '').trim())
  const specialSection: any[] = customClauses.length
    ? [
        { unbreakable: true, stack: [sectionTitle(T.special.title), { text: T.special.intro, margin: [0, 0, 0, 8] }] },
        ...customClauses.map((cl: any, idx: number) => ({
          stack: [
            { text: `${idx + 1}. ${cl.title || (language === 'en' ? 'Supplementary agreement' : 'Sondervereinbarung')}`, bold: true, color: BRAND.navy, fontSize: 9.5, margin: [0, 0, 0, 2] },
            { text: String(cl.text), alignment: 'justify' }
          ],
          margin: [0, 0, 0, 8]
        }))
      ]
    : []

  // ---- Signatures ----
  const S = T.signatures
  const sigLine = (label: string, value: string) => ({
    columns: [
      { text: label, width: 110, color: BRAND.grayText, fontSize: 9 },
      { text: value, width: '*', fontSize: 9.5 }
    ],
    margin: [0, 0, 0, 6]
  })
  const signaturesSection: any[] = [
    {
      unbreakable: true,
      stack: [
        sectionTitle(S.title),
        { text: S.logyouCompany, bold: true, color: BRAND.navy, margin: [0, 6, 0, 2] },
        { text: `${S.logyouCity}, ${formatDateLocal(dateIso, language)}`, fontSize: 9, color: BRAND.grayText, margin: [0, 0, 0, 26] },
        { canvas: [{ type: 'line', x1: 0, y1: 0, x2: 220, y2: 0, lineWidth: 0.75, lineColor: BRAND.grayLine }] },
        { text: `${S.logyouSigner} — ${S.logyouPosition}`, fontSize: 9, margin: [0, 4, 0, 24] },

        { text: S.customerWord, bold: true, color: BRAND.navy, margin: [0, 6, 0, 8] },
        ...(signature
          ? [
              sigLine(S.date, formatDateTimeLocal(signature.signedAt, language)),
              {
                columns: [
                  { text: S.signature, width: 110, color: BRAND.grayText, fontSize: 9 },
                  signature.imageDataUrl
                    ? { image: signature.imageDataUrl, fit: [170, 60], margin: [0, -6, 0, 0] }
                    : { text: signature.name || '', italics: true, fontSize: 11, margin: [0, 2, 0, 0] }
                ],
                margin: [0, 0, 0, 6]
              },
              { text: language === 'en' ? 'Signed electronically (see signature certificate)' : 'Elektronisch unterschrieben (siehe Signaturprotokoll)', fontSize: 7.5, color: BRAND.grayText, margin: [110, 0, 0, 6] },
              sigLine(S.name, signature.name || c.contactName || S.dots),
              sigLine(S.position, signature.position || c.signerPosition || S.dots),
              sigLine(S.company, signature.company || c.company || S.dots),
              ...((signature.ustId || c.ustId) ? [sigLine(S.vatId, signature.ustId || c.ustId)] : []),
              sigLine(S.address, [signature.street || c.street, [signature.zip || c.zip, signature.city || c.city].filter(Boolean).join(' '), signature.country || c.country].filter(Boolean).join(' / ') || S.dots)
            ]
          : [
              sigLine(S.date, S.dots),
              sigLine(S.signature, S.dots),
              sigLine(S.name, c.contactName || S.dots),
              sigLine(S.position, c.signerPosition || S.dots),
              sigLine(S.company, c.company || S.dots),
              ...(c.ustId ? [sigLine(S.vatId, c.ustId)] : []),
              sigLine(S.address, [c.street, [c.zip, c.city].filter(Boolean).join(' '), c.country].filter(Boolean).join(' / ') || S.dots)
            ])
      ]
    }
  ]

  // ---- Signature certificate (digital signing audit page) ----
  const certificateSection: any[] = signature
    ? (() => {
        const CT = language === 'en'
          ? { title: 'Signature certificate', intro: 'This document was signed electronically via the LogYou signing portal. The following data was recorded at the moment of signing:', signer: 'Signer', company: 'Company', position: 'Position', address: 'Address', vat: 'VAT ID', email: 'E-mail', phone: 'Phone', time: 'Signed at', ip: 'IP address', ua: 'Browser', ref: 'Signing reference', docs: 'Documents presented and accepted', hash: 'SHA-256', decl: 'Declarations (exact wording as ticked by the signer)', note: 'The signer confirmed having read the documents listed above and consented to signing electronically. The hash values allow verification that the documents have not been altered since signing.' }
          : { title: 'Signaturprotokoll', intro: 'Dieses Dokument wurde elektronisch über das LogYou-Signaturportal unterzeichnet. Zum Zeitpunkt der Unterschrift wurden folgende Daten erfasst:', signer: 'Unterzeichner', company: 'Unternehmen', position: 'Position', address: 'Anschrift', vat: 'USt-IdNr.', email: 'E-Mail', phone: 'Telefon', time: 'Unterschrieben am', ip: 'IP-Adresse', ua: 'Browser', ref: 'Signatur-Referenz', docs: 'Vorgelegte und akzeptierte Dokumente', hash: 'SHA-256', decl: 'Erklärungen (exakter Wortlaut der bestätigten Kontrollkästchen)', note: 'Der Unterzeichner hat bestätigt, die aufgeführten Dokumente gelesen zu haben, und der elektronischen Unterzeichnung zugestimmt. Die Hashwerte ermöglichen die Prüfung, dass die Dokumente seit der Unterschrift nicht verändert wurden.' }
        const row = (label: string, value: any) => [
          { text: label, color: BRAND.grayText, fontSize: 9 },
          { text: String(value || '—'), fontSize: 9 }
        ]
        const addr = [signature.street, [signature.zip, signature.city].filter(Boolean).join(' '), signature.country].filter(Boolean).join(', ')
        const docRows = (signature.documents || []).map((d) => [
          { text: d.title + (d.version ? ` (v${d.version})` : ''), fontSize: 8.5 },
          { text: d.filename, fontSize: 8, color: BRAND.grayText },
          { text: d.sha256, fontSize: 6, color: BRAND.grayText }
        ])
        const declRows = (signature.acceptances || []).map((a) => ({
          columns: [
            { text: '☑', width: 14, fontSize: 9, color: BRAND.navy },
            { stack: [{ text: a.text, fontSize: 8.5 }, { text: formatDateTimeLocal(a.acceptedAt, language), fontSize: 7, color: BRAND.grayText }], width: '*' }
          ],
          margin: [0, 0, 0, 5]
        }))
        return [
          { text: '', pageBreak: 'before' },
          sectionTitle(CT.title),
          { text: CT.intro, margin: [0, 0, 0, 10] },
          {
            table: {
              widths: [140, '*'],
              body: [
                row(CT.signer, signature.name),
                row(CT.company, signature.company),
                row(CT.position, signature.position),
                row(CT.address, addr),
                row(CT.vat, signature.ustId),
                row(CT.email, signature.email),
                row(CT.phone, signature.phone),
                row(CT.time, formatDateTimeLocal(signature.signedAt, language)),
                row(CT.ip, signature.ip),
                row(CT.ua, signature.userAgent),
                row(CT.ref, signature.token ? signature.token.slice(0, 16) : '')
              ]
            },
            layout: {
              hLineWidth: () => 0,
              vLineWidth: () => 0,
              fillColor: (rowIndex: number) => (rowIndex % 2 === 0 ? BRAND.zebra : null),
              paddingLeft: () => 8,
              paddingRight: () => 8,
              paddingTop: () => 4,
              paddingBottom: () => 4
            },
            margin: [0, 0, 0, 14]
          },
          ...(signature.imageDataUrl ? [{ image: signature.imageDataUrl, fit: [200, 70], margin: [0, 0, 0, 14] }] : []),
          ...(docRows.length
            ? [
                { text: CT.docs, bold: true, color: BRAND.navy, margin: [0, 0, 0, 6] },
                {
                  table: { widths: [130, 130, '*'], body: [[{ text: '', fontSize: 8 }, { text: '', fontSize: 8 }, { text: CT.hash, fontSize: 8, color: BRAND.grayText }], ...docRows] },
                  layout: 'lightHorizontalLines',
                  margin: [0, 0, 0, 10]
                }
              ]
            : []),
          ...(declRows.length ? [{ text: CT.decl, bold: true, color: BRAND.navy, margin: [0, 4, 0, 6] }, ...declRows] : []),
          { text: CT.note, fontSize: 8.5, color: BRAND.grayText, alignment: 'justify', margin: [0, 6, 0, 0] }
        ]
      })()
    : []

  const content: any[] = [
    ...cover,
    { text: '', pageBreak: 'after' },
    ...(on('master') ? renderSection(T.master) : []),
    ...(on('services') ? renderSection(T.services) : []),
    ...(on('term') ? renderSection(T.term) : []),
    ...(on('pricing') ? renderSection(T.pricing) : []),
    ...(on('assumptions') ? assumptionsSection : []),
    ...(on('adjustments') ? renderSection(T.adjustments) : []),
    ...(on('payment') ? renderSection(paymentSection) : []),
    ...(on('sla') ? renderSection(slaSection) : []),
    ...(on('liability') ? renderSection(T.liability) : []),
    ...(on('property') ? renderSection(T.property) : []),
    ...(on('compliance') ? renderSection(T.compliance) : []),
    ...(on('privacy') ? renderSection(T.privacy) : []),
    ...(on('marketing') ? renderSection(marketingSection) : []),
    ...(on('special') ? specialSection : []),
    ...(on('jurisdiction') ? renderSection(T.jurisdiction) : []),
    ...(on('final') ? renderSection(T.final) : []),
    ...(on('annex') ? renderSection(annexSection) : []),
    ...signaturesSection,
    ...certificateSection
  ]

  return {
    pageSize: 'A4',
    pageMargins: [40, 106, 40, 86],
    info: {
      title: `${T.docTitle} – ${c.company || ''}`,
      author: 'LogYou GmbH',
      subject: T.docTitle
    },
    header: buildBrandHeader(T.docTitle, `logyou.de  ·  ${T.dateWord} ${formatDateLocal(dateIso, language)}`, logos.dark),
    footer: buildBrandFooter(T.page, T.of),
    content,
    styles: {
      tableHeader: { fontSize: 8.5, bold: true, color: BRAND.white }
    },
    defaultStyle: {
      font: 'Roboto',
      fontSize: 9.5,
      color: BRAND.text,
      lineHeight: 1.3
    }
  }
}

export const generateContractPdf = async (payload: any, options: { signature?: ContractSignature | null; filenameSuffix?: string } = {}): Promise<{ buffer: Buffer; filename: string }> => {
  // The drawn signature is a canvas PNG, but never trust the client: pdfmake
  // only renders PNG/JPEG, so normalise (or drop the image) before building.
  if (options.signature?.imageDataUrl) {
    const { normalizePdfImage } = await import('./pdfImages')
    const img = await normalizePdfImage(options.signature.imageDataUrl)
    options = { ...options, signature: { ...options.signature, imageDataUrl: img || '' } }
  }
  // Import pdfmake with virtual file system for server-side use
  // (defensive vfs extraction — the export shape varies by pdfmake
  // version/bundler, do not simplify).
  const pdfMake = await import('pdfmake/build/pdfmake.js')
  const pdfFonts = await import('pdfmake/build/vfs_fonts.js')

  // @ts-ignore - Set up virtual file system
  const pdfMakeInstance = pdfMake.default || pdfMake

  let vfs = null
  if ((pdfFonts as any).pdfMake?.vfs) {
    vfs = (pdfFonts as any).pdfMake.vfs
  } else if ((pdfFonts as any).default?.pdfMake?.vfs) {
    vfs = (pdfFonts as any).default.pdfMake.vfs
  } else if ((pdfFonts as any).default?.vfs) {
    vfs = (pdfFonts as any).default.vfs
  } else if ((pdfFonts as any).vfs) {
    vfs = (pdfFonts as any).vfs
  } else if ((pdfFonts as any).default) {
    const defaultKeys = Object.keys((pdfFonts as any).default)
    if (defaultKeys.some((key: string) => key.endsWith('.ttf'))) {
      vfs = (pdfFonts as any).default
    }
  }
  if (!vfs) {
    throw new Error('Could not find vfs fonts in pdfmake fonts module')
  }
  pdfMakeInstance.vfs = vfs

  const language = payload?.meta?.language === 'en' ? 'en' : 'de'
  const logos = await getQuoteLogos()
  const docDefinition = buildContractDocDefinition(payload, logos, options.signature || null)
  let filename = sanitizeContractFilename(payload?.customer?.company, language, payload?.meta?.date)
  if (options.filenameSuffix) filename = filename.replace(/\.pdf$/, `${options.filenameSuffix}.pdf`)

  const buffer = await new Promise<Buffer>((resolve, reject) => {
    try {
      pdfMakeInstance.createPdf(docDefinition).getBuffer((buf: Buffer) => resolve(buf))
    } catch (error) {
      reject(error)
    }
  })
  return { buffer, filename }
}
