import { dt } from "@/lib/dt"
import {
  getHotel,
  getPackages,
  getRoomsAvailability,
} from "@/lib/trpc/memoizedRequests"

import { auth } from "@/auth"
import { getIntl } from "@/i18n"
import { safeTry } from "@/utils/safeTry"
import { isValidSession } from "@/utils/session"

import { generateChildrenString } from "../../utils"
import { combineRoomAvailabilities } from "../utils"
import Rooms from "."

import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import type { RoomsContainerProps } from "@/types/components/hotelReservation/selectRate/roomsContainer"

export async function RoomsContainer({
  adultArray,
  childArray,
  fromDate,
  hotelId,
  lang,
  toDate,
}: RoomsContainerProps) {
  const session = await auth()
  const isUserLoggedIn = isValidSession(session)

  const fromDateString = dt(fromDate).format("YYYY-MM-DD")
  const toDateString = dt(toDate).format("YYYY-MM-DD")

  const hotelDataPromise = safeTry(
    getHotel({
      hotelId: hotelId.toString(),
      isCardOnlyPayment: false,
      language: lang,
    })
  )

  const packagesPromise = safeTry(
    getPackages({
      hotelId: hotelId.toString(),
      startDate: fromDateString,
      endDate: toDateString,
      adults: adultArray[0],
      children: childArray ? childArray.length : undefined,
      packageCodes: [
        RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
        RoomPackageCodeEnum.PET_ROOM,
        RoomPackageCodeEnum.ALLERGY_ROOM,
      ],
    })
  )

  const uniqueAdultCounts = [...new Set(adultArray)]
  const roomsAvailabilityPromises = uniqueAdultCounts.map((adultCount) => {
    return safeTry(
      getRoomsAvailability({
        hotelId: hotelId,
        roomStayStartDate: fromDateString,
        roomStayEndDate: toDateString,
        adults: adultCount,
        children:
          childArray && childArray.length > 0
            ? generateChildrenString(childArray)
            : undefined,
      })
    )
  })

  const [hotelData, hotelDataError] = await hotelDataPromise
  const [packages, packagesError] = await packagesPromise
  const roomsAvailabilityResults = await Promise.all(roomsAvailabilityPromises)

  const roomsAvailability = combineRoomAvailabilities({
    availabilityResults: roomsAvailabilityResults,
  })

  const intl = await getIntl(lang)

  if (packagesError) {
    // TODO: Log packages error
    console.error("[RoomsContainer] unable to fetch packages")
  }

  if (!hotelData) {
    // TODO: Log hotel data error
    console.error("[RoomsContainer] unable to fetch hotel data")
    return null
  }

  return (
    <Rooms
      availablePackages={packages ?? []}
      hotelType={hotelData?.hotel.hotelType}
      isUserLoggedIn={isUserLoggedIn}
      roomsAvailability={roomsAvailability}
      roomCategories={hotelData?.roomCategories ?? []}
      vat={hotelData.hotel.vat}
    />
  )
}
