import { cx } from "class-variance-authority"
import { useIntl } from "react-intl"

import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
import { Button } from "@scandic-hotels/design-system/Button"
import { Divider } from "@scandic-hotels/design-system/Divider"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Modal from "@scandic-hotels/design-system/Modal"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum"

import { getRoomFeatureDescription } from "../../../../../utils/getRoomFeatureDescription"
import Breakfast from "./Breakfast"

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

import type { Room as RoomType } from "../../../../../stores/enter-details/types.ts"

interface RoomProps {
  room: RoomType
  roomNumber: number
  roomCount: number
  isUserLoggedIn: boolean
  nightsCount: number
  defaultCurrency: CurrencyEnum
}

export default function Room({
  room,
  roomNumber,
  roomCount,
  isUserLoggedIn,
  nightsCount,
  defaultCurrency,
}: RoomProps) {
  const intl = useIntl()
  const adults = room.adults
  const childrenInRoom = room.childrenInRoom

  const childrenBeds = childrenInRoom?.reduce(
    (acc, value) => {
      const bedType = Number(value.bed)
      if (bedType === ChildBedMapEnum.IN_ADULTS_BED) {
        return acc
      }
      const count = acc.get(bedType) ?? 0
      acc.set(bedType, count + 1)
      return acc
    },
    new Map<ChildBedMapEnum, number>([
      [ChildBedMapEnum.IN_CRIB, 0],
      [ChildBedMapEnum.IN_EXTRA_BED, 0],
    ])
  )

  const childBedCrib = childrenBeds?.get(ChildBedMapEnum.IN_CRIB)
  const childBedExtraBed = childrenBeds?.get(ChildBedMapEnum.IN_EXTRA_BED)

  const isFirstRoomMember = roomNumber === 1 && isUserLoggedIn
  const isOrWillBecomeMember = !!(
    room.guest.join ||
    room.guest.membershipNo ||
    isFirstRoomMember
  )
  const showMemberPrice = !!(
    isOrWillBecomeMember &&
    "member" in room.roomRate &&
    room.roomRate.member
  )
  const isSpecialRate =
    "corporateCheque" in room.roomRate ||
    "redemption" in room.roomRate ||
    "voucher" in room.roomRate ||
    room.roomRate.bookingCode ||
    room.roomRate.rateDefinition.isCampaignRate
  const showDiscounted = isSpecialRate || showMemberPrice

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

  const guestsParts = [adultsMsg]
  if (childrenInRoom?.length) {
    const childrenMsg = intl.formatMessage(
      {
        id: "common.numberOfChildren",
        defaultMessage:
          "{totalChildren, plural, one {# child} other {# children}}",
      },
      { totalChildren: childrenInRoom.length }
    )
    guestsParts.push(childrenMsg)
  }

  let rateDetails = room.rateDetails
  if (room.memberRateDetails) {
    if (showMemberPrice) {
      rateDetails = room.memberRateDetails
    }
  }

  const guests = guestsParts.join(", ")
  const zeroPrice = formatPrice(intl, 0, defaultCurrency)

  let price = formatPrice(
    intl,
    room.roomPrice.perStay.local.price,
    room.roomPrice.perStay.local.currency,
    room.roomPrice.perStay.local.additionalPrice,
    room.roomPrice.perStay.local.additionalPriceCurrency
  )

  let currency: string = room.roomPrice.perStay.local.currency
  const isVoucher = "voucher" in room.roomRate
  if (isVoucher) {
    currency = CurrencyEnum.Voucher
    price = formatPrice(
      intl,
      room.roomPrice.perStay.local.price,
      currency,
      room.roomPrice.perStay.local.additionalPrice,
      room.roomPrice.perStay.local.additionalPriceCurrency
    )
  }

  return (
    <>
      <div className={styles.room} data-testid={`summary-room-${roomNumber}`}>
        <div>
          {roomCount > 1 ? (
            <Typography variant="Body/Supporting text (caption)/smBold">
              <p className={styles.roomTitle}>
                {intl.formatMessage(
                  {
                    id: "booking.roomIndex",
                    defaultMessage: "Room {roomIndex}",
                  },
                  {
                    roomIndex: roomNumber,
                  }
                )}
              </p>
            </Typography>
          ) : null}
          <div className={styles.entry}>
            <div>
              <Typography variant="Body/Paragraph/mdBold">
                <p>{room.roomType}</p>
              </Typography>
              <Typography variant="Body/Supporting text (caption)/smRegular">
                <div className={styles.additionalInformation}>
                  <p>{guests}</p>
                  <p>{room.cancellationText}</p>
                </div>
              </Typography>
            </div>
            <Typography variant="Body/Paragraph/mdRegular">
              <div className={styles.prices}>
                <p
                  className={cx(styles.price, {
                    [styles.discounted]: showDiscounted,
                  })}
                >
                  {price}
                </p>
                {showDiscounted && room.roomPrice.perStay.local.regularPrice ? (
                  <s className={styles.strikeThroughRate}>
                    {formatPrice(
                      intl,
                      room.roomPrice.perStay.local.regularPrice,
                      currency
                    )}
                  </s>
                ) : null}
              </div>
            </Typography>
          </div>

          {rateDetails?.length ? (
            <div className={styles.ctaWrapper}>
              <Modal
                trigger={
                  <Button
                    className={styles.termsButton}
                    variant="Text"
                    typography="Body/Supporting text (caption)/smBold"
                    wrapping={false}
                  >
                    {intl.formatMessage({
                      id: "booking.rateDetails",
                      defaultMessage: "Rate details",
                    })}
                    <MaterialIcon
                      icon="chevron_right"
                      size={20}
                      color="CurrentColor"
                    />
                  </Button>
                }
                title={room.cancellationText}
              >
                <div className={styles.terms}>
                  {rateDetails.map((info) => (
                    <Typography key={info} variant="Body/Paragraph/mdRegular">
                      <p className={styles.termsText}>
                        <MaterialIcon
                          icon="check"
                          color="Icon/Feedback/Success"
                          size={20}
                          className={styles.termsIcon}
                        />
                        {info}
                      </p>
                    </Typography>
                  ))}
                </div>
              </Modal>
            </div>
          ) : null}
        </div>

        {room.roomFeatures
          ? room.roomFeatures.map((feature) => (
              <Typography key={feature.code} variant="Body/Paragraph/mdRegular">
                <div className={styles.entry}>
                  <p>
                    {getRoomFeatureDescription(
                      feature.code,
                      feature.description,
                      intl
                    )}
                  </p>

                  <div className={styles.prices}>
                    <span className={styles.price}>
                      {formatPrice(
                        intl,
                        feature.localPrice.price,
                        feature.localPrice.currency
                      )}
                    </span>
                  </div>
                </div>
              </Typography>
            ))
          : null}

        {room.bedType ? (
          <Typography variant="Body/Paragraph/mdRegular">
            <div className={styles.entry}>
              <div>
                <p>{room.bedType.description}</p>
                <Typography variant="Body/Supporting text (caption)/smRegular">
                  <p>
                    {intl.formatMessage({
                      id: "booking.subjectToAvailability",
                      defaultMessage: "Subject to availability",
                    })}
                  </p>
                </Typography>
              </div>

              <div className={styles.prices}>
                <span className={styles.price}>{zeroPrice}</span>
              </div>
            </div>
          </Typography>
        ) : null}

        {childBedCrib ? (
          <Typography variant="Body/Paragraph/mdRegular">
            <div className={styles.entry}>
              <div>
                <p>
                  {intl.formatMessage(
                    {
                      id: "booking.numberOfCribs",
                      defaultMessage: "Crib (child) × {count}",
                    },
                    { count: childBedCrib }
                  )}
                </p>
                <Typography variant="Body/Supporting text (caption)/smRegular">
                  <p>
                    {intl.formatMessage({
                      id: "booking.subjectToAvailability",
                      defaultMessage: "Subject to availability",
                    })}
                  </p>
                </Typography>
              </div>
              <div className={styles.prices}>
                <span className={styles.price}>
                  {formatPrice(intl, 0, currency)}
                </span>
              </div>
            </div>
          </Typography>
        ) : null}

        {childBedExtraBed ? (
          <Typography variant="Body/Paragraph/mdRegular">
            <div className={styles.entry}>
              <div>
                <p>
                  {intl.formatMessage(
                    {
                      id: "booking.extraBedsCount",
                      defaultMessage: "Extra bed (child) × {count}",
                    },
                    {
                      count: childBedExtraBed,
                    }
                  )}
                </p>
                <Typography variant="Body/Supporting text (caption)/smRegular">
                  <p>
                    {intl.formatMessage({
                      id: "booking.subjectToAvailability",
                      defaultMessage: "Subject to availability",
                    })}
                  </p>
                </Typography>
              </div>
              <div className={styles.prices}>
                <span className={styles.price}>
                  {formatPrice(intl, 0, currency)}
                </span>
              </div>
            </div>
          </Typography>
        ) : null}

        <Breakfast
          adults={room.adults}
          breakfast={room.breakfast}
          breakfastIncluded={room.breakfastIncluded}
          guests={guests}
          nights={nightsCount}
        />
      </div>

      <Divider color="Border/Divider/Subtle" />
    </>
  )
}
