"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 useLang from "../../../../hooks/useLang"
import { useEnterDetailsStore } from "../../../../stores/enter-details"
import PriceDetailsModal from "../../../PriceDetailsModal"
import { isBookingCodeRate } from "../../../SelectRate/RoomsContainer/RateSummary/utils"
import SignupPromoDesktop from "../../../SignupPromo/Desktop"
import { mapToPrice } from "./mapToPrice"
import Room from "./Room"
import { getMemberPrice } from "./utils"

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

export default function SummaryUI({
  isUserLoggedIn,
}: {
  isUserLoggedIn: boolean
}) {
  const intl = useIntl()
  const lang = useLang()
  const isDesktop = useMediaQuery("(min-width: 1367px)")

  const {
    booking,
    defaultCurrency,
    hotelOffersBreakfast,
    rooms,
    totalPrice,
    vat,
    toggleSummaryOpen,
  } = useEnterDetailsStore((state) => ({
    booking: state.booking,
    defaultCurrency: state.defaultCurrency,
    hotelOffersBreakfast: state.hotelOffersBreakfast,
    rooms: state.rooms,
    totalPrice: state.totalPrice,
    vat: state.vat,
    toggleSummaryOpen: state.actions.toggleSummaryOpen,
  }))

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

  const nightsMsg = intl.formatMessage(
    {
      id: "booking.numberOfNights",
      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 &&
    !isUserLoggedIn &&
    !roomOneGuest.membershipNo &&
    !roomOneGuest.join

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

  const roomOneRoomRate = rooms[0].room.roomRate
  const isVoucherRate = "voucher" in roomOneRoomRate

  const priceDetailsRooms = mapToPrice(rooms, isUserLoggedIn)
  const isAllCampaignRate = rooms.every(
    (room) => room.room.roomRate.rateDefinition.isCampaignRate
  )
  const containsBookingCodeRate = rooms.find(
    (r) => r && isBookingCodeRate(r.room.roomRate)
  )
  const containsCampaignRate = rooms.find(
    (r) => r && r.room.roomRate.rateDefinition.isCampaignRate
  )
  const showDiscounted = containsBookingCodeRate || isUserLoggedIn

  const totalCurrency = isVoucherRate
    ? CurrencyEnum.Voucher
    : totalPrice.local.currency

  return (
    <section className={styles.summary}>
      <header
        className={styles.header}
        role="button"
        onClick={isDesktop ? undefined : handleToggleSummary}
      >
        <Subtitle className={styles.title} type="two">
          {intl.formatMessage({
            id: "booking.bookingSummary",
            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-next-line formatjs/no-literal-string-in-jsx */}
          {dt(booking.toDate).locale(lang).format(longDateFormat[lang])} (
          {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
          {nightsMsg})
        </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}
          isUserLoggedIn={isUserLoggedIn}
          nightsCount={nights}
          showBookingCodeChip={
            rooms.length !== 1 &&
            (room.roomRate.rateDefinition.isCampaignRate ||
              !!room.roomRate.bookingCode)
          }
          hotelOffersBreakfast={hotelOffersBreakfast}
        />
      ))}

      <div>
        <div className={styles.entry}>
          <div>
            <Typography variant="Body/Paragraph/mdRegular">
              <p>
                {intl.formatMessage(
                  {
                    id: "booking.totalPriceInclVat",
                    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(
                    {
                      id: "booking.approxValue",
                      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">
                <p>
                  <s className={styles.strikeThroughRate}>
                    {formatPrice(
                      intl,
                      totalPrice.local.regularPrice,
                      totalPrice.local.currency
                    )}
                  </s>
                </p>
              </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}
            isCampaignRate={!!containsCampaignRate}
            hotelOffersBreakfast={hotelOffersBreakfast}
          />
        </div>
      </div>
      {rooms.length === 1 && (isAllCampaignRate || booking.bookingCode) && (
        <BookingCodeChip
          isCampaign={isAllCampaignRate}
          bookingCode={booking.bookingCode}
          alignCenter
        />
      )}
      <Divider className={styles.bottomDivider} color="Border/Divider/Subtle" />
      {showSignupPromo && roomOneMemberPrice && !isUserLoggedIn ? (
        <SignupPromoDesktop
          memberPrice={roomOneMemberPrice}
          badgeContent="✌️"
          isEnterDetailsPage
        />
      ) : null}
    </section>
  )
}
