import { getHotelData } from "@/lib/trpc/memoizedRequests" import { serverClient } from "@/lib/trpc/server" import { getLang } from "@/i18n/serverContext" import type { AvailabilityInput } from "@/types/components/hotelReservation/selectHotel/availabilityInput" import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" import type { CategorizedFilters, Filter, } from "@/types/components/hotelReservation/selectHotel/hotelFilters" import type { HotelPin } from "@/types/components/hotelReservation/selectHotel/map" import { HotelListingEnum } from "@/types/enums/hotelListing" const hotelSurroundingsFilterNames = [ "Hotel surroundings", "Hotel omgivelser", "Hotelumgebung", "Hotellia lähellä", "Hotellomgivelser", "Omgivningar", ] export async function fetchAvailableHotels( input: AvailabilityInput ): Promise { const availableHotels = await serverClient().hotel.availability.hotels(input) if (!availableHotels) throw new Error() const language = getLang() const hotelMap = new Map() availableHotels.availability.forEach((hotel) => { const existingHotel = hotelMap.get(hotel.hotelId) if (existingHotel) { if (hotel.ratePlanSet === HotelListingEnum.RatePlanSet.PUBLIC) { existingHotel.bestPricePerNight.regularAmount = hotel.bestPricePerNight?.regularAmount } else if (hotel.ratePlanSet === HotelListingEnum.RatePlanSet.MEMBER) { existingHotel.bestPricePerNight.memberAmount = hotel.bestPricePerNight?.memberAmount } } else { hotelMap.set(hotel.hotelId, { ...hotel }) } }) const hotels = Array.from(hotelMap.values()).map(async (hotel) => { const hotelData = await getHotelData({ hotelId: hotel.hotelId.toString(), language, }) if (!hotelData) throw new Error() return { hotelData: hotelData.data.attributes, price: hotel.bestPricePerNight, } }) return await Promise.all(hotels) } export function getFiltersFromHotels(hotels: HotelData[]): CategorizedFilters { const filters = hotels.flatMap((hotel) => hotel.hotelData.detailedFacilities) const uniqueFilterIds = [...new Set(filters.map((filter) => filter.id))] const filterList: Filter[] = uniqueFilterIds .map((filterId) => filters.find((filter) => filter.id === filterId)) .filter((filter): filter is Filter => filter !== undefined) return filterList.reduce( (acc, filter) => { if (filter.filter && hotelSurroundingsFilterNames.includes(filter.filter)) return { facilityFilters: acc.facilityFilters, surroundingsFilters: [...acc.surroundingsFilters, filter], } return { facilityFilters: [...acc.facilityFilters, filter], surroundingsFilters: acc.surroundingsFilters, } }, { facilityFilters: [], surroundingsFilters: [] } ) } export function getHotelPins(hotels: HotelData[]): HotelPin[] { return hotels.map((hotel) => ({ coordinates: { lat: hotel.hotelData.location.latitude, lng: hotel.hotelData.location.longitude, }, name: hotel.hotelData.name, publicPrice: hotel.price?.regularAmount ?? null, memberPrice: hotel.price?.memberAmount ?? null, currency: hotel.price?.currency || null, images: [ hotel.hotelData.hotelContent.images, ...(hotel.hotelData.gallery?.heroImages ?? []), ], amenities: hotel.hotelData.detailedFacilities.slice(0, 3), ratings: hotel.hotelData.ratings?.tripAdvisor.rating ?? null, })) } export function getCentralCoordinates(hotels: HotelPin[]) { const centralCoordinates = hotels.reduce( (acc, pin) => { acc.lat += pin.coordinates.lat acc.lng += pin.coordinates.lng return acc }, { lat: 0, lng: 0 } ) centralCoordinates.lat /= hotels.length centralCoordinates.lng /= hotels.length return centralCoordinates }