import type { UpdateBookingDetailsResponse } from '~~/shared/booking' import { getSeatCount } from '~~/shared/booking' import { requireAuth } from '../../utils/auth' import { getBookingById, getBookingInventorySummary, getActiveBookingModeOptionByCode, getActiveTicketCatalogItemByCode, clearBookingTransactionDocument, updateBookingDetails } from '../../utils/booking-repository' import { parseUpdateBookingDetailsInput } from '../../utils/bookings' import { deleteTransactionDocument } from '../../utils/transaction-documents' import { getRequiredRouteParam, httpError } from '../../utils/http' export default defineEventHandler(async (event): Promise => { const auth = await requireAuth(event) const bookingId = getRequiredRouteParam(event, 'id', 'Booking ID') const body = await readBody<{ customerName?: string customerPhone?: string bookingMode?: string | null quantity?: number ticketType?: string paymentMethod?: string | null remark?: string | null }>(event) const existingBooking = await getBookingById(bookingId, auth.user.role === 'super_admin' ? undefined : { personInChargeId: auth.user.id }) if (!existingBooking) { httpError(404, 'Booking not found') } const input = parseUpdateBookingDetailsInput(body) const [bookingMode, ticket] = await Promise.all([ getActiveBookingModeOptionByCode(input.bookingMode), getActiveTicketCatalogItemByCode(input.ticketType) ]) if (!bookingMode) { httpError(400, 'Booking mode is invalid') } if (!ticket) { httpError(400, 'Ticket category is invalid') } if (bookingMode.eventId !== ticket.eventId || bookingMode.eventId !== existingBooking.event.id) { httpError(400, 'Booking mode and ticket category must belong to the same event') } const seatCount = getSeatCount(bookingMode, input.quantity) const totalPrice = seatCount * ticket.price const seatIncrease = Math.max(seatCount - existingBooking.seatCount, 0) if (existingBooking.status === 'confirmed' && seatIncrease > 0) { const summary = await getBookingInventorySummary() if (summary.leftSeats !== null && seatIncrease > summary.leftSeats) { httpError(409, `Total seats cannot exceed the remaining capacity by ${seatIncrease - summary.leftSeats} seats`) } } const booking = await updateBookingDetails({ bookingId, customerName: input.customerName, customerPhone: input.customerPhone, bookingModeId: bookingMode.id, bookingMode: bookingMode.value, quantity: input.quantity, seatCount, ticketTypeId: ticket.id, ticketType: ticket.value, unitPrice: ticket.price, totalPrice, paymentMethod: input.paymentMethod, remark: input.remark, personInChargeId: auth.user.role === 'super_admin' ? undefined : auth.user.id }) if (!booking) { httpError(404, 'Booking not found') } if (input.paymentMethod === 'cash') { const cleared = await clearBookingTransactionDocument({ bookingId, personInChargeId: auth.user.role === 'super_admin' ? undefined : auth.user.id }) if (cleared) { await deleteTransactionDocument(cleared.previousStorageName) return { booking: cleared.booking } } } return { booking } })