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

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

import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal"
import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop"
import {
  ArrowRightIcon,
  CheckIcon,
  ChevronDownSmallIcon,
} from "@/components/Icons"
import Modal from "@/components/Modal"
import Button from "@/components/TempDesignSystem/Button"
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 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"
import { RateTypeEnum } from "@/types/enums/rateType"

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

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

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

  function getMemberPrice(roomRate: RoomRate) {
    return roomRate?.memberRate
      ? {
          currency: roomRate.memberRate.localPrice.currency,
          pricePerNight: roomRate.memberRate.localPrice.pricePerNight,
          amount: roomRate.memberRate.localPrice.pricePerStay,
        }
      : null
  }

  const memberPrice = getMemberPrice(rooms[0].roomRate)

  const containsBookingCodeRate = rooms.find(
    (room) => room.roomRate.publicRate?.rateType !== RateTypeEnum.Regular
  )
  const showDiscounted = containsBookingCodeRate || isMember

  return (
    <section className={styles.summary}>
      <header className={styles.header}>
        <Subtitle className={styles.title} type="two">
          {intl.formatMessage({ id: "Booking summary" })}
        </Subtitle>
        <Body className={styles.date} color="baseTextMediumContrast">
          {dt(booking.fromDate).locale(lang).format("ddd, D MMM")}
          <ArrowRightIcon color="peach80" height={15} width={15} />
          {dt(booking.toDate).locale(lang).format("ddd, D MMM")} ({nights})
        </Body>
        <Button
          intent="text"
          size="small"
          className={styles.chevronButton}
          onClick={toggleSummaryOpen}
        >
          <ChevronDownSmallIcon height="20" width="20" />
        </Button>
      </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 showMemberPrice = !!(isMember && memberPrice && roomNumber === 1)
        const isBookingCodeRate =
          room.roomRate.publicRate?.rateType !== RateTypeEnum.Regular
        const showDiscounted = isBookingCodeRate || showMemberPrice

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

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

        return (
          <Fragment key={idx}>
            <div
              className={styles.addOns}
              data-testid={`summary-room-${roomNumber}`}
            >
              <div>
                {rooms.length > 1 ? (
                  <Body textTransform="bold">
                    {intl.formatMessage(
                      { id: "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
                    )}
                  </Body>
                </div>
                <Caption color="uiTextMediumContrast">
                  {guestsParts.join(", ")}
                </Caption>
                <Caption color="uiTextMediumContrast">
                  {room.cancellationText}
                </Caption>
                <Modal
                  trigger={
                    <Button intent="text">
                      <Caption color="burgundy" type="underline">
                        {intl.formatMessage({ id: "Rate details" })}
                      </Caption>
                    </Button>
                  }
                  title={room.cancellationText}
                >
                  <div className={styles.terms}>
                    {room.rateDetails?.map((info) => (
                      <Body
                        key={info}
                        color="uiTextHighContrast"
                        className={styles.termsText}
                      >
                        <CheckIcon
                          color="uiSemanticSuccess"
                          width={20}
                          height={20}
                          className={styles.termsIcon}
                        ></CheckIcon>
                        {info}
                      </Body>
                    ))}
                  </div>
                </Modal>
              </div>

              {childBedCrib ? (
                <div className={styles.entry}>
                  <div>
                    <Body color="uiTextHighContrast">
                      {intl.formatMessage(
                        { id: "Crib (child) × {count}" },
                        { count: childBedCrib }
                      )}
                    </Body>
                    <Caption color="uiTextMediumContrast">
                      {intl.formatMessage({ id: "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(
                        { id: "Extra bed (child) × {count}" },
                        {
                          count: childBedExtraBed,
                        }
                      )}
                    </Body>
                  </div>
                  <Body color="uiTextHighContrast">
                    {formatPrice(
                      intl,
                      0,
                      room.roomPrice.perStay.local.currency
                    )}
                  </Body>
                </div>
              ) : null}
            </div>
            <Divider color="primaryLightSubtle" />
          </Fragment>
        )
      })}
      <div className={styles.total}>
        <div className={styles.entry}>
          <div>
            <Body>
              {intl.formatMessage(
                { id: "<b>Total price</b> (incl VAT)" },
                { b: (str) => <b>{str}</b> }
              )}
            </Body>
            <PriceDetailsModal
              fromDate={booking.fromDate}
              toDate={booking.toDate}
              rooms={rooms.map((r) => ({
                adults: r.adults,
                childrenInRoom: r.childrenInRoom,
                roomPrice: r.roomPrice,
                roomType: r.roomType,
              }))}
              totalPrice={totalPrice}
              vat={vat}
              bookingCode={booking.bookingCode}
            />
          </div>
          <div>
            <Body
              color={showDiscounted ? "red" : "uiTextHighContrast"}
              textTransform="bold"
              data-testid="total-price"
            >
              {formatPrice(
                intl,
                totalPrice.local.price,
                totalPrice.local.currency
              )}
            </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(
                  { id: "Approx. {value}" },
                  {
                    value: formatPrice(
                      intl,
                      totalPrice.requested.price,
                      totalPrice.requested.currency
                    ),
                  }
                )}
              </Caption>
            )}
          </div>
        </div>
        <Divider className={styles.bottomDivider} color="primaryLightSubtle" />
      </div>
      {!isMember && memberPrice ? (
        <SignupPromoDesktop memberPrice={memberPrice} badgeContent={"✌️"} />
      ) : null}
    </section>
  )
}
