import { NextRequest, NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth'; import { prisma } from '@/lib/prisma'; import { nextcloudCalendar } from '@/lib/nextcloud-calendar'; function generateBookingNumber(): string { const date = new Date(); const year = date.getFullYear().toString().slice(-2); const month = String(date.getMonth() + 1).padStart(2, '0'); const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0'); return `STM-${year}${month}-${random}`; } export async function POST(request: NextRequest) { try { const session = await getServerSession(authOptions); if (!session || session.user.role !== 'ADMIN') { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const body = await request.json(); const eventDate = new Date(body.eventDate); const startOfDay = new Date(eventDate); startOfDay.setHours(0, 0, 0, 0); const endOfDay = new Date(eventDate); endOfDay.setHours(23, 59, 59, 999); const availablePhotobox = await prisma.photobox.findFirst({ where: { locationId: body.locationId, model: body.model, active: true, NOT: { bookings: { some: { eventDate: { gte: startOfDay, lte: endOfDay, }, status: { in: ['RESERVED', 'CONFIRMED'], }, }, }, }, }, }); if (!availablePhotobox) { return NextResponse.json( { error: 'Keine Fotobox verfügbar für dieses Datum' }, { status: 409 } ); } const booking = await prisma.booking.create({ data: { bookingNumber: generateBookingNumber(), locationId: body.locationId, photoboxId: availablePhotobox.id, status: 'RESERVED', customerName: body.customerName, customerEmail: body.customerEmail, customerPhone: body.customerPhone, customerAddress: body.customerAddress, customerCity: body.customerCity, customerZip: body.customerZip, invoiceType: body.invoiceType, companyName: body.companyName, eventDate: new Date(body.eventDate), eventAddress: body.eventAddress, eventCity: body.eventCity, eventZip: body.eventZip, eventLocation: body.eventLocation, setupTimeStart: new Date(body.setupTimeStart), setupTimeLatest: new Date(body.setupTimeLatest), dismantleTimeEarliest: body.dismantleTimeEarliest ? new Date(body.dismantleTimeEarliest) : null, dismantleTimeLatest: body.dismantleTimeLatest ? new Date(body.dismantleTimeLatest) : null, calculatedPrice: body.calculatedPrice, notes: body.notes, }, include: { location: true, photobox: true, }, }); await prisma.notification.create({ data: { type: 'NEW_BOOKING_MANUAL', title: 'Neue manuelle Buchung', message: `${body.customerName} - ${eventDate.toLocaleDateString('de-DE')}`, metadata: { bookingId: booking.id, bookingNumber: booking.bookingNumber, }, }, }); if (Array.isArray(body.equipmentIds) && body.equipmentIds.length > 0) { await prisma.bookingEquipment.createMany({ data: body.equipmentIds.map((eqId: string) => ({ bookingId: booking.id, equipmentId: eqId, })), }); } try { await nextcloudCalendar.syncBookingToCalendar(booking); } catch (calError) { console.error('Calendar sync error after booking creation:', calError); } return NextResponse.json({ success: true, booking, }); } catch (error: any) { console.error('Booking creation error:', error); return NextResponse.json( { error: error.message || 'Internal server error' }, { status: 500 } ); } }