import { a as sanitizeXmlColor, n as sanitizeHref, r as sanitizeImageSrc } from "./sanitize-O_3j1mNJ.js";

//#region src/renderers/pptx.ts
/**
* PPTX renderer — lazy-loads pptxgenjs on first use.
* Each `<Page>` becomes a slide. Document nodes map to PPTX elements.
*
* @example
* ```ts
* import { render, Document, Page, Heading, Text } from '@pyreon/document'
*
* const doc = Document({
*   title: 'Presentation',
*   children: [
*     Page({ children: [Heading({ children: 'Slide 1' }), Text({ children: 'Hello' })] }),
*     Page({ children: [Heading({ children: 'Slide 2' })] }),
*   ],
* })
* const pptx = await render(doc, 'pptx') // → Uint8Array
* ```
*/
function resolveColumn(col) {
	return typeof col === "string" ? { header: col } : col;
}
function getTextContent(children) {
	return children.map((c) => typeof c === "string" ? c : getTextContent(c.children)).join("");
}
const HEADING_SIZES = {
	1: 28,
	2: 24,
	3: 20,
	4: 18,
	5: 16,
	6: 14
};
const SLIDE_WIDTH = 10;
const CONTENT_MARGIN = .5;
const CONTENT_WIDTH = SLIDE_WIDTH - CONTENT_MARGIN * 2;
function processNode(node, ctx) {
	const p = node.props;
	switch (node.type) {
		case "heading": {
			const fontSize = HEADING_SIZES[p.level ?? 1] ?? 20;
			ctx.slide.addText(getTextContent(node.children), {
				x: CONTENT_MARGIN,
				y: ctx.y,
				w: CONTENT_WIDTH,
				h: .6,
				fontSize,
				bold: true,
				color: sanitizeXmlColor(p.color ?? "#000000"),
				align: p.align ?? "left"
			});
			ctx.y += .7;
			break;
		}
		case "text": {
			const text = getTextContent(node.children);
			ctx.slide.addText(text, {
				x: CONTENT_MARGIN,
				y: ctx.y,
				w: CONTENT_WIDTH,
				h: .4,
				fontSize: p.size ?? 14,
				bold: p.bold ?? false,
				italic: p.italic ?? false,
				underline: p.underline ? { style: "sng" } : void 0,
				strike: p.strikethrough ? "sngStrike" : void 0,
				color: sanitizeXmlColor(p.color ?? "#333333"),
				align: p.align ?? "left"
			});
			ctx.y += .5;
			break;
		}
		case "image": {
			const src = sanitizeImageSrc(p.src);
			const w = Math.min((p.width ?? 400) / 96, CONTENT_WIDTH);
			const h = (p.height ?? 300) / 96;
			if (src.startsWith("data:")) {
				ctx.slide.addImage({
					data: src,
					x: CONTENT_MARGIN,
					y: ctx.y,
					w,
					h
				});
				ctx.y += h + .2;
			}
			break;
		}
		case "table": {
			const columns = (p.columns ?? []).map(resolveColumn);
			const rows = p.rows ?? [];
			const hs = p.headerStyle;
			const allRows = [columns.map((col) => ({
				text: col.header,
				options: {
					bold: true,
					fill: { color: sanitizeXmlColor(hs?.background ?? "#f5f5f5") },
					color: sanitizeXmlColor(hs?.color ?? "#000000"),
					align: col.align ?? "left",
					fontSize: 12
				}
			})), ...rows.map((row, rowIdx) => columns.map((col, colIdx) => ({
				text: String(row[colIdx] ?? ""),
				options: {
					align: col.align ?? "left",
					fontSize: 11,
					fill: p.striped && rowIdx % 2 === 1 ? { color: "F9F9F9" } : void 0
				}
			})))];
			const rowHeight = .35;
			const tableHeight = allRows.length * rowHeight;
			ctx.slide.addTable(allRows, {
				x: CONTENT_MARGIN,
				y: ctx.y,
				w: CONTENT_WIDTH,
				border: {
					pt: .5,
					color: "DDDDDD"
				},
				rowH: rowHeight
			});
			ctx.y += tableHeight + .2;
			break;
		}
		case "list": {
			const items = node.children.filter((c) => typeof c !== "string").map((item) => getTextContent(item.children));
			const isOrdered = p.ordered;
			const listText = items.map((item, i) => ({
				text: isOrdered ? `${i + 1}. ${item}\n` : `\u2022 ${item}\n`,
				options: {
					fontSize: 13,
					bullet: false
				}
			}));
			ctx.slide.addText(listText, {
				x: CONTENT_MARGIN,
				y: ctx.y,
				w: CONTENT_WIDTH,
				h: items.length * .35
			});
			ctx.y += items.length * .35 + .1;
			break;
		}
		case "code": {
			const text = getTextContent(node.children);
			ctx.slide.addText(text, {
				x: CONTENT_MARGIN,
				y: ctx.y,
				w: CONTENT_WIDTH,
				h: .5,
				fontSize: 10,
				fontFace: "Courier New",
				fill: { color: "F5F5F5" },
				color: "333333"
			});
			ctx.y += .6;
			break;
		}
		case "quote": {
			const text = getTextContent(node.children);
			ctx.slide.addText(text, {
				x: CONTENT_MARGIN + .3,
				y: ctx.y,
				w: CONTENT_WIDTH - .3,
				h: .5,
				fontSize: 13,
				italic: true,
				color: "555555"
			});
			ctx.y += .6;
			break;
		}
		case "link":
			ctx.slide.addText(getTextContent(node.children), {
				x: CONTENT_MARGIN,
				y: ctx.y,
				w: CONTENT_WIDTH,
				h: .4,
				fontSize: 13,
				color: "4F46E5",
				underline: { style: "sng" },
				hyperlink: { url: sanitizeHref(p.href) }
			});
			ctx.y += .5;
			break;
		case "button":
			ctx.slide.addText(getTextContent(node.children), {
				x: CONTENT_MARGIN,
				y: ctx.y,
				w: 3,
				h: .5,
				fontSize: 14,
				bold: true,
				color: sanitizeXmlColor(p.color ?? "#ffffff"),
				fill: { color: sanitizeXmlColor(p.background ?? "#4f46e5") },
				align: "center",
				hyperlink: { url: sanitizeHref(p.href) }
			});
			ctx.y += .6;
			break;
		case "spacer":
			ctx.y += (p.height ?? 12) / 72;
			break;
		case "divider":
			ctx.slide.addText("", {
				x: CONTENT_MARGIN,
				y: ctx.y,
				w: CONTENT_WIDTH,
				h: .02,
				fill: { color: sanitizeXmlColor(p.color ?? "#DDDDDD") }
			});
			ctx.y += .2;
			break;
		case "section":
		case "row":
		case "column":
			for (const child of node.children) if (typeof child !== "string") processNode(child, ctx);
			break;
		default: break;
	}
}
function processSlide(pageNode, pptx) {
	const ctx = {
		slide: pptx.addSlide(),
		y: CONTENT_MARGIN
	};
	for (const child of pageNode.children) if (typeof child !== "string") processNode(child, ctx);
}
const pptxRenderer = { async render(node, _options) {
	let PptxGenJS;
	try {
		PptxGenJS = await import("./pptxgen.es-FsqHs8mD.js");
	} catch {
		throw new Error("[@pyreon/document] PPTX renderer requires \"pptxgenjs\" package. Install it: bun add pptxgenjs");
	}
	const pptx = new (PptxGenJS.default ?? PptxGenJS)();
	if (node.props.title) pptx.title = node.props.title;
	if (node.props.author) pptx.author = node.props.author;
	if (node.props.subject) pptx.subject = node.props.subject;
	const pages = [];
	for (const child of node.children) if (typeof child !== "string" && child.type === "page") pages.push(child);
	if (pages.length === 0) {
		const syntheticPage = {
			type: "page",
			props: {},
			children: node.children
		};
		pages.push(syntheticPage);
	}
	for (const page of pages) processSlide(page, pptx);
	const output = await pptx.write("arraybuffer");
	return new Uint8Array(output);
} };

//#endregion
export { pptxRenderer };
//# sourceMappingURL=pptx-DXiMiYFM.js.map