import { notFound } from "next/navigation"

import { safeTry } from "@scandic-hotels/common/utils/safeTry"

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

import TrackingSDK from "@/components/TrackingSDK"
import { getLang } from "@/i18n/serverContext"
import { getHotelSearchDetails } from "@/utils/hotelSearchDetails"

import { getHotelPins } from "../../HotelCardDialogListing/utils"
import { getFiltersFromHotels, getHotels } from "../helpers"
import { getSelectHotelTracking } from "../tracking"
import SelectHotelMap from "."

import type { SelectHotelMapContainerProps } from "@/types/components/hotelReservation/selectHotel/map"

export async function SelectHotelMapContainer({
  booking,
  isAlternativeHotels,
}: SelectHotelMapContainerProps) {
  const lang = await getLang()
  const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
  const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
  const getHotelSearchDetailsPromise = safeTry(
    getHotelSearchDetails(booking, isAlternativeHotels)
  )

  const [searchDetails] = await getHotelSearchDetailsPromise

  if (!searchDetails) {
    return notFound()
  }

  const {
    city,
    cityIdentifier,
    hotel: isAlternativeFor,
    redemption,
  } = searchDetails

  if (!city) {
    return notFound()
  }

  const hotels = await getHotels({
    fromDate: booking.fromDate,
    toDate: booking.toDate,
    rooms: booking.rooms,
    isAlternativeFor,
    bookingCode: booking.bookingCode,
    city,
    redemption: !!redemption,
  })

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

  const arrivalDate = new Date(booking.fromDate)
  const departureDate = new Date(booking.toDate)
  const isRedemptionAvailability = redemption
    ? hotels.some(
        (hotel) => hotel.availability.productType?.redemptions?.length
      )
    : false

  const isBookingCodeRateAvailable = booking.bookingCode
    ? hotels?.some((hotel) => hotel.availability.bookingCode)
    : false

  const { hotelsTrackingData, pageTrackingData } = getSelectHotelTracking({
    lang,
    pageId: isAlternativeFor ? "alternative-hotels" : "select-hotel",
    pageName: isAlternativeHotels
      ? "hotelreservation|alternative-hotels|mapview"
      : "hotelreservation|select-hotel|mapview",
    siteSections: isAlternativeHotels
      ? "hotelreservation|altervative-hotels|mapview"
      : "hotelreservation|select-hotel|mapview",
    arrivalDate,
    departureDate,
    rooms: booking.rooms,
    hotelsResult: hotels.length,
    searchTerm: isAlternativeFor ? booking.hotelId : cityIdentifier,
    country: hotels?.[0]?.hotel.address.country,
    hotelCity: hotels?.[0]?.hotel.address.city,
    bookingCode: booking.bookingCode,
    isBookingCodeRateAvailable,
    isRedemption: redemption,
    isRedemptionAvailable: isRedemptionAvailability,
  })

  return (
    <>
      <SelectHotelMap
        apiKey={googleMapsApiKey}
        hotelPins={hotelPins}
        mapId={googleMapId}
        hotels={hotels}
        filterList={filterList}
        cityCoordinates={cityCoordinates}
        bookingCode={booking.bookingCode}
        isBookingCodeRateAvailable={isBookingCodeRateAvailable}
        isAlternativeHotels={isAlternativeHotels}
      />
      <TrackingSDK pageData={pageTrackingData} hotelInfo={hotelsTrackingData} />
    </>
  )
}
