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

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

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

import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate"
import type { Lang } from "@/constants/languages"

export type Props = {
  hotelId: number
  fromDate: Date
  toDate: Date
  adultCount: number
  childArray?: Child[]
  lang: Lang
}

export async function RoomsContainer({
  hotelId,
  fromDate,
  toDate,
  adultCount,
  childArray,
  lang,
}: Props) {
  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(
    getHotelData({ hotelId: hotelId.toString(), language: lang })
  )

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

  const roomsAvailabilityPromise = 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 [roomsAvailability, roomsAvailabilityError] =
    await roomsAvailabilityPromise

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

  if (roomsAvailabilityError) {
    // TODO: show proper error component
    console.error("[RoomsContainer] unable to fetch room availability")
    return null
  }

  if (!roomsAvailability) {
    // HotelInfoCard has the logic for displaying when there are no rooms available
    return null
  }

  return (
    <Rooms
      availablePackages={packages ?? []}
      roomsAvailability={roomsAvailability}
      roomCategories={hotelData?.included?.rooms ?? []}
      hotelType={hotelData?.data.attributes?.hotelType}
      isUserLoggedIn={isUserLoggedIn}
    />
  )
}
