// src/routes/api/admin/anmeldungen/+server.ts

import { json } from '@sveltejs/kit';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export async function GET() {
	try {
		const anmeldungen = await prisma.anmeldung.findMany({
			include: {
				wunsch1: true,
				wunsch2: true,
				wunsch3: true,
				zugewiesen: true,
				praktikum: true,
				pdfs: true
			},
			orderBy: [
				{
					timestamp: 'desc'
				}
			]
		});

		const formattedAnmeldungen = anmeldungen.map((anmeldung) => ({
			id: anmeldung.id,
			anrede: anmeldung.anrede,
			vorname: anmeldung.vorname,
			nachname: anmeldung.nachname,
			email: anmeldung.email,

			geburtsdatum: anmeldung.geburtsdatum,
			strasse: anmeldung.strasse,
			hausnummer: anmeldung.hausnummer,
			ort: anmeldung.ort,
			plz: anmeldung.plz,
			telefon: anmeldung.telefon,
			schulart: anmeldung.schulart,
			schulklasse: anmeldung.schulklasse,
			motivation: anmeldung.motivation,
			alter: anmeldung.alter,

			noteDeutsch: anmeldung.noteDeutsch ? anmeldung.noteDeutsch.toString() : undefined,
			noteMathe: anmeldung.noteMathe ? anmeldung.noteMathe.toString() : undefined,
			sozialverhalten: anmeldung.sozialverhalten,

			// Notfallkontakt
			notfallVorname: anmeldung.notfallVorname,
			notfallNachname: anmeldung.notfallNachname,
			notfallTelefon: anmeldung.notfallTelefon,

			status: mapPrismaStatusToFrontend(anmeldung.status),
			processedAt: anmeldung.processedAt ? anmeldung.processedAt.getTime() : undefined,

			wunsch1: anmeldung.wunsch1
				? {
						id: anmeldung.wunsch1.id,
						name: anmeldung.wunsch1.name
					}
				: undefined,
			wunsch2: anmeldung.wunsch2
				? {
						id: anmeldung.wunsch2.id,
						name: anmeldung.wunsch2.name
					}
				: undefined,
			wunsch3: anmeldung.wunsch3
				? {
						id: anmeldung.wunsch3.id,
						name: anmeldung.wunsch3.name
					}
				: undefined,

			assignedDienststelle: anmeldung.zugewiesen
				? {
						id: anmeldung.zugewiesen.id,
						name: anmeldung.zugewiesen.name
					}
				: undefined,

			zeitraum: anmeldung.praktikum
				? {
						id: anmeldung.praktikum.id,
						bezeichnung: anmeldung.praktikum.bezeichnung,
						startDatum: anmeldung.praktikum.startDatum.toISOString(),
						endDatum: anmeldung.praktikum.endDatum.toISOString()
					}
				: undefined,

			timestamp: anmeldung.timestamp ? anmeldung.timestamp.getTime() : Date.now(),

			pdfs: anmeldung.pdfs || []
		}));

		return json(formattedAnmeldungen);
	} catch (error) {
		console.error('Fehler beim Laden der Anmeldungen:', error);
		return json(
			{ error: 'Fehler beim Laden der Anmeldungen', details: (error as Error).message },
			{ status: 500 }
		);
	}
}

