import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { generate } from "@pdfme/generator";
import VerbrauchsausweisWohnen2016Template from "../../lib/pdf/templates/GEG24_Verbrauchsausweis.json";
import { convertAusweisData } from "#lib/AusweisData.js";

/* -------------------------------- Pdf Tools ------------------------------- */
import { variable } from "#lib/pdf/plugins/variables/index.js";
import { text, image } from "@pdfme/schemas";
import { Schema, Template } from "@pdfme/common";

import { Moment } from "moment";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import moment from "moment";
import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen.js";

export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohnenClient) {
	const template = VerbrauchsausweisWohnen2016Template as Template;

	const berechnungen = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis);
	
	let inputs: Record<string, string> = {};
	
	// Verbrauchszeiträume
	const addVerbrauchszeitraum = (() => {
		let row = 0;
		let columnWidth = [16, 16, 80, 12, 18, 18, 18, 12];
	
		const getPosition = (column: number) => {
			return {
				position: {
					x:
						15 +
						columnWidth.reduce(
							(a, c, i) => (i >= column ? a : a + c),
							0
						),
					y: 141 + row * 5,
				},
				height: 5,
				width: 14,
				type: "text",
				fontSize: 8,
				verticalAlign: "middle",
			};
		};
	
		return (
			schema: Schema,
			start: Moment,
			end: Moment,
			energietraeger: string,
			primaerenergiefaktor: number,
			energieverbrauch: number,
			anteilWarmwasser: number,
			klimafaktor: number
		) => {
			inputs[`verbrauchszeitraum_${row}_start`] = start.format("MM.YYYY");
			inputs[`verbrauchszeitraum_${row}_end`] = end.format("MM.YYYY");
			inputs[`verbrauchszeitraum_${row}_energietraeger`] = energietraeger;
			inputs[`verbrauchszeitraum_${row}_primaerenergiefaktor`] =
				primaerenergiefaktor.toString();
			inputs[`verbrauchszeitraum_${row}_energieverbrauch`] =
				energieverbrauch.toString();
			inputs[`verbrauchszeitraum_${row}_anteil_warmwasser`] = Math.round(
				anteilWarmwasser * energieverbrauch
			).toString();
			inputs[`verbrauchszeitraum_${row}_anteil_heizung`] = Math.round(
				(1 - anteilWarmwasser) *
				energieverbrauch
			).toString();
			inputs[`verbrauchszeitraum_${row}_klimafaktor`] =
				klimafaktor.toString();
	
			schema[`verbrauchszeitraum_${row}_start`] = getPosition(0);
			schema[`verbrauchszeitraum_${row}_end`] = getPosition(1);
			schema[`verbrauchszeitraum_${row}_energietraeger`] = getPosition(2);
			schema[`verbrauchszeitraum_${row}_primaerenergiefaktor`] =
				getPosition(3);
			schema[`verbrauchszeitraum_${row}_energieverbrauch`] = getPosition(4);
			schema[`verbrauchszeitraum_${row}_anteil_warmwasser`] = getPosition(5);
			schema[`verbrauchszeitraum_${row}_anteil_heizung`] = getPosition(6);
			schema[`verbrauchszeitraum_${row}_klimafaktor`] = getPosition(7);
	
			row++;
		};
	})();
	
	
	addVerbrauchszeitraum(
		template.schemas[2],
		moment(ausweis.startdatum),
		moment(ausweis.startdatum).add("1", "year"),
		ausweis.gebaeude_aufnahme_allgemein?.brennstoff_1,
		berechnungen?.primaerfaktorww,
		berechnungen?.verbrauch_1_kwh,
		ausweis.anteil_warmwasser_1 / 100,
		berechnungen?.klimafaktoren[0].klimafaktor
	);
	
	addVerbrauchszeitraum(
		template.schemas[2],
		moment(ausweis.startdatum).add("1", "year"),
		moment(ausweis.startdatum).add("2", "years"),
		ausweis.gebaeude_aufnahme_allgemein?.brennstoff_1,
		berechnungen?.primaerfaktorww,
		berechnungen?.verbrauch_2_kwh,
		ausweis.anteil_warmwasser_1 / 100,
		berechnungen?.klimafaktoren[1].klimafaktor
	);
	
	addVerbrauchszeitraum(
		template.schemas[2],
		moment(ausweis.startdatum).add("2", "years"),
		moment(ausweis.startdatum).add("3", "years"),
		ausweis.gebaeude_aufnahme_allgemein?.brennstoff_1,
		berechnungen?.primaerfaktorww,
		berechnungen?.verbrauch_3_kwh,
		ausweis.anteil_warmwasser_1 / 100,
		berechnungen?.klimafaktoren[2].klimafaktor
	);
	
	if (ausweis.zusaetzliche_heizquelle) {
		addVerbrauchszeitraum(
		template.schemas[2],
			moment(ausweis.startdatum),
			moment(ausweis.startdatum).add("1", "year"),
			ausweis.gebaeude_aufnahme_allgemein?.brennstoff_2,
			berechnungen?.primaerfaktorww_1,
			berechnungen?.verbrauch_4_kwh,
			ausweis.anteil_warmwasser_2 / 100,
			berechnungen?.klimafaktoren[0].klimafaktor
		);
	
		addVerbrauchszeitraum(
			template.schemas[2],
			moment(ausweis.startdatum).add("1", "year"),
			moment(ausweis.startdatum).add("2", "years"),
			ausweis.gebaeude_aufnahme_allgemein?.brennstoff_2,
			berechnungen?.primaerfaktorww_1,
			berechnungen?.verbrauch_5_kwh,
			ausweis.anteil_warmwasser_2 / 100,
			berechnungen?.klimafaktoren[1].klimafaktor
		);
	
		addVerbrauchszeitraum(
			template.schemas[2],
			moment(ausweis.startdatum).add("2", "years"),
			moment(ausweis.startdatum).add("3", "years"),
			ausweis.gebaeude_aufnahme_allgemein?.brennstoff_2,
			berechnungen?.primaerfaktorww_1,
			berechnungen?.verbrauch_6_kwh,
			ausweis.anteil_warmwasser_2 / 100,
			berechnungen?.klimafaktoren[1].klimafaktor
		);
	}
	
	const convertedInputs = { ...convertAusweisData(ausweis), ...inputs };
	const empfehlungen = getEmpfehlungen(ausweis);
	
	const addEmpfehlung = (() => {
		let i = 0;
		let columnWidth = [9, 25, 81, 13, 10, 17, 31];
	
		const getPosition = (column: number) => {
			return {
				position: {
					x:
						13 +
						columnWidth.reduce(
							(a, c, i) => (i >= column ? a : a + c),
							0
						),
					y: 94 + i * 15,
				},
				height: 15,
				width: columnWidth[column],
				type: "text",
				fontSize: 8,
				verticalAlign: "middle",
			};
		};
	
		return (empfehlung: ReturnType<typeof getEmpfehlungen>[0]) => {
			template.schemas[3][`empfehlung_${i}_nr`] = getPosition(0)
			template.schemas[3][`empfehlung_${i}_bauteil`] = getPosition(1)
			template.schemas[3][`empfehlung_${i}_beschreibung`] = getPosition(2)
			template.schemas[3][`empfehlung_${i}_amortisationszeit`] = getPosition(5)
			template.schemas[3][`empfehlung_${i}_kosten`] = getPosition(6)
	
			convertedInputs[`empfehlung_${i}_nr`] = (i + 1).toString();
			convertedInputs[`empfehlung_${i}_bauteil`] = empfehlung.anlagenteil;
			convertedInputs[`empfehlung_${i}_beschreibung`] = empfehlung.description;
			convertedInputs[`empfehlung_${i}_amortisationszeit`] = "";
			convertedInputs[`empfehlung_${i}_kosten`] = "";
	
			i++;
		}
	})()
	
	
	for (const empfehlung of empfehlungen) {
		addEmpfehlung(empfehlung);
	}
	

	// Fügt den Header mit Registriernummer und GEG Datum hinzu.
	const addHeader = (page: number, includeRegistriernummer = true) => {
		if (includeRegistriernummer) {
			template.schemas[page]["ausweis.registriernummer"] = {
				position: { x: 153, y: 37 },
				height: 5,
				width: 35,
				type: "text",
				fontSize: 8,
				verticalAlign: "middle",
			};
		}

		template.schemas[page]["geg_datum"] = {
			position: { x: 108, y: 21.7 },
			height: 5,
			width: 25,
			type: "text",
			fontSize: 8,
			verticalAlign: "middle",
		};
	}

	for (let i = 0; i < template.schemas.length; i++) {
		if (i == template.schemas.length - 1) {
			// Die letzte Seite ist nur ein Anhang mit Erläuterungen, darauf ist keine Registriernummer vermerkt.
			addHeader(i, false);
		} else {
			addHeader(i);
		}
	}

	convertedInputs["ausweis.registriernummer"] = "1231234";
	convertedInputs["geg_datum"] = "01.01.2024";
	
	
	const pdf = await generate({
		template,
		plugins: { text, image, variable: { ...variable, pdf: variable.pdf.bind(convertedInputs), ui: variable.ui.bind(convertedInputs) } },
		inputs: [convertedInputs],
		options: {
			author: "IB Cornelsen",
			creationDate: new Date(),
			creator: "IB Cornelsen",
			language: "de",
			title: "Verbrauchsausweis Wohnen GEG 2024",
		},
	});

	return pdf;
}