"use client"

import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import { AvailabilityEnum } from "@scandic-hotels/trpc/enums/selectHotel"

import { useSelectRateContext } from "../../../contexts/SelectRate/SelectRateContext"
import useLang from "../../../hooks/useLang"
import { mapPackageToLabel } from "../../../utils/getRoomFeatureDescription"
import { getValidDates } from "../getValidDates"
import { getSelectRateTracking } from "./tracking"

import type { RouterOutput } from "@scandic-hotels/trpc/client"

import type { SelectRateBooking } from "../../../types/components/selectRate/selectRate"

interface TrackingProps {
  hotelData: NonNullable<RouterOutput["hotel"]["get"]>
  booking: SelectRateBooking
}

export function SelectRateTracking({ hotelData, booking }: TrackingProps) {
  const lang = useLang()
  const { availability, input } = useSelectRateContext()

  const { fromDate, toDate } = getValidDates(booking.fromDate, booking.toDate)

  const { rooms, searchType, bookingCode } = booking

  const arrivalDate = fromDate.toDate()
  const departureDate = toDate.toDate()

  const specialRoomType = input.data?.booking.rooms
    ?.map((room) => {
      const packages = room.packages
        ?.map((pkg) => mapPackageToLabel(pkg))
        .join(",")
      return packages ?? ""
    })
    .join("|")
  const { hotelsTrackingData, pageTrackingData } = getSelectRateTracking({
    lang,
    arrivalDate,
    departureDate,
    hotelId: hotelData.hotel.id,
    hotelName: hotelData.hotel.name,
    country: hotelData.hotel.address.country,
    hotelCity: hotelData.hotel.address.city,
    bookingCode,
    isRedemption: searchType === SEARCH_TYPE_REDEMPTION,
    specialRoomType,
    rooms,
  })

  let shouldTrackNoAvailability = false
  if (availability && !availability.isFetching && availability.data) {
    shouldTrackNoAvailability = availability.data.some((room) => {
      if (!room || "error" in room) return false

      const allRoomsNotAvailable = room.roomConfigurations.every(
        (roomConfig) => roomConfig.status === AvailabilityEnum.NotAvailable
      )

      const isPublicPromotionWithCode = room.roomConfigurations.some((r) => {
        const filteredCampaigns = r.campaign.filter(Boolean)
        return filteredCampaigns.length
          ? filteredCampaigns.every(
              (product) => !!product.rateDefinition?.isCampaignRate
            )
          : false
      })

      const noAvailableBookingCodeRooms =
        !isPublicPromotionWithCode &&
        room.roomConfigurations.every(
          (r) => r.status === AvailabilityEnum.NotAvailable || !r.code.length
        )

      return (
        allRoomsNotAvailable ||
        (input.bookingCode && noAvailableBookingCodeRooms)
      )
    })
  }

  return (
    <>
      <NoAvailabilityTracking
        lang={lang}
        shouldTrackNoAvailability={shouldTrackNoAvailability}
        hotelsTrackingData={hotelsTrackingData}
        pageTrackingData={pageTrackingData}
      />

      <TrackingSDK hotelInfo={hotelsTrackingData} pageData={pageTrackingData} />
    </>
  )
}
