import fuelList from "#components/Ausweis/brennstoffListe.js";
import { faker } from "@faker-js/faker";
import { type Enums } from "#lib/client/prisma";
import "cypress-file-upload"
import moment from "moment";

describe("Verbrauchsausweis erstellen Schritt 1", () => {
	const ausstellgrund = (["Modernisierung", "Neubau", "Sonstiges", "Verkauf", "Vermietung"] as Enums.Ausstellgrund[]);
	const heizungsstatus = (["BEHEIZT", "NICHT_VORHANDEN", "UNBEHEIZT"] as Enums.Heizungsstatus[]);

	it("erstellt einen neuen Verbrauchsausweis Wohngebäude.", () => {
		cy.visit("/energieausweis-erstellen/verbrauchsausweis-gewerbe");

		cy.wait(1000);

		// Wir überprüfen, ob alle Ausstelgründe vorhanden sind, diese sollten genau so viele sein wie in der Datenbank vorhanden sind.
		cy.get("select[data-cy='ausstellgrund']")
			.select(
				faker.number.int({
					min: 0,
					max: (["Modernisierung", "Neubau", "Sonstiges", "Verkauf", "Vermietung"] as Enums.Ausstellgrund[]).length - 1,
				})
			)

		// Jetzt Füllen wir das Baujahr vom Gebäude aus.
		cy.get("input[name='baujahr_gebaeude']")
			.should("have.attr", "type", "number")
			.type(
				faker.number.int({ min: 1900, max: 2021 }).toString() +
					"{enter}",
				{ delay: 50 }
			);

		// Jetzt Füllen wir das Baujahr der Heizung aus.
		cy.get("input[name='baujahr_heizung']")
			.should("have.attr", "type", "number")
			.type(
				faker.number.int({ min: 1900, max: 2021 }).toString() +
					"{enter}",
				{ delay: 50 }
			);

		// Anzahl Einheiten
		cy.get("input[name='einheiten']")
			.should("have.attr", "type", "number")
			.type(faker.number.int({ min: 1, max: 5 }).toString());

		// Sanierungsstatus
		cy.get("select[name='saniert']").select(
			Math.random() > 0.5 ? "true" : "false"
		);

		// Adresse
		cy.get("input[name='adresse']").type(faker.location.streetAddress());

		// Postleitzahl
		cy.get("input[name='plz']").type(
			faker.location.zipCode({
				format: "#####",
			})
		);

		// TODO: Ort - Dieser wird aus der Datenbank abgefragt, wir müssen also warten, bis der Dropdown da ist.

		// Flaeche
		cy.get("input[name='flaeche']")
			.should("have.attr", "type", "number")
			.type(faker.number.int({ min: 50, max: 1000 }).toString());

		// Nutzlaeche
		cy.get("input[name='nutzflaeche']")
			.should("have.attr", "type", "number")
			.type(faker.number.int({ min: 50, max: 1000 }).toString());	

		// Keller
		cy.get("select[name='keller']").find("option:not([disabled])").should("have.length", heizungsstatus.length).parent().select(faker.number.int({
			max: heizungsstatus.length,
			min: 1
		}));

		// Dachgeschoss
		cy.get("select[name='dachgeschoss']").find("option:not([disabled])").should("have.length", heizungsstatus.length).parent().select(faker.number.int({
			max: heizungsstatus.length,
			min: 1
		}));

		// Brennstoff und Einheit 1
		const brennstoffKombo = fuelList[faker.number.int({ min: 0, max: fuelList.length - 1 })];

		cy.get("select[name='brennstoff_1']").select(brennstoffKombo[0]);
		cy.get("select[name='einheit_1']").select(brennstoffKombo[1]);

let availableDates = [];
		const startDate = moment()
			.subtract(4, "years")
			.subtract(6, "months");
		const endDate = moment().subtract(3, "years");
	
		for (let m = moment(startDate); m.isBefore(endDate); m.add(1, "month")) {
			availableDates.push({
				year: m.year(),
				month: m.month(),
			});
		}

		// Verbrauchszeitraum
		cy.get("select[name='energieverbrauch_zeitraum_monat']").select(availableDates[0].month.toString());
		cy.get("select[name='energieverbrauch_zeitraum_jahr']").select(availableDates[0].year.toString());

		// Verbrauch
		cy.get("input[name='verbrauch_1']").type(faker.number.int({ min: 4000, max: 15000 }).toString());
		cy.get("input[name='verbrauch_2']").type(faker.number.int({ min: 4000, max: 15000 }).toString());
		cy.get("input[name='verbrauch_3']").type(faker.number.int({ min: 4000, max: 15000 }).toString());

		
		const zusaetzlicheHeizquelle = Math.random() > 0.5;

		if (zusaetzlicheHeizquelle) {
			cy.get("[data-cy='zusaetzliche_heizquelle']").check();

			// Brennstoff und Einheit 2
			const brennstoffKombo2 = fuelList[faker.number.int({ min: 0, max: fuelList.length - 1 })];

			cy.get("[data-cy='brennstoff_2']").select(brennstoffKombo2[0], { force: true });
			cy.get("[data-cy='einheit_2']").select(brennstoffKombo2[1], { force: true });

			// Verbrauch
			cy.get("input[name='verbrauch_4']").type(faker.number.int({ min: 4000, max: 15000 }).toString(), { force: true });
			cy.get("input[name='verbrauch_5']").type(faker.number.int({ min: 4000, max: 15000 }).toString(), { force: true });
			cy.get("input[name='verbrauch_6']").type(faker.number.int({ min: 4000, max: 15000 }).toString(), { force: true });
		}

		// Gebäudestrom
		cy.get("input[name='strom_1']").type(faker.number.int({ min: 4000, max: 15000 }).toString());
		cy.get("input[name='strom_2']").type(faker.number.int({ min: 4000, max: 15000 }).toString());
		cy.get("input[name='strom_3']").type(faker.number.int({ min: 4000, max: 15000 }).toString());

		// Stromverbrauch Enthält
		if (Math.random() > 0.5) cy.get("input[name='stromverbrauch_enthaelt_heizung']").check();
		if (Math.random() > 0.5) cy.get("input[name='stromverbrauch_enthaelt_warmwasser']").check();
		if (Math.random() > 0.5) cy.get("input[name='stromverbrauch_enthaelt_lueftung']").check();
		if (Math.random() > 0.5) cy.get("input[name='stromverbrauch_enthaelt_beleuchtung']").check();
		if (Math.random() > 0.5) cy.get("input[name='stromverbrauch_enthaelt_kuehlung']").check();

		// Warmwasser enthalten und bekannt
		const warmwasserEnthalten = Math.random() > 0.5;
		const anteilBekannt = Math.random() > 0.5;

		if (warmwasserEnthalten) {
			cy.get("input[name='warmwasser_enthalten']").check();			

			if (anteilBekannt) {
				// Der Anteil ist bekannt, wir müssen ihn also angeben.
				cy.get("input[name='warmwasser_anteil_bekannt']").check();

				cy.get("input[name='anteil_warmwasser_1']").type(faker.number.int({ min: 0, max: 50 }).toString());

				if (zusaetzlicheHeizquelle) {
					// Zusätzliche Heizquelle existiert, also müssen wir auch hier den Anteil angeben.
					cy.get("input[name='anteil_warmwasser_1']").type(faker.number.int({ min: 0, max: 50 }).toString());
				}
			}
		}

		// Thermische Kühlung enthalten
		const kuehlungEnthalten = Math.random() > 0.5;

		if (kuehlungEnthalten) {
			cy.get("input[name='kuehlung_enthalten']").check();			

			cy.get("input[name='anteil_kuehlung_1']").type(faker.number.int({ min: 0, max: 50 }).toString());

			if (zusaetzlicheHeizquelle) {
				// Zusätzliche Heizquelle existiert, also müssen wir auch hier den Anteil angeben.
				cy.get("input[name='anteil_kuehlung_2']").type(faker.number.int({ min: 0, max: 50 }).toString());
			}
		}

		// Alternative Energieversorgungssysteme
		if (Math.random() > 0.5) cy.get("input[name='alternative_heizung']").check();
		if (Math.random() > 0.5) cy.get("input[name='alternative_warmwasser']").check();
		if (Math.random() > 0.5) cy.get("input[name='alternative_lueftung']").check();
		if (Math.random() > 0.5) cy.get("input[name='alternative_kuehlung']").check();

		// Gebäudetyp
		cy.get("select[name='gebaeudetyp']").then(($dropdown) => {
			const options = $dropdown.find('option:not([disabled])');
			// Select the option at the random index
			cy.get("select[name='gebaeudetyp']").select(options.eq(faker.number.int({ min: 1, max: options.length - 1 })).val() as string);
		});

		// Gebäudeteil
		cy.get("select[name='gebaeudeteil']").then(($dropdown) => {
			const options = $dropdown.find('option');
			// Select the option at the random index
			cy.get("select[name='gebaeudeteil']").select(options.eq(faker.number.int({ min: 1, max: options.length - 1 })).val() as string);
		});

		// Lüftung
		cy.get("select[name='lueftung']").then(($dropdown) => {
			const options = $dropdown.find('option');
			// Select the option at the random index
			cy.get("select[name='lueftung']").select(options.eq(faker.number.int({ min: 1, max: options.length - 1 })).val() as string);
		});

		// Kühlung
		cy.get("select[name='kuehlung']").then(($dropdown) => {
			const options = $dropdown.find('option');
			// Select the option at the random index
			cy.get("select[name='kuehlung']").select(options.eq(faker.number.int({ min: 1, max: options.length - 1 })).val() as string);
		});

		// Leerstand
		cy.get("input[name='leerstand']").should("have.attr", "type", "number").type(faker.number.int({ min: 0, max: 30 }).toString());

		// Heizungsanlage Daten
		if (Math.random() > 0.5) cy.get("input[name='zentralheizung']").check();
		if (Math.random() > 0.5) cy.get("input[name='einzelofen']").check();
		if (Math.random() > 0.5) cy.get("input[name='durchlauf_erhitzer']").check();
		if (Math.random() > 0.5) cy.get("input[name='standard_kessel']").check();
		if (Math.random() > 0.5) cy.get("input[name='solarsystem_warmwasser']").check();
		if (Math.random() > 0.5) cy.get("input[name='waermepumpe']").check();
		if (Math.random() > 0.5) cy.get("input[name='niedertemperatur_kessel']").check();
		if (Math.random() > 0.5) cy.get("input[name='brennwert_kessel']").check();
		if (Math.random() > 0.5) cy.get("input[name='warmwasser_rohre_gedaemmt']").check();
		if (Math.random() > 0.5) cy.get("input[name='heizungsrohre_gedaemmt']").check();
		if (Math.random() > 0.5) cy.get("input[name='zirkulation']").check();
		// if (Math.random() > 0.5) cy.get("input[name='raum_temperatur_regler']").check();

		// Heizungsanlage Bilder
		cy.get("input[name='heizung_image']").should("have.attr", "type", "file").attachFile("images/heizungsanlage/1.jpeg", { subjectType: "input" });
		cy.get("input[name='heizung_image']").should("have.attr", "type", "file").attachFile("images/heizungsanlage/2.jpeg", { subjectType: "input" });

		// Fenster Daten
		if (Math.random() > 0.5) cy.get("input[name='einfach_verglasung']").check();
		if (Math.random() > 0.5) cy.get("input[name='doppel_verglasung']").check();
		if (Math.random() > 0.5) cy.get("input[name='isolier_verglasung']").check();
		if (Math.random() > 0.5) cy.get("input[name='dreifach_verglasung']").check();
		if (Math.random() > 0.5) cy.get("input[name='fenster_dicht']").check();
		if (Math.random() > 0.5) cy.get("input[name='fenster_teilweise_undicht']").check();
		if (Math.random() > 0.5) cy.get("input[name='tueren_dicht']").check();
		if (Math.random() > 0.5) cy.get("input[name='tueren_undicht']").check();
		if (Math.random() > 0.5) cy.get("input[name='rolllaeden_kaesten_gedaemmt']").check();

		// Fenster Bilder
		cy.get("input[name='fenster_image']").should("have.attr", "type", "file").attachFile("images/fenster/1.jpeg", { subjectType: "input" });
		cy.get("input[name='fenster_image']").should("have.attr", "type", "file").attachFile("images/fenster/2.jpeg", { subjectType: "input" });

		// Wärmedämmung Daten
		if (Math.random() > 0.5) cy.get("input[name='aussenwand_gedaemmt']").check();
		if (Math.random() > 0.5) cy.get("input[name='keller_wand_gedaemmt']").check();
		if (Math.random() > 0.5) cy.get("input[name='keller_decke_gedaemmt']").check();
		if (Math.random() > 0.5) cy.get("input[name='dachgeschoss_gedaemmt']").check();
		if (Math.random() > 0.5) cy.get("input[name='oberste_geschossdecke_gedaemmt']").check();
		if (Math.random() > 0.5) cy.get("input[name='oberste_geschossdecke_min_12cm_gedaemmt']").check();

		// Wärmedämmung Bilder
		cy.get("input[name='daemmung_image']").should("have.attr", "type", "file").attachFile("images/daemmung/1.jpeg", { subjectType: "input" });
		cy.get("input[name='daemmung_image']").should("have.attr", "type", "file").attachFile("images/daemmung/2.jpeg", { subjectType: "input" });

		// Gebäude Bild
		cy.get("input[name='gebaeude_image']").should("have.attr", "type", "file").attachFile("images/gebaeude/1.jpeg", { subjectType: "input" });

		// Jetzt können wir den Verbrauchsausweis erstellen.
		cy.get("form[name='ausweis'] button[data-cy='weiter']").click({ force: true });

		// Wir sind nicht eingeloggt also sollte jetzt ein Login Screen erscheinen.
		// Wir klicken auf registrieren und erstellen einen neuen Benutzer, danach loggen wir uns mit diesem ein.
		cy.get("[data-cy='registrieren']").click();

		const email = faker.internet.email();
		const passwort = "test1234";
		const vorname = faker.person.firstName();
		const nachname = faker.person.lastName();

		cy.get("form[name='signup'] input[name='email']").should("be.visible").should("have.attr", "type", "email").type(email);
		cy.get("form[name='signup'] input[name='passwort']").should("be.visible").should("have.attr", "type", "password").type(passwort);
		cy.get("form[name='signup'] input[name='vorname']").should("be.visible").should("have.attr", "type", "text").type(vorname);
		cy.get("form[name='signup'] input[name='nachname']").should("be.visible").should("have.attr", "type", "text").type(nachname);

		cy.get("form[name='signup'] button[type='submit']").click();

		// Wir sind jetzt registriert und können uns nun einloggen.
		// Die Email sollte automatisch eingetragen sein, da wir uns gerade registriert haben.
		cy.get("form[name='login'] input[name='email']").should("be.visible").should("have.attr", "type", "email").should("contain.value", email);
		cy.get("form[name='login'] input[name='passwort']").should("be.visible").should("have.attr", "type", "password").type(passwort);

		cy.get("form[name='login'] button[type='submit']").click();

		// Der Ausweis sollte jetzt schon erstellt worden sein und wir sollten auf die kundendaten seite weitergeleitet worden sein.
		cy.url().should("contain", "/kundendaten");

		cy.wait(1000)

		// Wir füllen jetzt die Kundendaten aus.
		// cy.get("select[name='anrede']").select(Math.random() > 0.5 ? "Herr" : "Frau");
		cy.get("input[name='vorname']").should("contain.value", vorname);
		cy.get("input[name='name']").should("contain.value", nachname);
		// cy.get("input[name='email']").should("contain.value", email);
		// cy.get("input[name='telefon']").type(faker.phone.number());
		
		cy.get("input[name='rechnung_empfaenger']").type(`${vorname} ${nachname}`);
		cy.get("input[name='rechnung_strasse']").type(faker.location.streetAddress());
		// TODO: Random Plz generieren, allerdings muss die auch in der Datenbank vorhanden sein...
		cy.get("input[name='rechnung_plz']").type("2103");
		// Jetzt sollte der PLZ Container erscheinen, dort klicken wir einfach das erste Element an.
		cy.get("div[data-test='plz-container']").children().first().click();
		// cy.get("input[name='rechnung_telefon']").type(faker.phone.number());
		cy.get("input[name='rechnung_email']").should("contain.value", email);
		cy.get("input[data-cy='paypal']").click();

		// Datenschutz und AGB akzeptieren, dann schicken wir das Formular ab.
		// cy.get("input[name='agb-akzeptieren']").check()
		// cy.get("input[name='datenschutz-akzeptieren']").check()
		cy.get("button[data-cy='bestellen']").click();

		cy.origin('https://www.mollie.com', () => {
			// Jetzt sind wir auf der Mollie Seite, dort wählen wir den "paid" status aus
			cy.get("input[type='radio'][name='final_state'][value='paid']").check();
			// Da wird unser Test fehlschlagen, da die localhost domain von Mollie aus nicht erreichbar ist.
		})
	});	
});
