import { UUidWithPrefix } from "#components/Ausweis/types.js";
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
import { prisma } from "#lib/server/prisma.js";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { VerbrauchsausweisGewerbeSchema } from "src/generated/zod/verbrauchsausweisgewerbe.js";
import { z } from "zod";

export const PUT = defineApiRoute({
	meta: {
		contentTypes: ["application/json"],
		description:
			"Erstellt einen neuen Verbrauchsausweis für Gewerbegebäude nach dem Schema der EnEV von 2016. Als Input wird ein bestehendes Gebäude benötigt. Falls keine UID einer bestehenden Gebäudeaufnahme mitgegeben wird, wird automatisch eine erstellt.",
		tags: ["Verbrauchsausweis Gewerbe"],
	},
	input: z.object({
		ausweis: VerbrauchsausweisGewerbeSchema.omit({
			id: true,
			benutzer_id: true,
			uid: true,
			aufnahme_id: true,
			rechnung_id: true,
			updated_at: true,
			created_at: true
		}).merge(z.object({
			startdatum: z.coerce.date()
		})),
		uid_aufnahme: UUidWithPrefix
	}),
	output: z.object({
		uid: UUidWithPrefix,
		objekt_uid: UUidWithPrefix,
		aufnahme_uid: UUidWithPrefix,
	}),
	headers: authorizationHeaders,
	middleware: authorizationMiddleware,
	async fetch(input, ctx, user) {
		const aufnahme = await prisma.aufnahme.findUnique({
			where: {
				uid: input.uid_aufnahme
			}
		})

		if (!aufnahme || aufnahme.benutzer_id !== user.id) {
			throw new APIError({
				code: "FORBIDDEN",
				message: "Aufnahme konnte nicht gefunden werden oder gehört nicht zu diesem Benutzer."
			})
		}

			const createdAusweis = await prisma.verbrauchsausweisGewerbe.create({
				data: {
					...input.ausweis,
					benutzer: {
						connect: {
							id: user.id,
						},
					},
					aufnahme: {
						connect: {
							uid: aufnahme.uid,
						},
					},
				},
				select: {
					uid: true,
					aufnahme: {
						select: {
							uid: true,
							objekt: {
								select: {
									uid: true,
								},
							},
						},
					},
				},
			});

			return {
				uid: createdAusweis.uid,
				objekt_uid: createdAusweis.aufnahme.objekt.uid,
				aufnahme_uid: createdAusweis.aufnahme.uid,
			};
	},
});

export const GET = defineApiRoute({
	meta: {
		description: "Gibt ein spezifisches Gebäude des Benutzers zurück.",
		tags: ["Gebäude"],
		headers: {
			Authorization: {
				description: "Ein gültiger Authentifizierungstoken",
				required: true,
				allowEmptyValue: false,
				examples: {
					Bearer: {
						value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
					},
				},
			},
		},
	},
	middleware: authorizationMiddleware,
	async fetch(input, context, user) {
		const { uid } = context.params;

		const ausweis = await prisma.verbrauchsausweisGewerbe.findUnique({
			where: {
				uid,
			},
			include: {
				benutzer: true,
				aufnahme: {
					include: {
						bilder: true,
						events: {
							include: {
								benutzer: {
									select: {
										uid: true,
									},
								},
							},
							orderBy: {
								date: "asc",
							},
						},
					},
				},
			},
		});

		if (
			!ausweis ||
			(ausweis.benutzer_id !== null && ausweis.benutzer_id !== user.id)
		) {
			// Falls wir den Ausweis nicht finden können, werfen wir einen Fehler
			throw new APIError({
				code: "NOT_FOUND",
				message: "Ausweis konnte nicht gefunden werden.",
			});
		}

		return ausweis;
	},
});
