import { NextResponse } from 'next/server'; import { auth } from '@/lib/auth/config'; import { prisma } from '@/lib/db/prisma'; import { createReservationSchema } from '@/lib/validations/reservation'; import { sendEmail, buildReservationConfirmationHtml } from '@/lib/email'; export async function POST(request: Request) { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ error: 'Autenticação necessária.' }, { status: 401 }); } const body = await request.json(); const parsed = createReservationSchema.safeParse(body); if (!parsed.success) { return NextResponse.json( { error: 'Dados inválidos.', details: parsed.error.flatten() }, { status: 400 } ); } const { animalId, date, notes } = parsed.data; // Verificar que o animal existe e está disponível const animal = await prisma.animal.findUnique({ where: { id: animalId }, include: { shelter: { select: { name: true } } }, }); if (!animal) { return NextResponse.json({ error: 'Animal não encontrado.' }, { status: 404 }); } if (animal.status !== 'AVAILABLE') { return NextResponse.json({ error: 'Animal não disponível para reserva.' }, { status: 409 }); } // Criar reserva + marcar animal como RESERVED em transacção const reservation = await prisma.$transaction(async (tx) => { const res = await tx.reservation.create({ data: { userId: session.user!.id!, animalId, date: new Date(date), status: 'PENDING', notes, }, include: { user: { select: { name: true, email: true } }, animal: { select: { name: true, shelter: { select: { name: true } } } }, }, }); await tx.animal.update({ where: { id: animalId }, data: { status: 'RESERVED' }, }); return res; }); // Enviar email de confirmação (não bloqueia a resposta) sendEmail({ to: reservation.user.email, subject: `Reserva confirmada — ${reservation.animal.name} 🐾`, html: buildReservationConfirmationHtml({ userName: reservation.user.name, animalName: reservation.animal.name, shelterName: reservation.animal.shelter.name, date: new Date(date).toLocaleDateString('pt-PT', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', }), }), }).catch(console.error); return NextResponse.json(reservation, { status: 201 }); } export async function GET(request: Request) { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ error: 'Autenticação necessária.' }, { status: 401 }); } const reservations = await prisma.reservation.findMany({ where: { userId: session.user.id }, include: { animal: { include: { photos: { where: { isPrimary: true }, take: 1 }, shelter: { select: { name: true, district: true } }, }, }, }, orderBy: { date: 'desc' }, }); return NextResponse.json(reservations); }