import { notFound } from "next/navigation"

import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
import { dt } from "@scandic-hotels/common/dt"
import { Alert } from "@scandic-hotels/design-system/Alert"
import { Divider } from "@scandic-hotels/design-system/Divider"

import { BookingConfirmationProvider } from "../../providers/BookingConfirmationProvider"
import { getBookingConfirmation } from "../../trpc/memoizedRequests/getBookingConfirmation"
import { filterOverlappingDates } from "../../utils/SelectRate"
import { SidePanel } from "../SidePanel"
import { Confirmation } from "./Confirmation"
import { HotelDetails } from "./HotelDetails"
import { PaymentDetails } from "./PaymentDetails"
import { Promos } from "./Promos"
import { Receipt } from "./Receipt"
import { Rooms } from "./Rooms"
import { mapRoomState } from "./utils"

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

import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
import type { IntlShape } from "react-intl"

type BookingConfirmationProps = {
  intl: IntlShape
  refId: string
  membershipFailedError: boolean
  renderTracking: (trackingProps: {
    bookingConfirmation: BookingConfirmation
    refId: string
  }) => React.ReactNode
}

export async function BookingConfirmation({
  intl,
  refId,
  membershipFailedError,
  renderTracking,
}: BookingConfirmationProps) {
  const bookingConfirmation = await getBookingConfirmation(refId)

  if (!bookingConfirmation) {
    return notFound()
  }

  const { booking, hotel, room, roomCategories } = bookingConfirmation

  if (!room) {
    return notFound()
  }

  return (
    <BookingConfirmationProvider
      bookingCode={booking.bookingCode}
      currencyCode={booking.currencyCode}
      fromDate={booking.checkInDate}
      toDate={booking.checkOutDate}
      roomCategories={roomCategories}
      rooms={[
        mapRoomState(booking, room, intl),
        // null represents "known but not yet fetched rooms" and is used to render placeholders correctly
        ...Array(booking.linkedReservations.length).fill(null),
      ]}
      vat={booking.vatPercentage}
    >
      <Confirmation booking={booking} hotel={hotel} room={room}>
        <div className={styles.booking}>
          {membershipFailedError && (
            <Alert
              type={AlertTypeEnum.Info}
              heading={intl.formatMessage({
                defaultMessage: "Failed to verify membership",
              })}
              text={intl.formatMessage({
                defaultMessage:
                  "Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.",
              })}
            />
          )}
          <Rooms
            booking={booking}
            checkInTime={hotel.hotelFacts.checkin.checkInTime}
            checkOutTime={hotel.hotelFacts.checkin.checkOutTime}
            mainRoom={room}
          />
          <PaymentDetails />
          <Divider color="Border/Divider/Subtle" />
          <HotelDetails hotel={hotel} />
          {filterOverlappingDates(
            hotel.specialAlerts,
            dt(booking.checkInDate),
            dt(booking.checkOutDate)
          ).map((alert) => (
            <div key={alert.id}>
              <Alert
                type={alert.type}
                heading={alert.heading}
                text={alert.text}
              />
            </div>
          ))}
          <Promos booking={booking} />
          <div className={styles.mobileReceipt}>
            <Receipt />
          </div>
        </div>
        <aside className={styles.aside}>
          <SidePanel variant="receipt">
            <Receipt />
          </SidePanel>
        </aside>
      </Confirmation>

      {renderTracking({ bookingConfirmation, refId })}
    </BookingConfirmationProvider>
  )
}
