import type { RoomParam } from "@/types/components/hotelReservation/selectRate/section" import type { RoomConfiguration } from "@/server/routers/hotels/output" /** * Get the lowest priced room for each room type that appears more than once. */ export function filterDuplicateRoomTypesByLowestPrice( roomConfigurations: RoomConfiguration[] ): RoomConfiguration[] { const roomTypeCount = roomConfigurations.reduce( (acc, room) => { acc[room.roomType] = (acc[room.roomType] || 0) + 1 return acc }, {} as Record ) const duplicateRoomTypes = new Set( Object.keys(roomTypeCount).filter((roomType) => roomTypeCount[roomType] > 1) ) const roomMap = new Map() roomConfigurations.forEach((room) => { const { roomType, products } = room if (!duplicateRoomTypes.has(roomType)) { roomMap.set(roomType, room) return } products.forEach((product) => { const { productType } = product const publicProduct = productType.public || { requestedPrice: null, localPrice: null, } const memberProduct = productType.member || { requestedPrice: null, localPrice: null, } const { requestedPrice: publicRequestedPrice, localPrice: publicLocalPrice, } = publicProduct const { requestedPrice: memberRequestedPrice, localPrice: memberLocalPrice, } = memberProduct const previousLowest = roomMap.get(roomType) const currentRequestedPrice = Math.min( Number(publicRequestedPrice?.pricePerNight) ?? Infinity, Number(memberRequestedPrice?.pricePerNight) ?? Infinity ) const currentLocalPrice = Math.min( Number(publicLocalPrice?.pricePerNight) ?? Infinity, Number(memberLocalPrice?.pricePerNight) ?? Infinity ) if ( !previousLowest || currentRequestedPrice < Math.min( Number( previousLowest.products[0].productType.public.requestedPrice ?.pricePerNight ) ?? Infinity, Number( previousLowest.products[0].productType.member?.requestedPrice ?.pricePerNight ) ?? Infinity ) || (currentRequestedPrice === Math.min( Number( previousLowest.products[0].productType.public.requestedPrice ?.pricePerNight ) ?? Infinity, Number( previousLowest.products[0].productType.member?.requestedPrice ?.pricePerNight ) ?? Infinity ) && currentLocalPrice < Math.min( Number( previousLowest.products[0].productType.public.localPrice ?.pricePerNight ) ?? Infinity, Number( previousLowest.products[0].productType.member?.localPrice ?.pricePerNight ) ?? Infinity )) ) { roomMap.set(roomType, room) } }) }) return Array.from(roomMap.values()) } /** * Parse the room params from the search params. */ export function parseRoomParams(searchParams: URLSearchParams): RoomParam[] { const rooms: RoomParam[] = [] // Collect all param keys and sort them to ensure correct order const paramKeys = Array.from(searchParams.keys()).sort() for (const key of paramKeys) { const roomRegex = /^room\[(\d+)\]\.(.+)/ const roomMatch = roomRegex.exec(key) if (!roomMatch) continue const [, roomIndex, param] = roomMatch const value = searchParams.get(key) if (!value) continue // Initialize room if it doesn't exist if (!rooms[Number(roomIndex)]) rooms[Number(roomIndex)] = { adults: 1 } // Handle adults if (param === "adults") { rooms[Number(roomIndex)].adults = Number(value) continue } // Handle children const childRegex = /child\[(\d+)\]\.(.+)/ const childMatch = childRegex.exec(param) if (childMatch) { const [, childIndex, childParam] = childMatch const room = rooms[Number(roomIndex)] if (!room.children) room.children = [] // Set child properties if (childParam === "age" && room.children) { room.children[Number(childIndex)] = { age: Number(value), bed: Number(value), } } else if (childParam === "bed" && room.children?.[Number(childIndex)]) room.children[Number(childIndex)].bed = Number(value) } } return rooms }