"use client"
import { usePathname } from "next/navigation"
import { useEffect, useMemo, useRef } from "react"

import { useEnterDetailsStore } from "@/stores/enter-details"

import { useSessionId } from "@/hooks/useSessionId"
import { createSDKPageObject, pushToDataLayer } from "@/utils/tracking"

import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import {
  type Ancillary,
  TrackingChannelEnum,
  type TrackingSDKHotelInfo,
  type TrackingSDKPageData,
  type TrackingSDKUserData,
} from "@/types/components/tracking"
import type { Packages } from "@/types/requests/packages"
import type { Lang } from "@/constants/languages"
import type { RoomConfiguration } from "@/server/routers/hotels/output"

type Props = {
  initialHotelsTrackingData: TrackingSDKHotelInfo
  userTrackingData: TrackingSDKUserData
  lang: Lang
  selectedRoom: RoomConfiguration
  cancellationRule: string
}

export default function EnterDetailsTracking(props: Props) {
  const {
    initialHotelsTrackingData,
    userTrackingData,
    lang,
    selectedRoom,
    cancellationRule,
  } = props

  const { bedType, breakfast, totalPrice, roomPrice, roomRate, packages } =
    useEnterDetailsStore((state) => state)
  const pathName = usePathname()
  const sessionId = useSessionId()

  const previousPathname = useRef<string | null>(null)

  const getSpecialRoomType = (packages: Packages | null) => {
    if (!packages) {
      return ""
    }

    const specialRoom = packages.find((p) =>
      [
        RoomPackageCodeEnum.PET_ROOM,
        RoomPackageCodeEnum.ALLERGY_ROOM,
        RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
      ].includes(p.code)
    )

    switch (specialRoom?.code) {
      case RoomPackageCodeEnum.PET_ROOM:
        return "pet-friendly"
      case RoomPackageCodeEnum.ALLERGY_ROOM:
        return "allergy room"
      case RoomPackageCodeEnum.ACCESSIBILITY_ROOM:
        return "accessibility room"
      default:
        return ""
    }
  }

  const getAnalyticsRateCode = (rateCodeName: string | undefined) => {
    switch (rateCodeName) {
      case "FLEXEU":
        return "flex"
      case "CHANGEEU":
        return "change"
      case "SAVEEU":
        return "save"
      default:
        return rateCodeName
    }
  }

  const pageObject = useMemo(() => {
    const stepByPathname = pathName.split("/").pop()!
    const pageTrackingData: TrackingSDKPageData = {
      pageId: stepByPathname,
      domainLanguage: lang,
      channel: TrackingChannelEnum["hotelreservation"],
      pageName: `hotelreservation|${stepByPathname}`,
      siteSections: `hotelreservation|${stepByPathname}`,
      pageType: stepByPathname,
      siteVersion: "new-web",
    }

    const trackingData = {
      ...pageTrackingData,
      pathName,
      sessionId,
      pageLoadTime: 0, // Yes, this is instant
    }
    const pageObject = createSDKPageObject(trackingData)

    return pageObject
  }, [lang, sessionId, pathName])

  const hotelDetailsData = useMemo(() => {
    const isMember = true
    const rate = isMember ? roomRate.memberRate : roomRate.publicRate

    const breakfastAncillary = breakfast && {
      hotelid: initialHotelsTrackingData.hotelID,
      productName: "BreakfastAdult",
      productCategory: "", // TODO: Add category
      productId: breakfast.code,
      productPrice: +breakfast.localPrice.price,
      productUnits: initialHotelsTrackingData.noOfAdults,
      productPoints: 0,
      productType: "food",
    }

    const data: TrackingSDKHotelInfo = {
      ...initialHotelsTrackingData,
      rateCode: rate?.rateCode,
      rateCodeType: roomRate.publicRate.rateType,
      rateCodeName: rate?.rateCode,
      rateCodeCancellationRule: cancellationRule,
      revenueCurrencyCode: totalPrice.local?.currency,
      breakfastOption: breakfast ? "breakfast buffet" : "no breakfast",
      totalPrice: totalPrice.local?.price,
      specialRoomType: getSpecialRoomType(packages),
      roomTypeName: selectedRoom.roomType,
      bedType: bedType?.description,
      roomTypeCode: bedType?.roomTypeCode,
      roomPrice: roomPrice.perStay.local.price,
      discount: roomRate.memberRate
        ? roomRate.publicRate.localPrice.pricePerStay -
          roomRate.memberRate.localPrice.pricePerStay
        : 0,
      analyticsrateCode: getAnalyticsRateCode(roomRate.publicRate.rateCode),
      ancillaries: breakfastAncillary ? [breakfastAncillary] : [],
    }

    return data
  }, [
    bedType,
    breakfast,
    totalPrice,
    roomPrice,
    roomRate,
    packages,
    initialHotelsTrackingData,
    cancellationRule,
    selectedRoom.roomType,
  ])

  useEffect(() => {
    if (previousPathname.current !== pathName) {
      pushToDataLayer({
        event: "pageView",
        pageInfo: pageObject,
        userInfo: userTrackingData,
        hotelInfo: hotelDetailsData,
      })
    }
    previousPathname.current = pathName // Update for next render
  }, [userTrackingData, pageObject, hotelDetailsData, pathName])

  return null
}
