// Node entry uses the wasm-pack `--target nodejs` build, which is a
// self-initializing CJS module: it `require('fs').readFileSync`s its
// own .wasm at import time, so callers don't need to await any init.
import { render_pdf as wasmRenderPdf } from '../pkg-node/forme.js';
import { readFile } from 'node:fs/promises';
import { resolve } from 'node:path';
// ── Font resolution ──────────────────────────────────────────────
function uint8ArrayToBase64(bytes) {
    return Buffer.from(bytes).toString('base64');
}
async function resolveFonts(doc) {
    const fonts = doc.fonts;
    if (!fonts?.length)
        return;
    for (const font of fonts) {
        if (font.src instanceof Uint8Array) {
            font.src = uint8ArrayToBase64(font.src);
        }
        else if (typeof font.src === 'string' && !font.src.startsWith('data:')) {
            const bytes = await readFile(resolve(font.src));
            font.src = uint8ArrayToBase64(new Uint8Array(bytes));
        }
        // data URIs pass through as-is (engine extracts base64 portion)
    }
}
// ── Image resolution ─────────────────────────────────────────────
async function resolveImages(doc) {
    const children = doc.children;
    if (!children?.length)
        return;
    for (const child of children) {
        await resolveImagesInNode(child);
    }
}
async function resolveImagesInNode(node) {
    const kind = node.kind;
    if (kind?.type === 'Image' && typeof kind.src === 'string') {
        const src = kind.src;
        if (src.startsWith('http://') || src.startsWith('https://')) {
            const res = await fetch(src);
            if (!res.ok)
                throw new Error(`Failed to fetch image: ${src} (${res.status})`);
            const contentType = res.headers.get('content-type') || 'image/png';
            const buf = new Uint8Array(await res.arrayBuffer());
            kind.src = `data:${contentType};base64,${uint8ArrayToBase64(buf)}`;
        }
    }
    const children = node.children;
    if (children?.length) {
        for (const child of children) {
            await resolveImagesInNode(child);
        }
    }
}
// ── Render functions ───────────────────────────────────────────────
export async function renderPdf(json) {
    return wasmRenderPdf(json);
}
export async function renderPdfWithLayout(json) {
    const { render_pdf_with_layout } = await import('../pkg-node/forme.js');
    const result = render_pdf_with_layout(json);
    return result;
}
export async function renderDocument(element, options) {
    const { serialize } = await import('@formepdf/react');
    const doc = serialize(element);
    if (options?.embedData !== undefined) {
        doc.embeddedData = JSON.stringify(options.embedData);
    }
    if (options?.flattenForms) {
        doc.flattenForms = true;
    }
    await Promise.all([resolveFonts(doc), resolveImages(doc)]);
    return renderPdf(JSON.stringify(doc));
}
export async function renderDocumentWithLayout(element, options) {
    const { serialize } = await import('@formepdf/react');
    const doc = serialize(element);
    if (options?.embedData !== undefined) {
        doc.embeddedData = JSON.stringify(options.embedData);
    }
    if (options?.flattenForms) {
        doc.flattenForms = true;
    }
    await Promise.all([resolveFonts(doc), resolveImages(doc)]);
    return renderPdfWithLayout(JSON.stringify(doc));
}
// ── Template rendering ──────────────────────────────────────────────
export async function renderTemplate(templateJson, dataJson) {
    const { render_template_pdf } = await import('../pkg-node/forme.js');
    return render_template_pdf(templateJson, dataJson);
}
export async function renderTemplateWithLayout(templateJson, dataJson) {
    const { render_template_pdf_with_layout } = await import('../pkg-node/forme.js');
    const result = render_template_pdf_with_layout(templateJson, dataJson);
    return result;
}
// ── PDF certification ────────────────────────────────────────────────
export async function certifyPdf(pdfBytes, config) {
    const { certify_pdf } = await import('../pkg-node/forme.js');
    return certify_pdf(pdfBytes, JSON.stringify(config));
}
/** @deprecated Use certifyPdf */
export const signPdf = certifyPdf;
export async function redactPdf(pdfBytes, regions) {
    const { redact_pdf } = await import('../pkg-node/forme.js');
    return redact_pdf(pdfBytes, JSON.stringify(regions));
}
/**
 * Find text regions matching patterns in a PDF.
 *
 * Searches PDF content streams for literal or regex patterns and returns
 * redaction regions (in web top-origin coordinates) for each match.
 */
export async function findTextRegions(pdfBytes, patterns) {
    const { find_text_regions } = await import('../pkg-node/forme.js');
    const json = find_text_regions(pdfBytes, JSON.stringify(patterns));
    return JSON.parse(json);
}
/**
 * Redact text matching patterns from a PDF.
 *
 * Convenience wrapper: finds all text matching the patterns, then
 * applies coordinate-based redaction to each match.
 */
export async function redactText(pdfBytes, patterns) {
    const { redact_text } = await import('../pkg-node/forme.js');
    return redact_text(pdfBytes, JSON.stringify(patterns));
}
// ── PDF merging ──────────────────────────────────────────────────────
/**
 * Merge multiple PDF documents into a single PDF.
 *
 * @param pdfs - Array of PDF byte arrays to merge in order.
 * @returns The merged PDF as a Uint8Array.
 */
export async function mergePdfs(pdfs) {
    const { merge_pdfs } = await import('../pkg-node/forme.js');
    const base64Pdfs = pdfs.map((pdf) => Buffer.from(pdf).toString('base64'));
    return merge_pdfs(JSON.stringify(base64Pdfs));
}
// ── Data extraction ──────────────────────────────────────────────────
export { extractData } from './extract.js';
