import { env } from "@/env/server"
import { getCityCoordinates } from "@/lib/trpc/memoizedRequests"

import {
  fetchAvailableHotels,
  getFiltersFromHotels,
} from "@/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils"
import { safeTry } from "@/utils/safeTry"

import { getHotelPins } from "../../HotelCardDialogListing/utils"
import SelectHotelMap from "."

import type {
  HotelData,
  NullableHotelData,
} from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
import type { Location } from "@/types/trpc/routers/hotel/locations"

function isHotelData(hotel: NullableHotelData): hotel is HotelData {
  return hotel !== null && hotel !== undefined
}

type Props = {
  city: Location
  searchParams: SelectHotelSearchParams
  adultsInRoom: number
  childrenInRoom: string | undefined
}

export async function SelectHotelMapContainer({
  city,
  searchParams,
  adultsInRoom,
  childrenInRoom,
}: Props) {
  const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
  const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY

  const fetchAvailableHotelsPromise = safeTry(
    fetchAvailableHotels({
      cityId: city.id,
      roomStayStartDate: searchParams.fromDate,
      roomStayEndDate: searchParams.toDate,
      adults: adultsInRoom,
      children: childrenInRoom,
    })
  )

  const [hotels, hotelsError] = await fetchAvailableHotelsPromise

  if (hotelsError) {
    // TODO: show proper error component
    console.error("[SelectHotelMapContainer] unable to fetch hotels")
    return null
  }

  const validHotels = hotels?.filter(isHotelData) || []

  const hotelPins = getHotelPins(validHotels)
  const filterList = getFiltersFromHotels(validHotels)
  const cityCoordinates = await getCityCoordinates({
    city: city.name,
    hotel: { address: hotels?.[0]?.hotelData?.address.streetAddress },
  })

  return (
    <SelectHotelMap
      apiKey={googleMapsApiKey}
      hotelPins={hotelPins}
      mapId={googleMapId}
      hotels={validHotels}
      filterList={filterList}
      cityCoordinates={cityCoordinates}
    />
  )
}
