import { type HotelListingHotelData, type HotelSortItem, HotelSortOption, } from "@scandic-hotels/trpc/types/hotel" import type { HotelFilter, HotelFilters, } from "@scandic-hotels/trpc/routers/hotels/filters/output" const HOTEL_SORTING_STRATEGIES: Partial< Record< HotelSortOption, (a: HotelListingHotelData, b: HotelListingHotelData) => number > > = { [HotelSortOption.Name]: function (a, b) { return a.hotel.name.localeCompare(b.hotel.name) }, [HotelSortOption.TripAdvisorRating]: function (a, b) { return (b.hotel.tripadvisor ?? 0) - (a.hotel.tripadvisor ?? 0) }, } export function getFilteredHotels( hotels: HotelListingHotelData[], filters: HotelFilter[] ) { if (filters.length) { return hotels.filter(({ hotel }) => filters.every((filter) => { const matchesFacility = hotel.detailedFacilities.some( (facility) => facility.id === Number(filter.id) ) const matchesCountry = hotel.countryCode === filter.id return matchesFacility || matchesCountry }) ) } return hotels } export function getSortedHotels( hotels: HotelListingHotelData[], sortOption: HotelSortOption ) { const sortFn = HOTEL_SORTING_STRATEGIES[sortOption] return sortFn ? [...hotels].sort(sortFn) : hotels } export function isValidSortOption( value: string, sortItems: HotelSortItem[] ): value is HotelSortOption { return sortItems.map((item) => item.value).includes(value as HotelSortOption) } export function getFiltersWithHotelCount( hotelFilters: HotelFilters, hotels: HotelListingHotelData[] ): HotelFilters { const flattenedFilters = Object.values(hotelFilters).flat() const filterHotelCounts: Record = {} hotels.forEach(({ hotel }) => { hotel.detailedFacilities.forEach((facility) => { filterHotelCounts[facility.id] = (filterHotelCounts[facility.id] || 0) + 1 }) if (hotel.countryCode) { filterHotelCounts[hotel.countryCode] = (filterHotelCounts[hotel.countryCode] || 0) + 1 } }) return flattenedFilters.reduce( (acc, filter) => { if (filter.filterType === "facility") { acc.facilityFilters.push({ ...filter, hotelCount: filterHotelCounts[filter.id] ?? 0, }) } else if (filter.filterType === "surroundings") { acc.surroundingsFilters.push({ ...filter, hotelCount: filterHotelCounts[filter.id] ?? 0, }) } else if (filter.filterType === "country") { acc.countryFilters.push({ ...filter, filterType: "country", hotelCount: filterHotelCounts[filter.id] ?? 0, }) } return acc }, { facilityFilters: [], surroundingsFilters: [], countryFilters: [], } as HotelFilters ) }