import { AufnahmeClient, OptionalNullable, UUidWithPrefix, ZodOverlap } from "#components/Ausweis/types.js";
import { exclude } from "#lib/exclude.js";
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
import { Enums, prisma } from "#lib/server/prisma.js";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { AufnahmeSchema } from "src/generated/zod/aufnahme.js";
import { z } from "zod";

export const PATCH = defineApiRoute({
	input: AufnahmeSchema.omit({
		id: true,
		uid: true,
		benutzer_id: true,
		objekt_id: true,
		erstellungsdatum: true
	}),
	output: z.void(),
	middleware: authorizationMiddleware,
	async fetch(input, ctx, user) {
		const { uid } = ctx.params

		const aufnahme = await prisma.aufnahme.findUnique({
			where: {
				uid,
				benutzer_id: user.id
			}
		});

		if (!aufnahme) {
			throw new APIError({
				code: "NOT_FOUND",
				message: "Aufnahme mit dieser UID existiert nicht oder gehört nicht dem aktuellen Benutzer."
			})
		}

		await prisma.aufnahme.update({
			where: {
				uid
			},
			data: input
		})
	},
});

export const GET = defineApiRoute({
	meta: {
		description: "Gibt eine spezifische Aufnhame eines Objektes des Benutzers zurück.",
		tags: ["Aufnahme"],
		headers: {
			"Authorization": {
				description: "Ein gültiger Authentifizierungstoken",
				required: true,
				allowEmptyValue: false,
				examples: {
					Bearer: {
						value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
					}
				}
			}
		}
	},
	output: ZodOverlap<OptionalNullable<AufnahmeClient>>(AufnahmeSchema.omit({
		id: true,
		objekt_id: true,
		benutzer_id: true
	}).merge(z.object({
		uid_objekt: UUidWithPrefix
	}))),
	middleware: authorizationMiddleware,
	async fetch(input, context, user) {
		const { uid } = context.params;

		const aufnahme = await prisma.aufnahme.findUnique({
			where: user.rolle === Enums.BenutzerRolle.USER ? {
				uid,
				benutzer_id: user.id
			} : { uid },
			include: {
				objekt: {
					select: {
						uid: true
					}
				}
			}
		});

		if (!aufnahme) {
			throw new APIError({
				code: "NOT_FOUND",
				message: "Aufnahme mit dieser UID existiert nicht oder gehört nicht dem aktuellen Benutzer."
			})
		}

		return exclude({
			uid_objekt: aufnahme.objekt.uid,
			...aufnahme
		}, ["id", "objekt_id", "benutzer_id", "objekt"])
	},
});
