"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 {
  refId: string
  sig: string
  successRedirectUrl: string
}

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

  useEffect(() => {
    // Cookie is used by Booking Confirmation page to validate that the user came from payment callback
    document.cookie = `bcsig=${sig}; Path=/; Max-Age=60; Secure; SameSite=Strict`
  }, [sig])

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

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

    if (
      validBookingStatuses.includes(
        bookingStatus.booking.reservationStatus as BookingStatusEnum
      )
    ) {
      const glaSessionData = readGlaFromSessionStorage()
      if (glaSessionData) {
        trackEvent({
          event: "guaranteeBookingSuccess",
          hotelInfo: {
            lateArrivalGuarantee: glaSessionData.lateArrivalGuarantee,
            hotelId: glaSessionData.hotelId,
            guaranteedProduct: "room",
          },
          paymentInfo: {
            hotelId: glaSessionData.hotelId,
            type: glaSessionData.paymentMethod,
            isSavedCreditCard: glaSessionData.isSavedCreditCard,
          },
        })
        clearGlaSessionStorage()
      }
      // a successful booking can still have membership errors
      const membershipFailedError = bookingStatus.booking.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 />
}
