"use client"

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

import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
import { longDateFormat } from "@scandic-hotels/common/constants/dateFormats"
import { dt } from "@scandic-hotels/common/dt"
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
import Body from "@scandic-hotels/design-system/Body"
import { BookingCodeChip } from "@scandic-hotels/design-system/BookingCodeChip"
import { Divider } from "@scandic-hotels/design-system/Divider"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Subtitle from "@scandic-hotels/design-system/Subtitle"
import { Typography } from "@scandic-hotels/design-system/Typography"

import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal"
import { isBookingCodeRate } from "@/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/utils"
import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop"
import useLang from "@/hooks/useLang"

import { mapToPrice } from "./mapToPrice"
import Room from "./Room"
import { getMemberPrice } from "./utils"

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

import type { EnterDetailsSummaryProps } from "@/types/components/hotelReservation/summary"

export default function SummaryUI({
  booking,
  rooms,
  totalPrice,
  isMember,
  vat,
  toggleSummaryOpen,
  defaultCurrency,
}: EnterDetailsSummaryProps) {
  const intl = useIntl()
  const lang = useLang()
  const isDesktop = useMediaQuery("(min-width: 1367px)")

  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()
    }
  }

  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
  const isVoucherRate = "voucher" in roomOneRoomRate
  // In case of Redemption, voucher and Corporate cheque do not show approx price
  const isSpecialRate =
    "corporateCheque" in roomOneRoomRate ||
    "redemption" in roomOneRoomRate ||
    isVoucherRate

  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
  )
  const containsBookingCodeRate = rooms.find(
    (r) => r && isBookingCodeRate(r.room.roomRate)
  )
  const showDiscounted = containsBookingCodeRate || isMember

  const totalCurrency = isVoucherRate
    ? intl.formatMessage({ defaultMessage: "Voucher" })
    : totalPrice.local.currency

  if (isVoucherRate && defaultCurrency === CurrencyEnum.Voucher) {
    defaultCurrency = intl.formatMessage({
      defaultMessage: "Voucher",
    }) as CurrencyEnum
  }

  return (
    <section className={styles.summary}>
      <header
        className={styles.header}
        role="button"
        onClick={isDesktop ? undefined : 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(longDateFormat[lang])}
          <MaterialIcon
            icon="arrow_right"
            color="Icon/Interactive/Secondary"
            size={15}
          />
          {/* eslint-disable formatjs/no-literal-string-in-jsx */}
          {dt(booking.toDate).locale(lang).format(longDateFormat[lang])} (
          {nightsMsg}){/* eslint-enable formatjs/no-literal-string-in-jsx */}
        </Body>
        <MaterialIcon
          className={styles.chevronIcon}
          icon="keyboard_arrow_down"
          size={30}
          color="CurrentColor"
        />
      </header>
      <Divider color="Border/Divider/Subtle" />
      {rooms.map(({ room }, idx) => (
        <Room
          key={idx}
          defaultCurrency={defaultCurrency}
          room={room}
          roomNumber={idx + 1}
          roomCount={rooms.length}
          isMember={isMember}
          isSpecialRate={isSpecialRate}
          nightsCount={nights}
        />
      ))}

      <div>
        <div className={styles.entry}>
          <div>
            <Typography variant="Body/Paragraph/mdRegular">
              <p>
                {intl.formatMessage(
                  {
                    defaultMessage: "<b>Total price</b> (incl VAT)",
                  },
                  {
                    b: (str) => (
                      <Typography variant="Body/Paragraph/mdBold">
                        <span>{str}</span>
                      </Typography>
                    ),
                  }
                )}
              </p>
            </Typography>
            {totalPrice.requested ? (
              <Typography variant="Body/Supporting text (caption)/smRegular">
                <p className={styles.approxPrice}>
                  {intl.formatMessage(
                    {
                      defaultMessage: "Approx. {value}",
                    },
                    {
                      value: formatPrice(
                        intl,
                        totalPrice.requested.price,
                        totalPrice.requested.currency,
                        totalPrice.requested.additionalPrice,
                        totalPrice.requested.additionalPriceCurrency
                      ),
                    }
                  )}
                </p>
              </Typography>
            ) : null}
          </div>
          <div className={styles.prices}>
            <Typography variant="Body/Paragraph/mdBold">
              <span
                className={cx(styles.price, {
                  [styles.discounted]: showDiscounted,
                })}
                data-testid="total-price"
              >
                {formatPrice(
                  intl,
                  totalPrice.local.price,
                  totalCurrency,
                  totalPrice.local.additionalPrice,
                  totalPrice.local.additionalPriceCurrency
                )}
              </span>
            </Typography>
            {showDiscounted && totalPrice.local.regularPrice ? (
              <Typography variant="Body/Paragraph/mdRegular">
                <s className={styles.strikeThroughRate}>
                  {formatPrice(
                    intl,
                    totalPrice.local.regularPrice,
                    totalPrice.local.currency
                  )}
                </s>
              </Typography>
            ) : null}
          </div>
        </div>

        <div className={styles.ctaWrapper}>
          <PriceDetailsModal
            bookingCode={booking.bookingCode}
            defaultCurrency={defaultCurrency}
            fromDate={booking.fromDate}
            rooms={priceDetailsRooms}
            toDate={booking.toDate}
            totalPrice={totalPrice}
            vat={vat}
          />
        </div>
      </div>
      <BookingCodeChip
        isCampaign={isAllCampaignRate}
        bookingCode={booking.bookingCode}
        isBreakfastIncluded={isAllBreakfastIncluded}
        alignCenter
      />
      <Divider className={styles.bottomDivider} color="Border/Divider/Subtle" />
      {showSignupPromo && roomOneMemberPrice && !isMember ? (
        <SignupPromoDesktop
          memberPrice={roomOneMemberPrice}
          badgeContent={"✌️"}
          isEnterDetailsPage
        />
      ) : null}
    </section>
  )
}
