import * as txml from "#lib/helpers/txml.js"
import { PDFDocument, PDFFont, rgb, StandardFonts } from "pdf-lib"
import { Checkbox, Flex, Text } from "./index.js"
import { Layout } from "./Layout.js"
import { Image } from "./Image.js"
import { PDFElement } from "./PDFElement.js"

export function xml2pdf(xml: string, fonts: Record<string, PDFFont> & { "default": PDFFont }) {
	const tree = txml.parse(xml)

	const iterateChildren = (children: ReturnType<typeof txml.parse>, parent: PDFElement) => {
		for (const child of children) {
			if (typeof child === "string") {
				// Simple text
				parent.addChild(new Text(child, { font: fonts["default"] }))
			} else if (child.tagName === "flex") {
				const flexbox = new Flex({
					height: parseFloat(child.attributes.height) || "auto",
					width: parseFloat(child.attributes.width) || "auto",
					align: child.attributes.align,
					direction: child.attributes.direction,
					gap: parseFloat(child.attributes.gap) || 0,
					justify: child.attributes.justify,
					margin: {
						bottom: parseFloat(child.attributes.marginBottom) || 0,
						left: parseFloat(child.attributes.marginLeft) || 0,
						right: parseFloat(child.attributes.marginRight) || 0,
						top: parseFloat(child.attributes.marginTop) || 0,
					},
					padding: {
						bottom: parseFloat(child.attributes.paddingBottom) || 0,
						left: parseFloat(child.attributes.paddingLeft) || 0,
						right: parseFloat(child.attributes.paddingRight) || 0,
						top: parseFloat(child.attributes.paddingTop) || 0,
					}
				})
				
				iterateChildren(child.children, flexbox)
				parent.addChild(flexbox)
			} else if (child.tagName === "text") {

				let color = rgb(0,0,0)

				if (child.attributes.hasOwnProperty("color")) {
					const colorValue = child.attributes.color.split(",")

					if (colorValue.length !== 3) {
						throw new Error("Invalid color, please provide 'r,g,b' as a value.")
					}

					color = rgb(...colorValue.map((x) => parseInt(x) / 255) as [number, number, number]);
				}
				
				const text = new Text(child.children[0] || "", { font: child.attributes.hasOwnProperty("font") ? fonts[child.attributes["font"]] : fonts["default"], lineHeight: parseFloat(child.attributes.lineHeight), fontSize: parseFloat(child.attributes.size) || 10, color, margin: {
					bottom: parseFloat(child.attributes.marginBottom) || 0,
					left: parseFloat(child.attributes.marginLeft) || 0,
					right: parseFloat(child.attributes.marginRight) || 0,
					top: parseFloat(child.attributes.marginTop) || 0,
				},
				padding: {
					bottom: parseFloat(child.attributes.paddingBottom) || 0,
					left: parseFloat(child.attributes.paddingLeft) || 0,
					right: parseFloat(child.attributes.paddingRight) || 0,
					top: parseFloat(child.attributes.paddingTop) || 0,
				} })

				parent.addChild(text)
			} else if (child.tagName === "checkbox") {
				if (typeof child.attributes.width === "undefined" || typeof child.attributes.height === "undefined") {
					throw new Error("Missing height or width property in Checkbox creation.")
				}

				const checkbox = new Checkbox(parseFloat(child.attributes.width), parseFloat(child.attributes.height), (child.attributes.hasOwnProperty("checked") && child.attributes.checked !== "false") || false)

				parent.addChild(checkbox);
			} else if (child.tagName === "layout") {
				const layout = new Layout([], {
					margin: {
						bottom: parseFloat(child.attributes.marginBottom) || 0,
						left: parseFloat(child.attributes.marginLeft) || 0,
						right: parseFloat(child.attributes.marginRight) || 0,
						top: parseFloat(child.attributes.marginTop) || 0,
					},
					padding: {
						bottom: parseFloat(child.attributes.paddingBottom) || 0,
						left: parseFloat(child.attributes.paddingLeft) || 0,
						right: parseFloat(child.attributes.paddingRight) || 0,
						top: parseFloat(child.attributes.paddingTop) || 0,
					}
				})

				iterateChildren(child.children, layout)
				parent.addChild(layout)
			} else if (child.tagName === "img") {
				const image = new Image({
					width: parseFloat(child.attributes.width),
					height: parseFloat(child.attributes.height),
					margin: {
						bottom: parseFloat(child.attributes.marginBottom) || 0,
						left: parseFloat(child.attributes.marginLeft) || 0,
						right: parseFloat(child.attributes.marginRight) || 0,
						top: parseFloat(child.attributes.marginTop) || 0,
					},
					src: child.attributes.src,
					data: child.attributes.data
				})

				parent.addChild(image)
			}
		}
	}

	const layout = new Layout([]);
	iterateChildren(tree, layout)

	return layout
}

// const pdf = await PDFDocument.create()

// const page = pdf.addPage()

// const font = await pdf.embedFont(StandardFonts.Helvetica)
// const bold = await pdf.embedFont(StandardFonts.HelveticaBold)

// console.log(page.getWidth(), "WIDTH");


// const layout = xml2pdf(`
// 	<flex direction="column" justify="end" width="${page.getWidth()}" height="${page.getHeight()}">
// 		<flex direction="row" gap="5" align="center">
// 			<checkbox width="8" height="8"></checkbox>
// 			<text size="12">awd1</text>
// 		</flex>
// 		<flex direction="row" gap="5" align="center">
// 			<checkbox width="8" height="8"></checkbox>
// 			<text size="12">awd2</text>
// 		</flex>
// 		<flex direction="row" gap="5" align="center">
// 			<checkbox width="8" height="8"></checkbox>
// 			<text size="12">awd3</text>
// 		</flex>
// 		<flex direction="row" gap="5" align="center">
// 			<checkbox width="8" height="8"></checkbox>
// 			<text size="12">awd4</text>
// 		</flex>
// 	</flex>`, {
// 	"default": font
// })

// layout.draw(page, 0, page.getHeight())

// import { writeFileSync } from "fs"
// import { FixedLengthArray } from "#lib/Berechnungen/BedarfsausweisWohnen/types.js"

// writeFileSync("./test-pdf.pdf", await pdf.save())