import moment from "moment";
import newUserIdMap from "./new-user-id-map.json" assert { type: "json" };
import processed from "./processed.json" assert { type: "json" };
import { Benutzer, Enums, prisma } from "#lib/server/prisma.js";
import * as fs from "fs";
import { fileURLToPath } from "url";
import { hashPassword } from "#lib/password.js";
import Papa from "papaparse"

const saveUserMap = () => {
	fs.writeFileSync(
		fileURLToPath(new URL("./new-user-id-map.json", import.meta.url)),
		JSON.stringify(newUserIdMap)
	);
};

const path = fileURLToPath(new URL("./ausweise.csv", import.meta.url));

if (!fs.existsSync(path)) {
	throw new Error(`${path} existiert nicht.`)
}

const file = fs.createReadStream(path, "utf8");
Papa.parse(file, {
	header: true,
	step: async function(results) {
		const dataset = results.data as any;

		if (dataset.id in processed) {
			return;
		}
	
		const user_id = dataset.user_id;
	
		let user: Benutzer;
		if (!newUserIdMap[user_id]) {
			console.log(`Missing user ${user_id}`);
			
			user = await prisma.benutzer.create({
				data: {
					email: dataset.email || "nutzer@nutzeremail.com",
					passwort: hashPassword(Math.random().toString(36).slice(-8)),
					adresse: dataset.strasse,
					ort: dataset.ort,
					plz: dataset.plz,
					name: dataset.name,
					vorname: dataset.vorname,
					rolle: Enums.BenutzerRolle.USER,
					telefon: dataset.telefonnummer,
				},
			});
	
			newUserIdMap[user_id] = user.uid;
			saveUserMap();
		} else {
			user = await prisma.benutzer.findUnique({
				where: {
					uid: newUserIdMap[user_id],
				},
			});
		}
	
		if (!user) {
			saveProcessed();
			throw new Error("Benutzer ist nicht vorhanden.");
		}
	
		await prisma.$transaction(async (tx) => {			
			const objekt = await tx.objekt.create({
				data: {
					adresse: dataset.strasse,
					erstellungsdatum: moment(dataset.erstellungsdatum).toDate(),
					ort: dataset.objekt_ort,
					plz: dataset.objekt_plz,
					benutzer: {
						connect: {
							uid: user.uid,
						},
					},
				},
			});
	
			const aufnahme = await tx.aufnahme.create({
				data: {
					alternative_heizung: dataset.alheizung == "1",
					alternative_kuehlung: dataset.alkuehlung == "1",
					alternative_lueftung: dataset.allueftung == "1",
					alternative_warmwasser: dataset.alwarmwasser == "1",
					aussenwand_gedaemmt: dataset.aussenwand_gedaemmt == "1",
					aussenwand_min_12cm_gedaemmt:
						dataset.aussenwand_min_12cm_gedaemmt == "1",
					ausstellungsdatum: moment(dataset.erstellungsdatum).toDate(),
					baujahr_gebaeude: parseInt(dataset.baujahr_gebaeude) ? [parseInt(dataset.baujahr_gebaeude)] : [],
					baujahr_heizung: parseInt(dataset.baujahr_anlage) ? [parseInt(dataset.baujahr_anlage)] : [],
					baujahr_klima: parseInt(dataset.baujahr_klimaanlage) ? [parseInt(dataset.baujahr_klimaanlage)] : [],
					benutzer: {
						connect: {
							uid: user.uid,
						},
					},
					objekt: {
						connect: {
							id: objekt.id,
						},
					},
					brennstoff_1: dataset.energietraeger_1,
					brennstoff_2: dataset.energietraeger_2,
					dachgeschoss:
						dataset.dachgeschoss == "Beheizt"
							? Enums.Heizungsstatus.BEHEIZT
							: dataset.dachgeschoss == "Nicht Vorhanden"
							? Enums.Heizungsstatus.NICHT_VORHANDEN
							: Enums.Heizungsstatus.UNBEHEIZT,
					brennwert_kessel: dataset.brennwert_kessel == "1",
					dachgeschoss_gedaemmt: dataset.dachgeschoss_gedaemmt == "1",
					dachgeschoss_min_12cm_gedaemmt:
						dataset.dachgeschoss_min_12cm_gedaemmt == "1",
					doppel_verglasung: dataset.doppel_verglasung == "1",
					dreifach_verglasung: dataset.dreifach_verglasung == "1",
					durchlauf_erhitzer: dataset.durchlauf_erhitzer == "1",
					einfach_verglasung: dataset.einfach_verglasung == "1",
					einzelofen: dataset.einzelofen == "1",
					einheiten: parseInt(dataset.anzahl_einheiten),
					fenster_dicht: dataset.fenster_dicht == "1",
					fenster_teilweise_undicht:
						dataset.fenster_teilweise_undicht == "1",
					flaeche: parseFloat(dataset.wohnflaeche),
					nutzflaeche: parseFloat(dataset.nutzflaeche),
					gebaeudeteil: dataset.objekt_gebaeudeteil,
					gebaeudetyp: dataset.objekt_typ,
					heizungsrohre_gedaemmt: dataset.heizungsrohre_gedaemmt == "1",
					isolier_verglasung: dataset.isolier_verglasung == "1",
					keller:
						dataset.keller_beheizt == "Beheizt"
							? Enums.Heizungsstatus.BEHEIZT
							: dataset.dachgeschoss == "Nicht Vorhanden"
							? Enums.Heizungsstatus.NICHT_VORHANDEN
							: Enums.Heizungsstatus.UNBEHEIZT,
					keller_decke_gedaemmt: dataset.keller_decke_gedaemmt == "1",
					keller_wand_gedaemmt: dataset.keller_wand_gedaemmt == "1",
					kuehlung: dataset.wird_gekuehlt,
					erstellungsdatum: moment(dataset.erstellungsdatum).toDate(),
					rolllaeden_kaesten_gedaemmt:
						dataset.rolllaeden_kaesten_gedaemmt == "1",
					leerstand: parseInt(dataset.leerstand),
					lueftung:
						dataset.lueftungskonzept == "Fensterlüftung"
							? Enums.Lueftungskonzept.Fensterlueftung
							: dataset.lueftungskonzept ==
								"Lüftungsanlage mit Wärmerückgewinnung"
							? Enums.Lueftungskonzept
									.LueftungsanlageMitWaermerueckgewinnung
							: dataset.lueftungskonzept ==
								"Lüftungsanlage ohne Wärmerückgewinnung"
							? Enums.Lueftungskonzept
									.LueftungsanlageOhneWaermerueckgewinnung
							: Enums.Lueftungskonzept.Schachtlueftung,
					niedertemperatur_kessel: dataset.niedertemperatur_kessel == "1",
					oberste_geschossdecke_gedaemmt:
						dataset.oberste_geschossdecke_gedaemmt == "1",
					oberste_geschossdecke_min_12cm_gedaemmt:
						dataset.oberste_geschossdecke_min_12cm_gedaemmt == "1",
					photovoltaik: dataset.photovoltaik == "1",
					raum_temperatur_regler: dataset.raum_temperatur_regler == "1",
					saniert: dataset.objekt_saniert == "1",
					solarsystem_warmwasser: dataset.solarsystem_warmwasser == "1",
					standard_kessel: dataset.standard_kessel == "1",
					tueren_dicht: dataset.tueren_dicht == "1",
					tueren_undicht: dataset.tueren_undicht == "1",
					waermepumpe: dataset.waermepumpe == "1",
					warmwasser_rohre_gedaemmt:
						dataset.warmwasser_rohre_gedaemmt == "1",
					zentralheizung: dataset.zentralheizung == "1",
					zirkulation: dataset.zirkulation == "1",
					boxpruefung: dataset.boxpruefung == "1",
				},
			});
	
			if (dataset.ausweisart === "VA") {
				const ausweis = await tx.verbrauchsausweisWohnen.create({
					data: {
						alternative_heizung: dataset.alheizung == "1",
						alternative_kuehlung: dataset.alkuehlung == "1",
						alternative_lueftung: dataset.allueftung == "1",
						alternative_warmwasser: dataset.alwarmwasser == "1",
						anteil_warmwasser_1: parseFloat(
							dataset.anteil_warmwasser_1
						),
						anteil_warmwasser_2: parseFloat(
							dataset.anteil_warmwasser_2
						),
						aufnahme: {
							connect: {
								id: aufnahme.id,
							},
						},
						ausgestellt: dataset.erledigt == "2",
						ausstellgrund:
							dataset.ausstellgrund == "Vermietung"
								? Enums.Ausstellgrund.Vermietung
								: dataset.ausstellgrund == "Verkauf"
								? Enums.Ausstellgrund.Verkauf
								: dataset.ausstellgrund == "Modernisierung"
								? Enums.Ausstellgrund.Modernisierung
								: dataset.ausstellgrund == "Neubau"
								? Enums.Ausstellgrund.Neubau
								: Enums.Ausstellgrund.Sonstiges,
						bestellt: dataset.erledigt == "0",
						einheit_1: dataset.energietraeger_einheit_heizquelle_1,
						einheit_2: dataset.energietraeger_einheit_heizquelle_2,
						storniert: dataset.erledigt == "4",
						benutzer: {
							connect: {
								uid: user.uid,
							},
						},
						kontrolldatei_angefragt: dataset.kontrolldatei == "1",
						registriernummer: dataset.regnummer,
						startdatum: moment(
							`${dataset.energieverbrauch_zeitraum_jahr}-${dataset.energieverbrauch_zeitraum_monat.padStart(2, "0")}-01`
						).toDate(),	
						verbrauch_1: parseFloat(
							dataset.energieverbrauch_1_heizquelle_1
						),
						verbrauch_2: parseFloat(
							dataset.energieverbrauch_2_heizquelle_1
						),
						verbrauch_3: parseFloat(
							dataset.energieverbrauch_3_heizquelle_1
						),
						verbrauch_4: parseFloat(
							dataset.energieverbrauch_1_heizquelle_2
						),
						verbrauch_5: parseFloat(
							dataset.energieverbrauch_2_heizquelle_2
						),
						verbrauch_6: parseFloat(
							dataset.energieverbrauch_3_heizquelle_2
						),
						warmwasser_anteil_bekannt:
							dataset.warmwasser_anteil_bekannt == "1",
						warmwasser_enthalten: dataset.warmwasser_enthalten == "1",
						zurueckgestellt: dataset.zurueckGestellt == "1",
						zusaetzliche_heizquelle:
							dataset.zusaetzliche_heizquelle == "1",
					},
				});
			} else if (dataset.ausweisart === "VANW") {
				const ausweis = await tx.verbrauchsausweisGewerbe.create({
					data: {
						alternative_heizung: dataset.alheizung == "1",
						alternative_kuehlung: dataset.alkuehlung == "1",
						alternative_lueftung: dataset.allueftung == "1",
						alternative_warmwasser: dataset.alwarmwasser == "1",
						anteil_warmwasser_1: parseFloat(
							dataset.anteil_warmwasser_1
						),
						anteil_warmwasser_2: parseFloat(
							dataset.anteil_warmwasser_2
						),
						aufnahme: {
							connect: {
								id: aufnahme.id,
							},
						},
						ausgestellt: dataset.erledigt == "2",
						ausstellgrund:
							dataset.ausstellgrund == "Vermietung"
								? Enums.Ausstellgrund.Vermietung
								: dataset.ausstellgrund == "Verkauf"
								? Enums.Ausstellgrund.Verkauf
								: dataset.ausstellgrund == "Modernisierung"
								? Enums.Ausstellgrund.Modernisierung
								: dataset.ausstellgrund == "Neubau"
								? Enums.Ausstellgrund.Neubau
								: Enums.Ausstellgrund.Sonstiges,
						bestellt: dataset.erledigt == "0",
						einheit_1: dataset.energietraeger_einheit_heizquelle_1,
						einheit_2: dataset.energietraeger_einheit_heizquelle_2,
						storniert: dataset.erledigt == "4",
						benutzer: {
							connect: {
								uid: user.uid,
							},
						},
						kontrolldatei_angefragt: dataset.kontrolldatei == "1",
						registriernummer: dataset.regnummer,
						startdatum: moment(
							`${dataset.energieverbrauch_zeitraum_jahr}-${dataset.energieverbrauch_zeitraum_monat.padStart(2, "0")}-01`
						).toDate(),	
						verbrauch_1: parseFloat(
							dataset.energieverbrauch_1_heizquelle_1
						),
						verbrauch_2: parseFloat(
							dataset.energieverbrauch_2_heizquelle_1
						),
						verbrauch_3: parseFloat(
							dataset.energieverbrauch_3_heizquelle_1
						),
						verbrauch_4: parseFloat(
							dataset.energieverbrauch_1_heizquelle_2
						),
						verbrauch_5: parseFloat(
							dataset.energieverbrauch_2_heizquelle_2
						),
						verbrauch_6: parseFloat(
							dataset.energieverbrauch_3_heizquelle_2
						),
						anteil_kuehlung_1: parseFloat(dataset.anteil_kuehlung_1),
						anteil_kuehlung_2: parseFloat(dataset.anteil_kuehlung_2),
						brennstoff_1: dataset.energietraeger_1,
						brennstoff_2: dataset.energietraeger_2,
						strom_1: parseFloat(dataset.vanw_strom_1),
						strom_2: parseFloat(dataset.vanw_strom_2),
						strom_3: parseFloat(dataset.vanw_strom_3),
						kuehlung_enthalten: dataset.wird_gekuehlt == "1" ? true : false,
						stromverbrauch_enthaelt_beleuchtung: dataset.nwbeleuchtung == "1",
						stromverbrauch_enthaelt_heizung: dataset.nwheizung == "1",
						stromverbrauch_enthaelt_kuehlung: dataset.nwkuehlung == "1",
						stromverbrauch_enthaelt_lueftung: dataset.nwlueftung == "1",
						stromverbrauch_enthaelt_sonstige: dataset.nwsonstiges,
						stromverbrauch_enthaelt_warmwasser: dataset.nwwarmwasser == "1",
						warmwasser_enthalten: dataset.warmwasser_enthalten == "1",
						zurueckgestellt: dataset.zurueckGestellt == "1",
						zusaetzliche_heizquelle:
							dataset.zusaetzliche_heizquelle == "1"
					},
				});
			} else if (dataset.ausweisart === "BA") {
				const ausweis = await tx.bedarfsausweisWohnen.create({
					data: {
						alternative_heizung: dataset.alheizung == "1",
						alternative_kuehlung: dataset.alkuehlung == "1",
						alternative_lueftung: dataset.allueftung == "1",
						alternative_warmwasser: dataset.alwarmwasser == "1",
						aufnahme: {
							connect: {
								id: aufnahme.id,
							},
						},
						ausgestellt: dataset.erledigt == "2",
						ausstellgrund:
							dataset.ausstellgrund == "Vermietung"
								? Enums.Ausstellgrund.Vermietung
								: dataset.ausstellgrund == "Verkauf"
								? Enums.Ausstellgrund.Verkauf
								: dataset.ausstellgrund == "Modernisierung"
								? Enums.Ausstellgrund.Modernisierung
								: dataset.ausstellgrund == "Neubau"
								? Enums.Ausstellgrund.Neubau
								: Enums.Ausstellgrund.Sonstiges,
						bestellt: dataset.erledigt == "0",
						storniert: dataset.erledigt == "4",
						benutzer: {
							connect: {
								uid: user.uid,
							},
						},
						kontrolldatei_angefragt: dataset.kontrolldatei == "1",
						registriernummer: dataset.regnummer,
						zurueckgestellt: dataset.zurueckGestellt == "1",
						anteil_zusatzheizung: parseFloat(dataset.anteil_zusatzheizung),
						anzahl_gauben: parseInt(dataset.anzahl_gauben),
						anzahl_vollgeschosse: parseInt(dataset.anzahl_vollgeschosse),
						aussenwand_bauart: dataset.aussenwand_bauart,
						aussenwand_daemmung: parseFloat(dataset.aussenwand_daemmung),
						aussenwand_flaeche: parseFloat(dataset.aussenwand_flaeche),
						aussenwand_u_wert: parseFloat(dataset.aussenwand_u_wert),
						aussenwandflaeche_unbeheizt: parseFloat(dataset.aussenwandflaeche_unbeheizt),
						boden_bauart: dataset.boden_bauart,
						boden_daemmung: parseFloat(dataset.boden_daemmung),
						breite_gauben: parseFloat(dataset.breite_gauben),
						dach_bauart: dataset.dach_bauart,
						dach_daemmung: parseFloat(dataset.dach_daemmung),
						dach_u_wert: parseFloat(dataset.dach_u_wert),
						// TODO Das machen wir zwar so aber das ist doch scheiße....
						dachfenster_art: parseFloat(dataset.dachfenster_art),
						dachfenster_flaeche: parseFloat(dataset.dachfenster_flaeche),
						dachflaeche: parseFloat(dataset.dachflaeche),
						decke_bauart: dataset.decke_bauart,
						decke_daemmung: parseFloat(dataset.decke_daemmung),
						decke_u_wert: parseFloat(dataset.decke_u_wert),
						dicht: dataset.dicht == "1",
						fenster_art_1: parseFloat(dataset.fenster_art_1),
						fenster_art_2: parseFloat(dataset.fenster_art_2),
						deckenflaeche: parseFloat(dataset.deckenflaeche),
						fenster_flaeche_1: parseFloat(dataset.fenster_flaeche_1),
						fenster_flaeche_2: parseFloat(dataset.fenster_flaeche_2),
						fensterflaeche_nw_no: parseFloat(dataset.fensterflaeche_nw_no),
						fensterflaeche_so_sw: parseFloat(dataset.fensterflaeche_so_sw),
						fussboden_flaeche: parseFloat(dataset.fussboden_flaeche),
						fussboden_u_wert: parseFloat(dataset.fussboden_u_wert),
						geschosshoehe: parseFloat(dataset.geschosshoehe),
						haustuer_art: parseFloat(dataset.haustuer_art),
						haustuer_flaeche: parseFloat(dataset.haustuer_flaeche),
						heizung_speicherung: dataset.heizung_speicherung,
						heizung_verteilung: dataset.heizung_verteilung,
						heizung_zentral: dataset.heizung_zentral == "1",
						masse_a: parseFloat(dataset.masse_a),
						masse_b: parseFloat(dataset.masse_b),
						masse_c: parseFloat(dataset.masse_c),
						masse_d: parseFloat(dataset.masse_d),
						masse_e: parseFloat(dataset.masse_e),
						masse_f: parseFloat(dataset.masse_f),
						kollektor_flaeche: parseFloat(dataset.kollektor_flaeche),
						volumen: parseFloat(dataset.volumen),
						waerme_erzeugung_heizung: dataset.waerme_erzeugung_heizung,
						warmwasser_erzeugung: dataset.warmwasser_erzeugung,
						warmwasser_speicherung: dataset.warmwasser_speicherung,
						warmwasser_verteilung: dataset.warmwasser_verteilung
					},
				});
			}
	
			processed[dataset.id as string] = true;	
			saveProcessed()
		}, {
			maxWait: 5000,
			timeout: 10000
		});
	},
	complete(results, file) {
			saveProcessed()
	},
});

function saveProcessed() {
	fs.writeFileSync(
		fileURLToPath(new URL("./processed.json", import.meta.url)),
		JSON.stringify(processed)
	);
};
