import { getAusweisartFromUUID, UUidWithPrefix } from "#components/Ausweis/types.js";
import { omit } from "#lib/helpers.js";
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
import { sendGEGAnforderungsMail } from "#lib/server/mail/geg-anfordern.js";
import { Enums, GEGNachweisGewerbe, GEGNachweisWohnen, prisma } from "#lib/server/prisma.js";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { GEGEinpreisungSchema } from "src/generated/zod/gegeinpreisung.js";
import { z } from "zod";

export const PUT = defineApiRoute({
	input: GEGEinpreisungSchema.omit({
		benutzer_id: true,
		id: true,
		uid: true,
		status: true,
	}).merge(z.object({
		nachweis_uid: UUidWithPrefix
	})),
	headers: authorizationHeaders,
	middleware: authorizationMiddleware,
	async fetch(input, context, user) {
		const ausweisart = getAusweisartFromUUID(input.nachweis_uid);

		let einpreisung;
		let nachweis: GEGNachweisWohnen | GEGNachweisGewerbe;
		if (ausweisart === Enums.Ausweisart.GEGNachweisWohnen) {
			nachweis = await prisma.gEGNachweisWohnen.findUnique({
				where: {
					uid: input.nachweis_uid
				}
			})
		} else if (ausweisart === Enums.Ausweisart.GEGNachweisGewerbe) {
			nachweis = await prisma.gEGNachweisGewerbe.findUnique({
				where: {
					uid: input.nachweis_uid
				}
			})
		} else if (ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe) {
			nachweis = await prisma.bedarfsausweisGewerbe.findUnique({
				where: {
					uid: input.nachweis_uid
				}
			})
		} else {
			throw new APIError({
				"code": "BAD_REQUEST",
				"message": `Ausweisart wird nicht unterstützt: ${ausweisart}`
			})
		}
		

		if (!nachweis || nachweis.benutzer_id !== user.id) {
			throw new APIError({
				code: "BAD_REQUEST",
				message: "Ausweis existiert nicht oder gehört einem anderen Benutzer."
			})
		}

		if (ausweisart === Enums.Ausweisart.GEGNachweisWohnen) {
			einpreisung = await prisma.gEGEinpreisung.create({
				data: {
					...omit(input, ["nachweis_uid"]),
					status: Enums.Einpreisungsstatus.open,
					benutzer: {
						connect: {
							id: user.id
						}
					},
					geg_nachweis_wohnen: {
						connect: {
							uid: input.nachweis_uid
						}
					}
				}
			})
		} else if (ausweisart === Enums.Ausweisart.GEGNachweisGewerbe) {
			einpreisung = await prisma.gEGEinpreisung.create({
				data: {
					...omit(input, ["nachweis_uid"]),
					status: Enums.Einpreisungsstatus.open,
					benutzer: {
						connect: {
							id: user.id
						}
					},
					geg_nachweis_gewerbe: {
						connect: {
							uid: input.nachweis_uid
						}
					}
				}
			})
		} else if (ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe) {
			einpreisung = await prisma.gEGEinpreisung.create({
				data: {
					...omit(input, ["nachweis_uid"]),
					status: Enums.Einpreisungsstatus.open,
					benutzer: {
						connect: {
							id: user.id
						}
					},
					bedarfsausweis_gewerbe: {
						connect: {
							uid: input.nachweis_uid
						}
					}
				}
			})
		}

		await sendGEGAnforderungsMail(nachweis, user)

		return {
			uid: einpreisung.uid
		}
	},
})