import { cookies } from "next/headers"
import { notFound } from "next/navigation"
import { Suspense } from "react"

import { FamilyAndFriendsCodes } from "@/constants/booking"
import {
  getBreakfastPackages,
  getHotel,
  getProfileSafely,
  getSelectedRoomsAvailabilityEnterDetails,
} from "@/lib/trpc/memoizedRequests"

import HotelHeader from "@/components/HotelReservation/EnterDetails/Header"
import Payment from "@/components/HotelReservation/EnterDetails/Payment"
import Multiroom from "@/components/HotelReservation/EnterDetails/Room/Multiroom"
import RoomOne from "@/components/HotelReservation/EnterDetails/Room/One"
import DesktopSummary from "@/components/HotelReservation/EnterDetails/Summary/Desktop"
import MobileSummary from "@/components/HotelReservation/EnterDetails/Summary/Mobile"
import EnterDetailsTrackingWrapper from "@/components/HotelReservation/EnterDetails/Tracking"
import FnFNotAllowedAlert from "@/components/HotelReservation/FnFNotAllowedAlert/FnFNotAllowedAlert"
import RoomProvider from "@/providers/Details/RoomProvider"
import EnterDetailsProvider from "@/providers/EnterDetailsProvider"
import { parseDetailsSearchParams } from "@/utils/url"

import styles from "./page.module.css"

import type { LangParams, NextSearchParams, PageArgs } from "@/types/params"

export default async function DetailsPage(
  props: PageArgs<LangParams, NextSearchParams>
) {
  const searchParams = await props.searchParams
  const params = await props.params

  const { lang } = params

  const selectRoomParams = new URLSearchParams(searchParams)

  const booking = parseDetailsSearchParams(searchParams)

  if (!booking) return notFound()

  if (selectRoomParams.has("modifyRateIndex")) {
    selectRoomParams.delete("modifyRateIndex")
  }

  if (
    booking.bookingCode &&
    FamilyAndFriendsCodes.includes(booking.bookingCode)
  ) {
    const cookieStore = await cookies()
    const isInValidFNF = cookieStore.get("sc")?.value !== "1"

    if (isInValidFNF) {
      return <FnFNotAllowedAlert />
    }
  }

  const breakfastInput = {
    adults: 1,
    fromDate: booking.fromDate,
    hotelId: booking.hotelId,
    toDate: booking.toDate,
  }
  const hotelInput = {
    hotelId: booking.hotelId,
    // TODO: Remove this from input since it forces
    //       waterfalls for no other reason than to
    //       set merchantInformationData.alternatePaymentOptions
    //       to an empty array
    isCardOnlyPayment: false,
    language: lang,
  }
  void getHotel(hotelInput)
  void getBreakfastPackages(breakfastInput)
  void getProfileSafely()

  const rooms = await getSelectedRoomsAvailabilityEnterDetails({
    booking,
    lang,
  })

  const hotelData = await getHotel(hotelInput)

  if (!hotelData || !rooms.length) {
    return notFound()
  }

  const breakfastPackages = await getBreakfastPackages(breakfastInput)
  const user = await getProfileSafely()

  const isCardOnlyPayment = rooms.some((room) => room.mustBeGuaranteed)
  const { hotel } = hotelData
  // TODO: Temp fix to avoid waterfall fetch and moving this
  //       logic from the route here for now
  if (isCardOnlyPayment) {
    hotel.merchantInformationData.alternatePaymentOptions = []
  }

  const firstRoom = rooms[0]
  const multirooms = rooms.slice(1)

  const { rateDefinition, rateDefinitionMember } = firstRoom.roomRate
  if (user && rateDefinitionMember) {
    const rateCode = selectRoomParams.get("room[0].ratecode")
    if (rateDefinitionMember.rateCode !== rateCode) {
      booking.rooms[0].rateCode = rateDefinitionMember.rateCode
      selectRoomParams.set("room[0].ratecode", rateDefinitionMember.rateCode)
      booking.rooms[0].counterRateCode = rateDefinition.rateCode
      selectRoomParams.set("room[0].counterratecode", rateDefinition.rateCode)
    }
  }

  // attribute data-footer-spacing used to add spacing
  // beneath footer to be able to show entire footer upon
  // scrolling down to the bottom of the page
  return (
    <main data-footer-spacing>
      <EnterDetailsProvider
        booking={booking}
        breakfastPackages={breakfastPackages}
        lang={lang}
        rooms={rooms}
        searchParamsStr={selectRoomParams.toString()}
        user={user}
        vat={hotel.vat}
      >
        <HotelHeader hotelData={hotelData} />
        <div className={styles.container}>
          <div className={styles.content}>
            <RoomProvider idx={0} room={firstRoom}>
              <RoomOne user={user} />
            </RoomProvider>
            {multirooms.map((room, idx) => (
              // Need to start idx from 1 since first room is
              // rendered above
              <RoomProvider key={idx + 1} idx={idx + 1} room={room}>
                <Multiroom />
              </RoomProvider>
            ))}
            <Suspense>
              <Payment
                otherPaymentOptions={
                  hotel.merchantInformationData.alternatePaymentOptions
                }
                supportedCards={hotel.merchantInformationData.cards}
              />
            </Suspense>
          </div>
          <aside className={styles.summary}>
            <MobileSummary isMember={!!user} />
            <DesktopSummary isMember={!!user} />
          </aside>
        </div>
        <EnterDetailsTrackingWrapper
          booking={booking}
          hotel={hotel}
          isMember={!!user}
          lang={lang}
          rooms={rooms}
        />
      </EnterDetailsProvider>
    </main>
  )
}
