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

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

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

import { invertedBedTypeMap } from "../utils"
import Confirmation from "./Confirmation"

import type { BookingConfirmationProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
import {
  TrackingChannelEnum,
  type TrackingSDKHotelInfo,
  type TrackingSDKPageData,
  type TrackingSDKPaymentInfo,
} from "@/types/components/tracking"

export default async function BookingConfirmation({
  confirmationNumber,
}: BookingConfirmationProps) {
  const lang = getLang()
  const { booking, hotel, room } =
    await getBookingConfirmation(confirmationNumber)

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

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

  const initialHotelsTrackingData: TrackingSDKHotelInfo = {
    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
      ?.flatMap((c) => Array(c.quantity).fill(invertedBedTypeMap[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: 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: room?.bedType.name,
    roomTypeCode: booking.roomTypeCode ?? undefined,
    roomPrice: booking.roomPrice,
    bnr: booking.confirmationNumber ?? undefined,
  }

  const paymentInfo: TrackingSDKPaymentInfo = {
    paymentStatus: "confirmed",
  }

  return (
    <>
      <Confirmation booking={booking} hotel={hotel} room={room} />
      <Suspense fallback={null}>
        <TrackingSDK
          pageData={initialPageTrackingData}
          hotelInfo={initialHotelsTrackingData}
          paymentInfo={paymentInfo}
        />
      </Suspense>
    </>
  )
}
