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

import CampaignRateCard from "@scandic-hotels/design-system/CampaignRateCard"
import NoRateAvailableCard from "@scandic-hotels/design-system/NoRateAvailableCard"

import {
  sumPackages,
  sumPackagesRequestedPrice,
} from "@/components/HotelReservation/utils"
import { useRoomContext } from "@/contexts/SelectRate/Room"
import useRateTitles from "@/hooks/booking/useRateTitles"

import { isSelectedPriceProduct } from "./isSelected"
import { calculatePricePerNightPriceProduct } from "./totalPricePerNight"

import type { SharedRateCardProps } from "@/types/components/hotelReservation/selectRate/rates"
import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter"
import type { PriceProduct } from "@/types/trpc/routers/hotel/roomAvailability"

interface CampaignProps extends SharedRateCardProps {
  campaign: PriceProduct[]
}

export default function Campaign({
  campaign,
  handleSelectRate,
  nights,
  roomTypeCode,
}: CampaignProps) {
  const intl = useIntl()
  const { roomNr, selectedFilter, selectedPackages, selectedRate } =
    useRoomContext()
  const rateTitles = useRateTitles()

  const isCampaignRate = campaign.some(
    (c) =>
      c.rateDefinition.isCampaignRate || c.rateDefinitionMember?.isCampaignRate
  )

  if (selectedFilter === BookingCodeFilterEnum.Discounted && !isCampaignRate) {
    return null
  }

  const night = intl
    .formatMessage({
      defaultMessage: "night",
    })
    .toUpperCase()

  if (selectedFilter === BookingCodeFilterEnum.Discounted) {
    campaign = campaign.filter((product) => product.bookingCode)
  }

  const pkgsSum = sumPackages(selectedPackages)
  const pkgsSumRequested = sumPackagesRequestedPrice(selectedPackages)

  const standardPriceMsg = intl.formatMessage({
    defaultMessage: "Standard price",
  })

  const memberPriceMsg = intl.formatMessage({
    defaultMessage: "Member price",
  })

  return campaign.map((product) => {
    if (!product.public) {
      return (
        <NoRateAvailableCard
          key={product.rate}
          noPricesAvailableText={rateTitles.noPriceAvailable}
          paymentTerm={rateTitles[product.rate].paymentTerm}
          rateTitle={rateTitles[product.rate].title}
          variant="Campaign"
        />
      )
    }

    const rateTermDetails = product.rateDefinitionMember
      ? [
          {
            title: product.bookingCode
              ? product.rateDefinition.title
              : standardPriceMsg,
            terms: product.rateDefinition.generalTerms,
          },
          {
            title: product.bookingCode
              ? product.rateDefinitionMember.title
              : standardPriceMsg,
            terms: product.rateDefinitionMember.generalTerms,
          },
        ]
      : [
          {
            title: product.bookingCode
              ? product.rateDefinition.title
              : standardPriceMsg,
            terms: product.rateDefinition.generalTerms,
          },
        ]

    const isSelected = isSelectedPriceProduct(
      product,
      selectedRate,
      roomTypeCode
    )

    let bannerText = intl.formatMessage({
      defaultMessage: "Campaign",
    })
    if (product.bookingCode) {
      bannerText = product.bookingCode
    }

    if (product.rateDefinition.breakfastIncluded) {
      bannerText = `${bannerText} ∙ ${intl.formatMessage({
        defaultMessage: "Breakfast included",
      })}`
    } else {
      bannerText = `${bannerText} ∙ ${intl.formatMessage({
        defaultMessage: "Breakfast excluded",
      })}`
    }

    const pricePerNight = calculatePricePerNightPriceProduct(
      product.public.localPrice.pricePerNight,
      product.public.requestedPrice?.pricePerNight,
      nights,
      pkgsSum.price,
      pkgsSumRequested.price
    )

    const pricePerNightMember = product.member
      ? calculatePricePerNightPriceProduct(
          product.member.localPrice.pricePerNight,
          product.member.requestedPrice?.pricePerNight,
          nights,
          pkgsSum.price,
          pkgsSumRequested.price
        )
      : undefined

    let approximateRatePrice = undefined
    if (
      pricePerNight.totalRequestedPrice &&
      pricePerNightMember?.totalRequestedPrice
    ) {
      approximateRatePrice = `${pricePerNight.totalRequestedPrice}/${pricePerNightMember.totalRequestedPrice}`
    } else if (pricePerNight.totalRequestedPrice) {
      approximateRatePrice = pricePerNight.totalRequestedPrice
    }

    const approximateRate =
      approximateRatePrice && product.public.requestedPrice
        ? {
            label: intl.formatMessage({
              defaultMessage: "Approx.",
            }),
            price: approximateRatePrice,
            unit: product.public.requestedPrice.currency,
          }
        : undefined

    return (
      <CampaignRateCard
        key={product.rate}
        approximateRate={approximateRate}
        bannerText={bannerText}
        handleChange={() => handleSelectRate(product)}
        isSelected={isSelected}
        isHighlightedRate={!!product.rateDefinition?.displayPriceRed}
        memberRate={
          pricePerNightMember
            ? {
                label: memberPriceMsg,
                price: pricePerNightMember.totalPrice,
                unit: `${product.member!.localPrice.currency}/${night}`,
              }
            : undefined
        }
        name={`rateCode-${roomNr}-${product.public.rateCode}`}
        paymentTerm={rateTitles[product.rate].paymentTerm}
        rate={{
          label: standardPriceMsg,
          price: pricePerNight.totalPrice,
          unit: `${product.public.localPrice.currency}/${night}`,
        }}
        rateTitle={rateTitles[product.rate].title}
        omnibusRate={
          product.public.localPrice.omnibusPricePerNight
            ? {
                label: intl
                  .formatMessage({
                    defaultMessage: "Lowest price (last 30 days)",
                  })
                  .toUpperCase(),
                price:
                  product.public.localPrice.omnibusPricePerNight.toString(),
                unit: product.public.localPrice.currency,
              }
            : undefined
        }
        rateTermDetails={rateTermDetails}
        value={product.public.rateCode}
      />
    )
  })
}
