"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 {
  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 {
    currentStep,
    bedType,
    breakfast,
    totalPrice,
    roomPrice,
    roomRate,
    packages,
  } = useEnterDetailsStore((state) => state)
  const pathName = usePathname()
  const sessionId = useSessionId()

  // We need this check to differentiate hard vs soft navigations
  // This is not because of StrictMode
  const hasRunInitial = useRef<boolean>(false)
  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 pageObject = useMemo(() => {
    const pageTrackingData: TrackingSDKPageData = {
      pageId: currentStep,
      domainLanguage: lang,
      channel: TrackingChannelEnum["hotelreservation"],
      pageName: `hotelreservation|${currentStep}`,
      siteSections: `hotelreservation|${currentStep}`,
      pageType: currentStep,
      siteVersion: "new-web",
    }

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

  const hotelDetailsData = useMemo(() => {
    const isMember = true
    const rate = isMember ? roomRate.memberRate : roomRate.publicRate
    const data: TrackingSDKHotelInfo = {
      ...initialHotelsTrackingData,
      rateCode: rate?.rateCode,
      rateCodeType: rate?.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,
    }

    return data
  }, [
    roomRate.memberRate,
    roomRate.publicRate,
    initialHotelsTrackingData,
    cancellationRule,
    totalPrice.local?.currency,
    totalPrice.local?.price,
    breakfast,
    packages,
    selectedRoom.roomType,
    bedType?.description,
    bedType?.roomTypeCode,
    roomPrice.perStay.local.price,
  ])

  useEffect(() => {
    if (!hasRunInitial.current) {
      hasRunInitial.current = true
      previousPathname.current = pathName // Set initial path to compare later
      return
    }

    //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
}
