import { notFound } from "next/navigation" import { REDEMPTION } from "@/constants/booking" import { getLocations } from "@/lib/trpc/memoizedRequests" import { generateChildrenString } from "@/components/HotelReservation/utils" import { safeTry } from "@/utils/safeTry" import { convertSearchParamsToObj, type SelectHotelParams } from "@/utils/url" import type { AlternativeHotelsSearchParams, SelectHotelSearchParams, } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams" import type { Child, SelectRateSearchParams, } from "@/types/components/hotelReservation/selectRate/selectRate" import { type HotelLocation, isHotelLocation, type Location, } from "@/types/trpc/routers/hotel/locations" export type ChildrenInRoom = (Child[] | null)[] | null export type ChildrenInRoomString = (string | null)[] | null interface HotelSearchDetails { adultsInRoom: number[] bookingCode?: string childrenInRoom: ChildrenInRoom childrenInRoomString: ChildrenInRoomString city: Location | null hotel: HotelLocation | null noOfRooms: number redemption?: boolean selectHotelParams: SelectHotelParams & { city: string | undefined } } export async function getHotelSearchDetails< T extends | SelectHotelSearchParams | SelectRateSearchParams | AlternativeHotelsSearchParams, >( { searchParams, }: { searchParams: T & { [key: string]: string } }, isAlternativeHotels?: boolean ): Promise | null> { const selectHotelParams = convertSearchParamsToObj(searchParams) const [locations, error] = await safeTry(getLocations()) if (!locations || error) { return null } const hotel = ("hotelId" in selectHotelParams && (locations.find( (location) => isHotelLocation(location) && "operaId" in location && location.operaId === selectHotelParams.hotelId ) as HotelLocation | undefined)) || null if (isAlternativeHotels && !hotel) { return notFound() } const cityName = isAlternativeHotels ? hotel?.relationships.city.name : "city" in selectHotelParams ? (selectHotelParams.city as string | undefined) : undefined const city = (typeof cityName === "string" && locations.find( (location) => location.name.toLowerCase() === cityName.toLowerCase() )) || null if (!city && !hotel) return notFound() if (isAlternativeHotels && (!city || !hotel)) return notFound() let adultsInRoom: number[] = [] let childrenInRoom: ChildrenInRoom = null let childrenInRoomString: ChildrenInRoomString = null const { rooms } = selectHotelParams if (rooms?.length) { adultsInRoom = rooms.map((room) => room.adults ?? 0) childrenInRoom = rooms.map((room) => room.childrenInRoom ?? null) childrenInRoomString = rooms.map((room) => room.childrenInRoom ? generateChildrenString(room.childrenInRoom) : null ) } return { adultsInRoom, bookingCode: selectHotelParams.bookingCode ?? undefined, childrenInRoom, childrenInRoomString, city, hotel, noOfRooms: rooms?.length ?? 0, redemption: selectHotelParams.searchType === REDEMPTION, selectHotelParams: { city: cityName, ...selectHotelParams }, } }