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

import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import type { Room } from "@/types/components/hotelReservation/selectRate/selectRate"
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,
  arrivalDate: Date,
  departureDate: Date,
  adultsInRoom: number[],
  childrenInRoom: ChildrenInRoom,
  hotelId: string,
  hotelName: string,
  noOfRooms: number,
  country: string | undefined,
  hotelCity: string | undefined,
  paramCity: string | undefined,
  bookingCode?: string,
  isRedemption?: boolean,
  rooms?: Room[]
) {
  const pageTrackingData: TrackingSDKPageData = {
    channel: TrackingChannelEnum.hotelreservation,
    domainLanguage: lang,
    pageId: "select-rate",
    pageName: "hotelreservation|select-rate",
    pageType: "bookingroomsandratespage",
    siteSections: "hotelreservation|select-rate",
    siteVersion: "new-web",
  }

  const hotelsTrackingData: TrackingSDKHotelInfo = {
    ageOfChildren: childrenInRoom
      ?.map((c) => c?.map((k) => k.age).join(",") ?? "")
      .join("|"),
    arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
    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),
    hotelID: hotelId,
    leadTime: differenceInCalendarDays(arrivalDate, new Date()),
    noOfAdults: adultsInRoom.join(","),
    noOfChildren: childrenInRoom?.map((kids) => kids?.length ?? 0).join(","),
    noOfRooms,
    region: hotelCity,
    searchTerm: paramCity ?? hotelName,
    searchType: "hotel",
    bookingCode: bookingCode ?? "n/a",
    rewardNight: isRedemption ? "yes" : "no",
    specialRoomType: rooms
      ?.map((room) => {
        const packages = room.packages
          ?.map((pkg) => {
            if (pkg === RoomPackageCodeEnum.ACCESSIBILITY_ROOM) {
              return "accessibility"
            } else if (pkg === RoomPackageCodeEnum.ALLERGY_ROOM) {
              return "allergy friendly"
            } else if (pkg === RoomPackageCodeEnum.PET_ROOM) {
              return "pet room"
            } else {
              return ""
            }
          })
          .join(",")

        return packages ?? ""
      })
      .join("|"),
  }

  return {
    hotelsTrackingData,
    pageTrackingData,
  }
}
