"use client"
import { use, useEffect } from "react"
import { useIntl } from "react-intl"

import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"

import { BookingStatusEnum } from "@/constants/booking"
import { dt } from "@/lib/dt"
import { useMyStayRoomDetailsStore } from "@/stores/my-stay/myStayRoomDetailsStore"
import { useMyStayTotalPriceStore } from "@/stores/my-stay/myStayTotalPrice"

import Image from "@/components/Image"
import Divider from "@/components/TempDesignSystem/Divider"
import IconChip from "@/components/TempDesignSystem/IconChip"
import useLang from "@/hooks/useLang"

import { IconForFeatureCode } from "../../utils"
import Points from "../Points"
import Price from "../Price"
import { hasModifiableRate } from "../utils"
import { hasBreakfastPackageFromBookingFlow } from "../utils/hasBreakfastPackage"
import { mapRoomDetails } from "../utils/mapRoomDetails"
import MultiRoomSkeleton from "./MultiRoomSkeleton"
import ToggleSidePeek from "./ToggleSidePeek"

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

import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import type { Room } from "@/types/hotel"
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
import type { User } from "@/types/user"

interface MultiRoomProps {
  booking?: BookingConfirmation["booking"]
  room?:
    | (Room & {
        bedType: Room["roomTypes"][number]
      })
    | null
  bookingPromise?: Promise<BookingConfirmation | null>
  index?: number
  user: User | null
}

