"use client"
import { Fragment } from "react"
import { Button as ButtonRAC } from "react-aria-components"
import { useIntl } from "react-intl"

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 { dt } from "@/lib/dt"
import { useRatesStore } from "@/stores/select-rate"

import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal"
import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop"
import Modal from "@/components/Modal"
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 { isBookingCodeRate } from "./isBookingCodeRate"
import { mapToPrice } from "./mapToPrice"

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

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

export default function Summary({
  booking,
  rooms,
  totalPrice,
  isMember,
  vat,
  toggleSummaryOpen,
}: SelectRateSummaryProps) {
  const { rateSummary, defaultCurrency } = useRatesStore((state) => ({
    rateSummary: state.rateSummary,
    defaultCurrency: state.defaultCurrency,
  }))
  const intl = useIntl()
  const lang = useLang()

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

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

  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 memberPrice =
    rooms.length === 1 && rooms[0] ? getMemberPrice(rooms[0].roomRate) : null

  const containsBookingCodeRate = rooms.find(
    (r) => r && isBookingCodeRate(r.roomRate)
  )
  const showDiscounted = containsBookingCodeRate || isMember

  const priceDetailsRooms = mapToPrice(rateSummary, booking.rooms, isMember)

  return (
    <section className={styles.summary}>
      <header className={styles.header}>
        <ButtonRAC onPress={toggleSummaryOpen}>
          <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_forward"
              size={15}
              color="Icon/Interactive/Secondary"
            />
            {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
            {dt(booking.toDate).locale(lang).format("ddd, D MMM")} ({nights})
          </Body>
          <MaterialIcon
            className={styles.chevronIcon}
            icon="keyboard_arrow_down"
            size={30}
            color="CurrentColor"
          />
        </ButtonRAC>
      </header>
      <Divider color="Border/Divider/Subtle" />
      {rooms.map((room, idx) => {
        if (!room) {
          return null
        }

        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 showMemberPrice = !!(isMember && memberPrice && roomNumber === 1)
        const showDiscounted =
          isBookingCodeRate(room.roomRate) || showMemberPrice

        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 roomPackages = room.packages
        const zeroPrice = formatPrice(intl, 0, defaultCurrency)

        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={showDiscounted ? "red" : "uiTextHighContrast"}>
                    {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">
                  {guestsParts.join(", ")}
                </Caption>
                <Caption color="uiTextMediumContrast">
                  {room.cancellationText}
                </Caption>
                <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.cancellationText}
                >
                  <div className={styles.terms}>
                    {room.rateDetails?.map((info) => (
                      <Body
                        key={info}
                        color="uiTextHighContrast"
                        className={styles.termsText}
                      >
                        <MaterialIcon
                          icon="check"
                          color="Icon/Feedback/Success"
                          size={20}
                          className={styles.termsIcon}
                        />
                        {info}
                      </Body>
                    ))}
                  </div>
                </Modal>
              </div>

              {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">{zeroPrice}</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">{zeroPrice}</Body>
                </div>
              ) : null}
              {roomPackages?.map((pkg) => (
                <div className={styles.entry} key={pkg.code}>
                  <div>
                    <Body color="uiTextHighContrast">{pkg.description}</Body>
                  </div>

                  <Body color="uiTextHighContrast">
                    {formatPrice(
                      intl,
                      pkg.localPrice.price,
                      pkg.localPrice.currency
                    )}
                  </Body>
                </div>
              ))}
            </div>
            <Divider color="Border/Divider/Subtle" />
          </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}
              rooms={priceDetailsRooms}
              toDate={booking.toDate}
              totalPrice={totalPrice}
              vat={vat}
              defaultCurrency={defaultCurrency}
            />
          </div>
          <div>
            <Body
              color={showDiscounted ? "red" : "uiTextHighContrast"}
              textTransform="bold"
              data-testid="total-price"
            >
              {formatPrice(
                intl,
                totalPrice.local.price,
                totalPrice.local.currency,
                totalPrice.local.additionalPrice,
                totalPrice.local.additionalPriceCurrency
              )}
            </Body>
            {booking.bookingCode && totalPrice.local.regularPrice && (
              <Caption color="uiTextMediumContrast" striked={true}>
                {formatPrice(
                  intl,
                  totalPrice.local.regularPrice,
                  totalPrice.local.currency
                )}
              </Caption>
            )}
            {totalPrice.requested && (
              <Caption color="uiTextMediumContrast">
                {intl.formatMessage(
                  {
                    defaultMessage: "Approx. {value}",
                  },
                  {
                    value: formatPrice(
                      intl,
                      totalPrice.requested.price,
                      totalPrice.requested.currency,
                      totalPrice.requested.additionalPrice,
                      totalPrice.requested.additionalPriceCurrency
                    ),
                  }
                )}
              </Caption>
            )}
          </div>
        </div>
        <Divider
          className={styles.bottomDivider}
          color="Border/Divider/Subtle"
        />
      </div>
      {!isMember && memberPrice ? (
        <SignupPromoDesktop memberPrice={memberPrice} badgeContent={"✌️"} />
      ) : null}
    </section>
  )
}
