import { differenceInCalendarDays, format, isWeekend } from "date-fns"

import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import {
  TrackingChannelEnum,
  type TrackingSDKHotelInfo,
  type TrackingSDKPageData,
} from "@/types/components/tracking"
import type { Lang } from "@/constants/languages"
import type { ChildrenInRoom } from "@/utils/hotelSearchDetails"

export function getTracking(
  lang: Lang,
  isAlternativeFor: boolean,
  isAlternativeHotels: boolean,
  arrivalDate: Date,
  departureDate: Date,
  adultsInRoom: number[],
  childrenInRoom: ChildrenInRoom,
  hotelsResult: number,
  hotelId: string | undefined,
  noOfRooms: number,
  country: string | undefined,
  hotelCity: string | undefined,
  paramCity: string | undefined,
  bookingCode?: string,
  isBookingCodeRateAvailable?: boolean,
  isRedemption?: boolean,
  isRedemptionAvailability?: boolean
) {
  const pageTrackingData: TrackingSDKPageData = {
    channel: TrackingChannelEnum["hotelreservation"],
    domainLanguage: lang,
    pageId: isAlternativeFor ? "alternative-hotels" : "select-hotel",
    pageName: isAlternativeHotels
      ? "hotelreservation|alternative-hotels|mapview"
      : "hotelreservation|select-hotel|mapview",
    pageType: "bookinghotelsmapviewpage",
    siteSections: isAlternativeHotels
      ? "hotelreservation|altervative-hotels|mapview"
      : "hotelreservation|select-hotel|mapview",
    siteVersion: "new-web",
  }

  const hotelsTrackingData: TrackingSDKHotelInfo = {
    ageOfChildren: childrenInRoom
      ?.map((c) => c?.map((k) => k.age).join(",") ?? "")
      .join("|"),
    arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
    availableResults: hotelsResult,
    bookingCode: bookingCode ? bookingCode : "n/a",
    bookingCodeAvailability: isBookingCodeRateAvailable ? "true" : "false",
    bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
    childBedPreference: childrenInRoom
      ?.map((c) => c?.map((k) => ChildBedMapEnum[k.bed]).join(",") ?? "")
      .join("|"),
    country,
    departureDate: format(departureDate, "yyyy-MM-dd"),
    duration: differenceInCalendarDays(departureDate, arrivalDate),
    leadTime: differenceInCalendarDays(arrivalDate, new Date()),
    noOfAdults: adultsInRoom.join(","),
    noOfChildren: childrenInRoom?.map((kids) => kids?.length ?? 0).join(","),
    noOfRooms,
    region: hotelCity,
    rewardNight: isRedemption ? "yes" : "no",
    rewardNightAvailability: isRedemptionAvailability ? "true" : "false",
    searchTerm: isAlternativeFor ? hotelId : (paramCity as string),
    searchType: "destination",
  }

  return {
    hotelsTrackingData,
    pageTrackingData,
  }
}