export default function MultiRoom({
  room: initialRoom,
  booking: initialBooking,
  bookingPromise,
  index,
  user,
}: MultiRoomProps) {
  const intl = useIntl()
  const lang = useLang()
  const addRoomPrice = useMyStayTotalPriceStore(
    (state) => state.actions.addRoomPrice
  )

  const addLinkedReservationRoom = useMyStayRoomDetailsStore(
    (state) => state.actions.addLinkedReservationRoom
  )

  const bookedRoom = useMyStayRoomDetailsStore((state) => state.bookedRoom)
  const linkedReservationRooms = useMyStayRoomDetailsStore(
    (state) => state.linkedReservationRooms
  )

  const allRooms = [bookedRoom, ...linkedReservationRooms]

  // Resolve promise data directly without setState
  let bookingInfo = initialBooking
  let roomInfo = initialRoom

  if (bookingPromise) {
    const promiseData = use(bookingPromise)
    if (promiseData) {
      bookingInfo = promiseData.booking
      roomInfo = promiseData.room
    }
  }
  const isBookingCancelled =
    bookingInfo?.reservationStatus === BookingStatusEnum.Cancelled

  const multiRoom = allRooms.find(
    (room) => room.confirmationNumber === bookingInfo?.confirmationNumber
  )

  // Update stores when data is available
  useEffect(() => {
    if (bookingInfo) {
      addRoomPrice({
        id: bookingInfo.confirmationNumber,
        totalPrice: isBookingCancelled ? 0 : bookingInfo.totalPrice,
        currencyCode: bookingInfo.currencyCode,
        isMainBooking: false,
        roomPoints: bookingInfo.roomPoints,
      })

      // Add room details to the store
      addLinkedReservationRoom(
        mapRoomDetails({
          booking: bookingInfo,
          room: roomInfo ?? null,
          roomNumber: index !== undefined ? index + 2 : 1,
        })
      )
    }
  }, [
    bookingInfo,
    roomInfo,
    index,
    isBookingCancelled,
    addRoomPrice,
    addLinkedReservationRoom,
  ])

  if (!multiRoom?.roomNumber) return <MultiRoomSkeleton />

  const {
    adults,
    checkInDate,
    childrenAges,
    confirmationNumber,
    cancellationNumber,
    hotelId,
    roomPoints,
    roomPrice,
    packages,
    rateDefinition,
    isCancelled,
    priceType,
    vouchers,
  } = multiRoom

  const fromDate = dt(checkInDate).locale(lang)

  const adultsMsg = intl.formatMessage(
    {
      defaultMessage: "{adults, plural, one {# adult} other {# adults}}",
    },
    {
      adults: adults,
    }
  )

  const childrenMsg = intl.formatMessage(
    {
      defaultMessage: "{children, plural, one {# child} other {# children}}",
    },
    {
      children: childrenAges.length,
    }
  )

  const adultsOnlyMsg = adultsMsg
  const adultsAndChildrenMsg = [adultsMsg, childrenMsg].join(", ")

  return (
    <article className={styles.multiRoom}>
      <Typography variant="Title/smRegular">
        <h3 className={styles.roomName}>{roomInfo?.name}</h3>
      </Typography>
      <div className={styles.roomHeader}>
        {isCancelled ? (
          <IconChip
            color={"red"}
            icon={
              <MaterialIcon
                icon="cancel"
                size={20}
                color="Icon/Feedback/Error"
              />
            }
          >
            <Typography variant="Body/Supporting text (caption)/smBold">
              <span>
                {intl.formatMessage({
                  defaultMessage: "Cancelled",
                })}
              </span>
            </Typography>
          </IconChip>
        ) : (
          <div className={styles.chip}>
            <Typography variant="Tag/sm">
              <span>
                {intl.formatMessage(
                  {
                    defaultMessage: "Room {roomIndex}",
                  },
                  {
                    roomIndex: index !== undefined ? index + 2 : 1,
                  }
                )}
              </span>
            </Typography>
          </div>
        )}
        <div className={styles.reference}>
          <Typography variant="Body/Supporting text (caption)/smBold">
            {isCancelled ? (
              <span>
                {intl.formatMessage({
                  defaultMessage: "Cancellation no",
                })}
                {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
                {":"}
              </span>
            ) : (
              <span>
                {intl.formatMessage({
                  defaultMessage: "Reference",
                })}
                {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
                {":"}
              </span>
            )}
          </Typography>
          <Typography variant="Body/Supporting text (caption)/smRegular">
            {isCancelled ? (
              <span className={styles.cancellationNumber}>
                {cancellationNumber}
              </span>
            ) : (
              <span>{confirmationNumber}</span>
            )}
          </Typography>
        </div>
        <div className={styles.toggleSidePeek}>
          <ToggleSidePeek
            hotelId={hotelId}
            roomTypeCode={roomInfo?.roomTypes[0].code}
            user={user ?? undefined}
            confirmationNumber={confirmationNumber}
          />
        </div>
      </div>
      <div
        className={`${styles.multiRoomCard} ${isCancelled ? styles.cancelled : ""}`}
      >
        {packages?.some((item) =>
          Object.values(RoomPackageCodeEnum).includes(
            item.code as RoomPackageCodeEnum
          )
        ) && (
          <div className={styles.packages}>
            {packages
              .filter((item) =>
                Object.values(RoomPackageCodeEnum).includes(
                  item.code as RoomPackageCodeEnum
                )
              )
              .map((item) => {
                return (
                  <span className={styles.package} key={item.code}>
                    <IconForFeatureCode
                      featureCode={item.code}
                      size={16}
                      color="Icon/Interactive/Default"
                    />
                  </span>
                )
              })}
          </div>
        )}
        <div className={styles.imageContainer}>
          <Image
            src={roomInfo?.images[0]?.imageSizes.small ?? ""}
            alt={roomInfo?.name ?? ""}
            fill
          />
        </div>
        <div className={styles.details}>
          <div className={styles.row}>
            <Typography variant="Body/Paragraph/mdBold">
              <p>
                {intl.formatMessage({
                  defaultMessage: "Guests",
                })}
              </p>
            </Typography>
            <Typography variant="Body/Paragraph/mdRegular">
              <p>
                {childrenAges.length > 0 ? adultsAndChildrenMsg : adultsOnlyMsg}
              </p>
            </Typography>
          </div>
          <div className={styles.row}>
            <Typography variant="Body/Paragraph/mdBold">
              <p>
                {intl.formatMessage({
                  defaultMessage: "Terms",
                })}
              </p>
            </Typography>
            <Typography variant="Body/Paragraph/mdRegular">
              <p>{rateDefinition.cancellationText}</p>
            </Typography>
          </div>
          {hasModifiableRate(rateDefinition.cancellationRule) && (
            <div className={styles.row}>
              <Typography variant="Body/Paragraph/mdBold">
                <p>
                  {intl.formatMessage({
                    defaultMessage: "Modify By",
                  })}
                </p>
              </Typography>

              <Typography variant="Body/Paragraph/mdRegular">
                {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
                <p color="uiTextHighContrast">
                  18:00, {fromDate.format("dddd D MMM")}
                </p>
              </Typography>
            </div>
          )}
          <div className={styles.row}>
            <Typography variant="Body/Paragraph/mdBold">
              <p>
                {intl.formatMessage({
                  defaultMessage: "Breakfast",
                })}
              </p>
            </Typography>

            <Typography variant="Body/Paragraph/mdRegular">
              <p color="uiTextHighContrast">
                {hasBreakfastPackageFromBookingFlow(
                  packages?.map((pkg) => ({
                    code: pkg.code,
                  })) ?? []
                )
                  ? intl.formatMessage({
                      defaultMessage: "Included",
                    })
                  : intl.formatMessage({
                      defaultMessage: "Not included",
                    })}
              </p>
            </Typography>
          </div>
          <Divider color="subtle" />
          <div className={styles.row}>
            <Typography variant="Body/Lead text">
              <p>
                {intl.formatMessage({
                  defaultMessage: "Room total",
                })}
              </p>
            </Typography>
            {priceType === "points" ? (
              <Points points={roomPoints} variant="Body/Paragraph/mdBold" />
            ) : priceType === "voucher" ? (
              <Typography variant="Body/Paragraph/mdBold">
                <p>
                  {intl.formatMessage(
                    {
                      defaultMessage: "{count} voucher",
                    },
                    { count: vouchers }
                  )}
                </p>
              </Typography>
            ) : (
              <Price
                price={isCancelled ? 0 : roomPrice.perStay.local.price}
                variant="Body/Paragraph/mdBold"
                isMember={rateDefinition.isMemberRate}
              />
            )}
          </div>
        </div>
      </div>
    </article>
  )
}
