import initWasm, { render_pdf as wasmRenderPdf } from '../pkg/forme.js';
import { readFile } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
import { dirname, join, resolve } from 'node:path';
// ── WASM initialization ────────────────────────────────────────────
let initialized = false;
async function ensureInit() {
    if (initialized)
        return;
    const __dirname = dirname(fileURLToPath(import.meta.url));
    const wasmPath = join(__dirname, '..', 'pkg', 'forme_bg.wasm');
    const wasmBytes = await readFile(wasmPath);
    await initWasm({ module_or_path: wasmBytes });
    initialized = true;
}
// ── 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) {
    await ensureInit();
    return wasmRenderPdf(json);
}
export async function renderPdfWithLayout(json) {
    await ensureInit();
    // Dynamic import to access the WASM binding that returns { pdf, layout }
    const { render_pdf_with_layout } = await import('../pkg/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);
    }
    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);
    }
    await Promise.all([resolveFonts(doc), resolveImages(doc)]);
    return renderPdfWithLayout(JSON.stringify(doc));
}
// ── Template rendering ──────────────────────────────────────────────
export async function renderTemplate(templateJson, dataJson) {
    await ensureInit();
    const { render_template_pdf } = await import('../pkg/forme.js');
    return render_template_pdf(templateJson, dataJson);
}
export async function renderTemplateWithLayout(templateJson, dataJson) {
    await ensureInit();
    const { render_template_pdf_with_layout } = await import('../pkg/forme.js');
    const result = render_template_pdf_with_layout(templateJson, dataJson);
    return result;
}
// ── Data extraction ──────────────────────────────────────────────────
export { extractData } from './extract.js';
