"use client"

import { Fragment } from "react"
import { useIntl } from "react-intl"

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

import { dt } from "@/lib/dt"

import BookingCodeChip from "@/components/BookingCodeChip"
import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal"
import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop"
import Modal from "@/components/Modal"
import Divider from "@/components/TempDesignSystem/Divider"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import useLang from "@/hooks/useLang"
import { formatPrice } from "@/utils/numberFormatting"

import Breakfast from "./Breakfast"
import { mapToPrice } from "./mapToPrice"

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

import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import type { RoomRate } from "@/types/components/hotelReservation/enterDetails/details"
import type { EnterDetailsSummaryProps } from "@/types/components/hotelReservation/summary"
import { CurrencyEnum } from "@/types/enums/currency"

const notDisplayableCurrencies = [
  CurrencyEnum.CC,
  CurrencyEnum.POINTS,
  CurrencyEnum.Voucher,
  CurrencyEnum.Unknown,
]

export default function SummaryUI({
  booking,
  rooms,
  totalPrice,
  isMember,
  vat,
  toggleSummaryOpen,
}: EnterDetailsSummaryProps) {
  const intl = useIntl()
  const lang = useLang()

  const nights = dt(booking.toDate).diff(booking.fromDate, "days")

  const nightsMsg = intl.formatMessage(
    {
      defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
    },
    { totalNights: nights }
  )

  function handleToggleSummary() {
    if (toggleSummaryOpen) {
      toggleSummaryOpen()
    }
  }

  function getMemberPrice(roomRate: RoomRate) {
    if ("member" in roomRate && roomRate.member) {
      return {
        amount: roomRate.member.localPrice.pricePerStay,
        currency: roomRate.member.localPrice.currency,
        pricePerNight: roomRate.member.localPrice.pricePerNight,
      }
    }

    return null
  }

  const roomOneGuest = rooms[0].room.guest
  const showSignupPromo =
    rooms.length === 1 &&
    !isMember &&
    !roomOneGuest.membershipNo &&
    !roomOneGuest.join

  const roomOneMemberPrice = getMemberPrice(rooms[0].room.roomRate)

  const roomOneRoomRate = rooms[0].room.roomRate
  // In case of Redemption, voucher and Corporate cheque do not show approx price
  const isSpecialRate =
    "corporateCheque" in roomOneRoomRate ||
    "redemption" in roomOneRoomRate ||
    "voucher" in roomOneRoomRate

  const isSameCurrency = totalPrice.requested
    ? totalPrice.requested.currency === totalPrice.local.currency
    : false

  const priceDetailsRooms = mapToPrice(rooms, isMember)
  const isAllCampaignRate = rooms.every(
    (room) => room.room.roomRate.rateDefinition.isCampaignRate
  )
  const isAllBreakfastIncluded = rooms.every(
    (room) => room.room.roomRate.rateDefinition.breakfastIncluded
  )

  return (
    <section className={styles.summary}>
      <header
        className={styles.header}
        role="button"
        onClick={handleToggleSummary}
      >
        <Subtitle className={styles.title} type="two">
          {intl.formatMessage({
            defaultMessage: "Booking summary",
          })}
        </Subtitle>
        <Body className={styles.date} color="baseTextMediumContrast">
          {dt(booking.fromDate).locale(lang).format("ddd, D MMM")}
          <MaterialIcon
            icon="arrow_right"
            color="Icon/Interactive/Secondary"
            size={15}
          />
          {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
          {dt(booking.toDate).locale(lang).format("ddd, D MMM")} ({nightsMsg})
        </Body>
        <MaterialIcon
          className={styles.chevronIcon}
          icon="keyboard_arrow_down"
          size={30}
          color="CurrentColor"
        />
      </header>
      <Divider color="primaryLightSubtle" />
      {rooms.map(({ room }, idx) => {
        const roomNumber = idx + 1
        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 memberPrice = getMemberPrice(room.roomRate)

        const isFirstRoomMember = roomNumber === 1 && isMember
        const isOrWillBecomeMember = !!(
          room.guest.join ||
          room.guest.membershipNo ||
          isFirstRoomMember
        )
        const showMemberPrice = !!(isOrWillBecomeMember && memberPrice)

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

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

        const guests = guestsParts.join(", ")

        const hideBedCurrency = notDisplayableCurrencies.includes(
          room.roomPrice.perStay.local.currency
        )

        let rateDetails = room.rateDetails
        if (room.memberRateDetails) {
          if (isMember || room.guest.join) {
            rateDetails = room.memberRateDetails
          }
        }

        return (
          <Fragment key={idx}>
            <div
              className={styles.addOns}
              data-testid={`summary-room-${roomNumber}`}
            >
              <div>
                {rooms.length > 1 ? (
                  <Body textTransform="bold">
                    {intl.formatMessage(
                      {
                        defaultMessage: "Room {roomIndex}",
                      },
                      {
                        roomIndex: roomNumber,
                      }
                    )}
                  </Body>
                ) : null}
                <div className={styles.entry}>
                  <Body color="uiTextHighContrast">{room.roomType}</Body>
                  <Body color={showMemberPrice ? "red" : "uiTextHighContrast"}>
                    {showMemberPrice
                      ? formatPrice(
                          intl,
                          memberPrice.amount,
                          memberPrice.currency
                        )
                      : formatPrice(
                          intl,
                          room.roomPrice.perStay.local.price,
                          room.roomPrice.perStay.local.currency,
                          room.roomPrice.perStay.local.additionalPrice,
                          room.roomPrice.perStay.local.additionalPriceCurrency
                        )}
                  </Body>
                </div>
                <Caption color="uiTextMediumContrast">{guests}</Caption>
                <Caption color="uiTextMediumContrast">
                  {room.cancellationText}
                </Caption>
                {rateDetails ? (
                  <Modal
                    trigger={
                      <Button
                        variant="Text"
                        typography="Body/Supporting text (caption)/smBold"
                        wrapping={false}
                      >
                        {intl.formatMessage({
                          defaultMessage: "Rate details",
                        })}
                        <MaterialIcon
                          icon="chevron_right"
                          size={20}
                          color="CurrentColor"
                        />
                      </Button>
                    }
                    title={
                      room.rateTitle ? room.rateTitle : room.cancellationText
                    }
                    subtitle={
                      room.rateTitle ? room.cancellationText : undefined
                    }
                  >
                    <div className={styles.terms}>
                      {rateDetails.map((info) => {
                        return (
                          <Body
                            key={info}
                            color="uiTextHighContrast"
                            className={styles.termsText}
                          >
                            <MaterialIcon
                              icon="check"
                              color="Icon/Feedback/Success"
                              size={20}
                              className={styles.termsIcon}
                            />
                            {info}
                          </Body>
                        )
                      })}
                    </div>
                  </Modal>
                ) : null}
              </div>
              {room.roomFeatures
                ? room.roomFeatures.map((feature) => (
                    <div className={styles.entry} key={feature.code}>
                      <div>
                        <Body color="uiTextHighContrast">
                          {feature.description}
                        </Body>
                      </div>

                      <Body color="uiTextHighContrast">
                        {formatPrice(
                          intl,
                          feature.localPrice.price,
                          feature.localPrice.currency
                        )}
                      </Body>
                    </div>
                  ))
                : null}
              {room.bedType ? (
                <div className={styles.entry}>
                  <Body color="uiTextHighContrast">
                    {room.bedType.description}
                  </Body>

                  <Body color="uiTextHighContrast">
                    {formatPrice(
                      intl,
                      0,
                      hideBedCurrency
                        ? ""
                        : room.roomPrice.perStay.local.currency
                    )}
                  </Body>
                </div>
              ) : null}
              {childBedCrib ? (
                <div className={styles.entry}>
                  <div>
                    <Body color="uiTextHighContrast">
                      {intl.formatMessage(
                        {
                          defaultMessage: "Crib (child) × {count}",
                        },
                        { count: childBedCrib }
                      )}
                    </Body>
                    <Caption color="uiTextMediumContrast">
                      {intl.formatMessage({
                        defaultMessage: "Based on availability",
                      })}
                    </Caption>
                  </div>
                  <Body color="uiTextHighContrast">
                    {formatPrice(
                      intl,
                      0,
                      room.roomPrice.perStay.local.currency
                    )}
                  </Body>
                </div>
              ) : null}
              {childBedExtraBed ? (
                <div className={styles.entry}>
                  <div>
                    <Body color="uiTextHighContrast">
                      {intl.formatMessage(
                        {
                          defaultMessage: "Extra bed (child) × {count}",
                        },
                        {
                          count: childBedExtraBed,
                        }
                      )}
                    </Body>
                  </div>
                  <Body color="uiTextHighContrast">
                    {formatPrice(
                      intl,
                      0,
                      room.roomPrice.perStay.local.currency
                    )}
                  </Body>
                </div>
              ) : null}
              <Breakfast
                adults={room.adults}
                breakfast={room.breakfast}
                breakfastIncluded={room.breakfastIncluded}
                guests={guests}
                nights={nights}
              />
            </div>
            <Divider color="primaryLightSubtle" />
          </Fragment>
        )
      })}
      <div className={styles.total}>
        <div className={styles.entry}>
          <div>
            <Body>
              {intl.formatMessage(
                {
                  defaultMessage: "<b>Total price</b> (incl VAT)",
                },
                { b: (str) => <b>{str}</b> }
              )}
            </Body>
            <PriceDetailsModal
              bookingCode={booking.bookingCode}
              fromDate={booking.fromDate}
              isCampaignRate={isAllCampaignRate}
              rooms={priceDetailsRooms}
              toDate={booking.toDate}
              totalPrice={totalPrice}
              vat={vat}
            />
          </div>
          <div>
            <Body textTransform="bold" data-testid="total-price">
              {formatPrice(
                intl,
                totalPrice.local.price,
                totalPrice.local.currency,
                totalPrice.local.additionalPrice,
                totalPrice.local.additionalPriceCurrency
              )}
            </Body>
            {totalPrice.local.regularPrice ? (
              <Caption color="uiTextMediumContrast" striked={true}>
                {formatPrice(
                  intl,
                  totalPrice.local.regularPrice,
                  totalPrice.local.currency
                )}
              </Caption>
            ) : null}
            {totalPrice.requested && !isSpecialRate && !isSameCurrency && (
              <Caption color="uiTextMediumContrast">
                {intl.formatMessage(
                  {
                    defaultMessage: "Approx. {value}",
                  },
                  {
                    value: formatPrice(
                      intl,
                      totalPrice.requested.price,
                      totalPrice.requested.currency
                    ),
                  }
                )}
              </Caption>
            )}
          </div>
        </div>
        <BookingCodeChip
          isCampaign={isAllCampaignRate}
          bookingCode={booking.bookingCode}
          isBreakfastIncluded={isAllBreakfastIncluded}
          alignCenter
        />
        <Divider className={styles.bottomDivider} color="primaryLightSubtle" />
      </div>
      {showSignupPromo && roomOneMemberPrice && !isMember ? (
        <SignupPromoDesktop
          memberPrice={roomOneMemberPrice}
          badgeContent={"✌️"}
          isEnterDetailsPage
        />
      ) : null}
    </section>
  )
}
