"use client"

import { useRouter } from "next/navigation"
import { useEffect } from "react"

import { BookingStatusEnum, MEMBERSHIP_FAILED_ERROR } from "@/constants/booking"

import LoadingSpinner from "@/components/LoadingSpinner"
import { useHandleBookingStatus } from "@/hooks/booking/useHandleBookingStatus"
import { trackEvent } from "@/utils/tracking/base"

import { clearGlaSessionStorage, readGlaFromSessionStorage } from "./helpers"
import TimeoutSpinner from "./TimeoutSpinner"

const validBookingStatuses = [
  BookingStatusEnum.PaymentSucceeded,
  BookingStatusEnum.BookingCompleted,
]

interface HandleStatusPollingProps {
  confirmationNumber: string
  successRedirectUrl: string
}

export default function HandleSuccessCallback({
  confirmationNumber,
  successRedirectUrl,
}: HandleStatusPollingProps) {
  const router = useRouter()

  const {
    data: bookingStatus,
    error,
    isTimeout,
  } = useHandleBookingStatus({
    confirmationNumber,
    expectedStatuses: validBookingStatuses,
    maxRetries: 10,
    retryInterval: 2000,
    enabled: true,
  })

  useEffect(() => {
    if (!bookingStatus?.reservationStatus) {
      return
    }

    if (
      validBookingStatuses.includes(
        bookingStatus.reservationStatus as BookingStatusEnum
      )
    ) {
      const lateArrivalGuarantee = readGlaFromSessionStorage()
      if (lateArrivalGuarantee) {
        trackEvent({
          event: "guaranteeBookingSuccess",
          hotelInfo: {
            lateArrivalGuarantee,
            guaranteedProduct: "room",
          },
        })
        clearGlaSessionStorage()
      }
      // a successful booking can still have membership errors
      const membershipFailedError = bookingStatus.errors.find(
        (e) => e.errorCode === MEMBERSHIP_FAILED_ERROR
      )
      const errorParam = membershipFailedError
        ? `&errorCode=${membershipFailedError.errorCode}`
        : ""

      router.replace(`${successRedirectUrl}${errorParam}`)
    }
  }, [bookingStatus, successRedirectUrl, router])

  if (isTimeout || error) {
    return <TimeoutSpinner />
  }

  return <LoadingSpinner fullPage />
}
