import { differenceInCalendarDays, format, isWeekend } from "date-fns"
import { Suspense } from "react"

import { getBookingConfirmation } from "@/lib/trpc/memoizedRequests"

import BookingConfirmation from "@/components/HotelReservation/BookingConfirmation"
import TrackingSDK from "@/components/TrackingSDK"
import { setLang } from "@/i18n/serverContext"

import {
  TrackingChannelEnum,
  type TrackingSDKHotelInfo,
  type TrackingSDKPageData,
} from "@/types/components/tracking"
import { CurrencyEnum } from "@/types/enums/currency"
import type { LangParams, PageArgs } from "@/types/params"

export default async function BookingConfirmationPage({
  params,
  searchParams,
}: PageArgs<LangParams, { confirmationNumber: string }>) {
  setLang(params.lang)
  const bookingConfirmationPromise = getBookingConfirmation(
    searchParams.confirmationNumber
  )
  const { hotel, booking } = await bookingConfirmationPromise

  const arrivalDate = new Date(booking.checkInDate)
  const departureDate = new Date(booking.checkOutDate)

  const initialPageTrackingData: TrackingSDKPageData = {
    pageId: "booking-confirmation",
    domainLanguage: params.lang,
    channel: TrackingChannelEnum["hotelreservation"],
    pageName: `hotelreservation|confirmation`,
    siteSections: `hotelreservation|confirmation`,
    pageType: "confirmation",
    siteVersion: "new-web",
  }

  const initialHotelsTrackingData: TrackingSDKHotelInfo = {
    searchTerm: searchParams.city,
    arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
    departureDate: format(departureDate, "yyyy-MM-dd"),
    noOfAdults: booking.adults,
    noOfChildren: booking.childrenAges?.length,
    ageOfChildren: booking.childrenAges?.join(","),
    childBedPreference: booking?.extraBedTypes?.map((c) => c.bedType).join("|"),
    noOfRooms: 1, // // TODO: Handle multiple rooms
    duration: differenceInCalendarDays(departureDate, arrivalDate),
    leadTime: differenceInCalendarDays(arrivalDate, new Date()),
    searchType: "hotel",
    bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
    country: hotel?.address.country,
    hotelID: hotel.operaId,
    region: hotel?.address.city,
    rateCode: booking.rateDefinition.rateCode ?? undefined,
    rateCodeType: booking.rateDefinition.title ?? undefined,
    rateCodeName: booking.rateDefinition.rateCode ?? undefined,
    rateCodeCancellationRule:
      booking.rateDefinition?.cancellationText ?? undefined,
    revenueCurrencyCode: CurrencyEnum[booking.currencyCode],
    breakfastOption: booking.rateDefinition.breakfastIncluded
      ? "breakfast buffet"
      : "no breakfast",
    totalPrice: booking.totalPrice,
    //specialRoomType: getSpecialRoomType(booking.packages), TODO: Add
    //roomTypeName: booking.roomTypeCode ?? undefined, TODO: Do we get the name?
    //bedType: bedType?.description, TODO: Can we get bedType?
    roomTypeCode: booking.roomTypeCode ?? undefined,
    roomPrice: booking.roomPrice,
    bnr: booking.confirmationNumber ?? undefined,
  }

  return (
    <>
      <Suspense fallback={null}>
        <TrackingSDK
          pageData={initialPageTrackingData}
          hotelInfo={initialHotelsTrackingData}
        />
      </Suspense>

      <BookingConfirmation
        bookingConfirmationPromise={bookingConfirmationPromise}
      />
    </>
  )
}
