import type { BookingCapacitySettings, BookingMode, PublicBooking, TicketType } from '~~/shared/booking' import { formatBookingCurrency, getBookingModeLabel, getTicketCatalogItem, isBookingMode, isTicketType } from '~~/shared/booking' import { hasValidFullName, isValidPhoneNumber, normalizeFullName, normalizePhoneNumber } from '~~/shared/auth' import { assertBadRequest } from './http' export function parseCreateBookingInput(body: { customerName?: string customerPhone?: string bookingMode?: BookingMode quantity?: number ticketType?: TicketType personInChargeId?: string }) { const customerName = normalizeFullName(body.customerName || '') const customerPhone = normalizePhoneNumber(body.customerPhone || '') const bookingMode = body.bookingMode const ticketType = body.ticketType const quantity = Number(body.quantity) const personInChargeId = (body.personInChargeId || '').trim() assertBadRequest(hasValidFullName(customerName), 'Guest or organizer name must be at least 2 characters') assertBadRequest(isValidPhoneNumber(customerPhone), 'Phone number must contain 8 to 15 digits') assertBadRequest(isBookingMode(bookingMode), 'Booking mode is invalid') assertBadRequest(Number.isInteger(quantity) && quantity >= 1, 'Quantity must be a whole number of at least 1') assertBadRequest(isTicketType(ticketType), 'Ticket category is invalid') assertBadRequest(personInChargeId, 'Person in charge is required') return { customerName, customerPhone, bookingMode, quantity, ticketType, personInChargeId } } export function buildBookingMessage(booking: PublicBooking, confirmationUrl: string) { const ticket = getTicketCatalogItem(booking.ticketType) const ticketLabel = ticket?.label || booking.ticketType.toUpperCase() return [ "I'd like to book tickets for the DAP Johor 60th Anniversary Celebration.", '', `Name: ${booking.customerName}`, `Phone Number: ${booking.customerPhone}`, `Booking Mode: ${getBookingModeLabel(booking.bookingMode)}`, `Quantity: ${booking.quantity}`, `Ticket Category: ${ticketLabel}`, `Seats Covered: ${booking.seatCount}`, `Total Price: ${formatBookingCurrency(booking.totalPrice)}`, '', 'PIC confirmation link:', confirmationUrl ].join('\n') } export function parseBookingCapacityInput(body: { totalTables?: number | string | null }): Pick { const totalTables = parseOptionalInteger(body.totalTables) assertBadRequest(totalTables === null || totalTables >= 0, 'Total tables must be 0 or greater') return { totalTables } } function parseOptionalInteger(value: number | string | null | undefined) { if (value === null || value === undefined || value === '') { return null } const parsed = typeof value === 'number' ? value : Number.parseInt(String(value), 10) assertBadRequest(Number.isInteger(parsed), 'Capacity values must be whole numbers') return parsed }