export async function POST({ request, url }) {
	try {
		const id = parseInt(url.searchParams.get('id') || '0');
		const { dienststelleId } = await request.json();

		if (!id || !dienststelleId) {
			return json({ error: 'ID und Dienststelle erforderlich' }, { status: 400 });
		}

		// Prüfen ob Anmeldung existiert und Praktikumszeitraum laden
		const existingAnmeldung = await prisma.anmeldung.findUnique({
			where: { id },
			include: {
				praktikum: true
			}
		});

		if (!existingAnmeldung) {
			return json({ error: 'Anmeldung nicht gefunden' }, { status: 404 });
		}

		if (existingAnmeldung.status === 'ANGENOMMEN') {
			return json({ error: 'Anmeldung bereits angenommen' }, { status: 409 });
		}

		const zeitraumId = existingAnmeldung.praktikumId;

		if (!zeitraumId) {
			return json(
				{ error: 'Kein Praktikumszeitraum für diese Anmeldung gefunden' },
				{ status: 400 }
			);
		}

		// Prüfen ob ZeitraumPlaetze Eintrag existiert und freie Plätze vorhanden sind
		const zeitraumPlaetze = await prisma.zeitraumPlaetze.findUnique({
			where: {
				zeitraumId_dienststelleId: {
					zeitraumId: zeitraumId,
					dienststelleId: dienststelleId
				}
			}
		});

		if (!zeitraumPlaetze) {
			return json(
				{
					error: 'Keine Plätze für diese Dienststelle in diesem Zeitraum konfiguriert'
				},
				{ status: 400 }
			);
		}

		// Prüfen ob noch Plätze frei sind (plaetze > 0)
		if (zeitraumPlaetze.plaetze <= 0) {
			return json(
				{
					error: 'Keine freien Plätze mehr für diese Dienststelle in diesem Zeitraum verfügbar.'
				},
				{ status: 400 }
			);
		}

		// Anmeldung als angenommen markieren und Plätze in ZeitraumPlaetze reduzieren
		// Verwendung von $transaction für Atomarität (Race Condition vermeiden)
		await prisma.$transaction(async (tx) => {
			// Nochmal prüfen innerhalb der Transaktion
			const aktuellerStand = await tx.zeitraumPlaetze.findUnique({
				where: {
					zeitraumId_dienststelleId: {
						zeitraumId: zeitraumId,
						dienststelleId: dienststelleId
					}
				}
			});

			if (!aktuellerStand || aktuellerStand.plaetze <= 0) {
				throw new Error('Keine freien Plätze mehr verfügbar');
			}

			// Anmeldung aktualisieren
			await tx.anmeldung.update({
				where: { id },
				data: {
					status: 'ANGENOMMEN',
					zugewiesenId: dienststelleId,
					processedAt: new Date()
				}
			});

			// Plätze in ZeitraumPlaetze reduzieren
			await tx.zeitraumPlaetze.update({
				where: {
					zeitraumId_dienststelleId: {
						zeitraumId: zeitraumId,
						dienststelleId: dienststelleId
					}
				},
				data: {
					plaetze: {
						decrement: 1
					}
				}
			});
		});

		return json({ success: true });
	} catch (error) {
		console.error('Fehler beim Annehmen der Anmeldung:', error);

		// Spezifische Fehlermeldung für "keine Plätze"
		if ((error as Error).message === 'Keine freien Plätze mehr verfügbar') {
			return json(
				{
					error: 'Keine freien Plätze mehr für diese Dienststelle in diesem Zeitraum verfügbar.'
				},
				{ status: 400 }
			);
		}

		return json(
			{ error: 'Fehler beim Annehmen der Anmeldung', details: (error as Error).message },
			{ status: 500 }
		);
	}
}

export async function PATCH({ request, url }) {
	try {
		const id = parseInt(url.searchParams.get('id') || '0');
		const { action } = await request.json();

		if (!id) {
			return json({ error: 'ID erforderlich' }, { status: 400 });
		}

		let updateData = {};

		switch (action) {
			case 'reject':
				updateData = {
					status: 'ABGELEHNT',
					processedAt: new Date()
				};
				break;

			case 'set_processing':
				const anmeldung = await prisma.anmeldung.findUnique({
					where: { id }
				});

				if (!anmeldung) {
					return json({ error: 'Anmeldung nicht gefunden' }, { status: 404 });
				}

				updateData = {
					status: 'BEARBEITUNG',
					processedAt: new Date()
				};
				break;

			case 'reset_processing':
				updateData = {
					status: 'OFFEN',
					processedAt: null
				};
				break;

			default:
				return json({ error: 'Unbekannte Aktion' }, { status: 400 });
		}

		await prisma.anmeldung.update({
			where: { id },
			data: updateData
		});

		return json({ success: true });
	} catch (error) {
		console.error('Fehler beim Aktualisieren der Anmeldung:', error);
		return json(
			{ error: 'Fehler beim Aktualisieren der Anmeldung', details: (error as Error).message },
			{ status: 500 }
		);
	}
}

export async function DELETE({ url }) {
	try {
		const id = parseInt(url.searchParams.get('id') || '0');

		if (!id) {
			return json({ error: 'ID erforderlich' }, { status: 400 });
		}

		// Einfach löschen - Plätze werden NICHT zurückgegeben (gewolltes Verhalten)
		await prisma.anmeldung.delete({
			where: { id }
		});

		return json({ success: true });
	} catch (error) {
		console.error('Fehler beim Löschen der Anmeldung:', error);
		return json(
			{ error: 'Fehler beim Löschen der Anmeldung', details: (error as Error).message },
			{ status: 500 }
		);
	}
}

// Hilfsfunktion: Prisma Status zu Frontend Status
function mapPrismaStatusToFrontend(prismaStatus: string): string {
	const statusMap: Record<string, string> = {
		OFFEN: 'pending',
		BEARBEITUNG: 'processing',
		ANGENOMMEN: 'accepted',
		ABGELEHNT: 'rejected'
	};

	return statusMap[prismaStatus] || 'pending';
}
