"use client"
import { useRouter, useSearchParams } from "next/navigation"
import { useSession } from "next-auth/react"
import { useState, useTransition } from "react"
import { useIntl } from "react-intl"

import { dt } from "@/lib/dt"
import { useRatesStore } from "@/stores/select-rate"

import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop"
import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { isValidClientSession } from "@/utils/clientSession"
import { formatPrice } from "@/utils/numberFormatting"

import MobileSummary from "./MobileSummary"
import { getTotalPrice } from "./utils"

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

import { RateEnum } from "@/types/enums/rate"
import { RateTypeEnum } from "@/types/enums/rateType"

export default function RateSummary() {
  const {
    bookingCode,
    bookingRooms,
    dates,
    isFetchingPackages,
    rateSummary,
    roomsAvailability,
  } = useRatesStore((state) => ({
    bookingCode: state.booking.bookingCode,
    bookingRooms: state.booking.rooms,
    dates: {
      checkInDate: state.booking.fromDate,
      checkOutDate: state.booking.toDate,
    },
    isFetchingPackages: state.rooms.some((room) => room.isFetchingPackages),
    rateSummary: state.rateSummary,
    roomsAvailability: state.roomsAvailability,
  }))
  const { data: session } = useSession()
  const isUserLoggedIn = isValidClientSession(session)

  const [isSubmitting, setIsSubmitting] = useState(false)
  const intl = useIntl()
  const router = useRouter()
  const params = useSearchParams()
  const [_, startTransition] = useTransition()

  if (!roomsAvailability) {
    return null
  }

  const checkInDate = new Date(dates.checkInDate)
  const checkOutDate = new Date(dates.checkOutDate)
  const nights = dt(checkOutDate).diff(dt(checkInDate), "days")

  const totalNights = intl.formatMessage(
    {
      defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
    },
    { totalNights: nights }
  )
  const totalAdults = intl.formatMessage(
    {
      defaultMessage: "{totalAdults, plural, one {# adult} other {# adults}}",
    },
    { totalAdults: bookingRooms.reduce((acc, room) => acc + room.adults, 0) }
  )
  const childrenInOneOrMoreRooms = bookingRooms.some(
    (room) => room.childrenInRoom?.length
  )
  const childrenInroom = intl.formatMessage(
    {
      defaultMessage:
        "{totalChildren, plural, one {# child} other {# children}}",
    },
    {
      totalChildren: bookingRooms.reduce(
        (acc, room) => acc + (room.childrenInRoom?.length ?? 0),
        0
      ),
    }
  )
  const totalChildren = childrenInOneOrMoreRooms ? `, ${childrenInroom}` : ""
  const totalRooms = intl.formatMessage(
    {
      defaultMessage: "{totalRooms, plural, one {# room} other {# rooms}}",
    },
    { totalRooms: bookingRooms.length }
  )

  const summaryPriceText = `${totalNights}, ${totalAdults}${totalChildren}, ${totalRooms}`

  const totalRoomsRequired = bookingRooms.length
  const isAllRoomsSelected =
    rateSummary.filter((rate) => rate !== null).length === totalRoomsRequired
  const hasMemberRates = rateSummary.some(
    (room) => room && "member" in room.product && room.product.member
  )
  const showMemberDiscountBanner = hasMemberRates && !isUserLoggedIn

  const freeCancelation = intl.formatMessage({
    defaultMessage: "Free cancellation",
  })
  const nonRefundable = intl.formatMessage({
    defaultMessage: "Non-refundable",
  })
  const freeBooking = intl.formatMessage({
    defaultMessage: "Free rebooking",
  })
  const payLater = intl.formatMessage({
    defaultMessage: "Pay later",
  })
  const payNow = intl.formatMessage({
    defaultMessage: "Pay now",
  })

  function getRateDetails(rate: RateEnum) {
    switch (rate) {
      case RateEnum.change:
        return `${freeBooking}, ${payNow}`
      case RateEnum.flex:
        return `${freeCancelation}, ${payLater}`
      case RateEnum.save:
      default:
        return `${nonRefundable}, ${payNow}`
    }
  }

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    setIsSubmitting(true)
    startTransition(() => {
      router.push(`details?${params}`)
    })
  }

  if (!rateSummary.length || isFetchingPackages) {
    return null
  }

  const isBookingCodeRate = rateSummary.some(
    (rate) =>
      rate &&
      "public" in rate.product &&
      rate.product.public?.rateType !== RateTypeEnum.Regular
  )
  const isVoucherRate = rateSummary.some(
    (rate) => rate && "voucher" in rate.product
  )
  const isCorporateChequeRate = rateSummary.some(
    (rate) => rate && "corporateCheque" in rate.product
  )
  const showDiscounted =
    isUserLoggedIn ||
    isBookingCodeRate ||
    isVoucherRate ||
    isCorporateChequeRate

  const mainRoomProduct = rateSummary[0]
  const totalPriceToShow = getTotalPrice(
    mainRoomProduct,
    rateSummary,
    isUserLoggedIn
  )

  const rateProduct = rateSummary.find((rate) => rate?.product)?.product

  if (!totalPriceToShow || !rateProduct) {
    return null
  }

  let mainRoomCurrency = ""
  if ("member" in rateProduct && rateProduct.member?.localPrice) {
    mainRoomCurrency = rateProduct.member.localPrice.currency
  }
  if (
    !mainRoomCurrency &&
    "public" in rateProduct &&
    rateProduct.public?.localPrice
  ) {
    mainRoomCurrency = rateProduct.public.localPrice.currency
  }

  // attribute data-footer-spacing used to add spacing
  // beneath footer to be able to show entire footer upon
  // scrolling down to the bottom of the page
  return (
    <form
      data-footer-spacing
      action={`details?${params}`}
      method="GET"
      onSubmit={handleSubmit}
    >
      <div className={styles.summary}>
        <div className={styles.content}>
          <div className={styles.summaryText}>
            {rateSummary.map((room, index) => {
              if (!room) {
                return (
                  <div key={`unselected-${index}`}>
                    <Subtitle color="uiTextPlaceholder">
                      {intl.formatMessage(
                        {
                          defaultMessage: "Room {roomIndex}",
                        },
                        { roomIndex: index + 1 }
                      )}
                    </Subtitle>
                    <Body color="uiTextPlaceholder">
                      {intl.formatMessage({
                        defaultMessage: "Select room",
                      })}
                    </Body>
                  </div>
                )
              }

              return (
                <div key={index}>
                  {rateSummary.length > 1 ? (
                    <>
                      <Subtitle color="uiTextHighContrast">
                        {intl.formatMessage(
                          {
                            defaultMessage: "Room {roomIndex}",
                          },
                          { roomIndex: index + 1 }
                        )}
                      </Subtitle>
                      <Body color="uiTextMediumContrast">{room.roomType}</Body>
                      <Caption color="uiTextMediumContrast">
                        {getRateDetails(room.rate)}
                      </Caption>
                    </>
                  ) : (
                    <>
                      <Subtitle color="uiTextHighContrast">
                        {room.roomType}
                      </Subtitle>
                      <Body color="uiTextMediumContrast">
                        {getRateDetails(room.rate)}
                      </Body>
                    </>
                  )}
                </div>
              )
            })}
            {/* Render unselected rooms */}
            {Array.from({
              length: totalRoomsRequired - rateSummary.length,
            }).map((_, index) => (
              <div key={`unselected-${index}`}>
                <Subtitle color="uiTextPlaceholder">
                  {intl.formatMessage(
                    {
                      defaultMessage: "Room {roomIndex}",
                    },
                    { roomIndex: rateSummary.length + index + 1 }
                  )}
                </Subtitle>
                <Body color="uiTextPlaceholder">
                  {intl.formatMessage({
                    defaultMessage: "Select room",
                  })}
                </Body>
              </div>
            ))}
          </div>
          <div className={styles.summaryPriceContainer}>
            {showMemberDiscountBanner && (
              <div className={styles.promoContainer}>
                <SignupPromoDesktop
                  memberPrice={{
                    amount: rateSummary.reduce((total, rate) => {
                      if (!rate) {
                        return total
                      }

                      const { packages: roomPackages, product } = rate

                      const memberExists = "member" in product && product.member
                      const publicExists = "public" in product && product.public
                      if (!memberExists) {
                        if (!publicExists) {
                          return total
                        }
                      }

                      const price =
                        product.member?.localPrice.pricePerStay ||
                        product.public?.localPrice.pricePerStay

                      if (!price) {
                        return total
                      }

                      const selectedPackagesPrice = roomPackages.reduce(
                        (acc, pkg) => acc + pkg.localPrice.totalPrice,
                        0
                      )

                      return total + price + selectedPackagesPrice
                    }, 0),
                    currency: mainRoomCurrency,
                  }}
                />
              </div>
            )}
            <div className={styles.summaryPriceTextDesktop}>
              <Body>
                {intl.formatMessage(
                  {
                    defaultMessage: "<b>Total price</b> (incl VAT)",
                  },
                  { b: (str) => <b>{str}</b> }
                )}
              </Body>
              <Caption color="uiTextMediumContrast">{summaryPriceText}</Caption>
            </div>
            <div className={styles.summaryPrice}>
              <div className={styles.summaryPriceTextDesktop}>
                <Subtitle
                  color={showDiscounted ? "red" : "uiTextHighContrast"}
                  textAlign="right"
                >
                  {formatPrice(
                    intl,
                    totalPriceToShow.local.price,
                    totalPriceToShow.local.currency,
                    totalPriceToShow.local.additionalPrice,
                    totalPriceToShow.local.additionalPriceCurrency
                  )}
                </Subtitle>
                {bookingCode && totalPriceToShow.local.regularPrice && (
                  <Caption
                    textAlign="right"
                    color="uiTextMediumContrast"
                    striked={true}
                  >
                    {formatPrice(
                      intl,
                      totalPriceToShow.local.regularPrice,
                      totalPriceToShow.local.currency
                    )}
                  </Caption>
                )}
                {totalPriceToShow.requested ? (
                  <Body color="uiTextMediumContrast">
                    {intl.formatMessage(
                      {
                        defaultMessage: "Approx. {value}",
                      },
                      {
                        value: formatPrice(
                          intl,
                          totalPriceToShow.requested.price,
                          totalPriceToShow.requested.currency,
                          totalPriceToShow.requested.additionalPrice,
                          totalPriceToShow.requested.additionalPriceCurrency
                        ),
                      }
                    )}
                  </Body>
                ) : null}
              </div>
              <div className={styles.summaryPriceTextMobile}>
                <Caption color="uiTextHighContrast">
                  {intl.formatMessage({
                    defaultMessage: "Total price",
                  })}
                </Caption>
                <Subtitle color={showDiscounted ? "red" : "uiTextHighContrast"}>
                  {formatPrice(
                    intl,
                    totalPriceToShow.local.price,
                    totalPriceToShow.local.currency,
                    totalPriceToShow.local.additionalPrice,
                    totalPriceToShow.local.additionalPriceCurrency
                  )}
                </Subtitle>
                <Footnote
                  color="uiTextMediumContrast"
                  className={styles.summaryPriceTextMobile}
                >
                  {summaryPriceText}
                </Footnote>
              </div>
              <Button
                className={styles.continueButton}
                disabled={!isAllRoomsSelected || isSubmitting}
                theme="base"
                type="submit"
              >
                {intl.formatMessage({
                  defaultMessage: "Continue",
                })}
              </Button>
            </div>
          </div>
        </div>
        <div className={styles.mobileSummary}>
          <MobileSummary
            isAllRoomsSelected={isAllRoomsSelected}
            isUserLoggedIn={isUserLoggedIn}
            totalPriceToShow={totalPriceToShow}
            showMemberDiscountBanner={showMemberDiscountBanner}
          />
        </div>
      </div>
    </form>
  )
}
