import { notFound } from "next/navigation"

import {
  BookingErrorCodeEnum,
  PaymentCallbackStatusEnum,
} from "@/constants/booking"
import { myStay } from "@/constants/routes/myStay"
import { serverClient } from "@/lib/trpc/server"

import GuaranteeCallback from "@/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback"
import TrackGuarantee from "@/components/HotelReservation/MyStay/TrackGuarantee"
import LoadingSpinner from "@/components/LoadingSpinner"

import type { LangParams, PageArgs } from "@/types/params"

export default async function GuaranteePaymentCallbackPage(
  props: PageArgs<
    LangParams,
    {
      status?: PaymentCallbackStatusEnum
      RefId?: string
      confirmationNumber?: string
      ancillary?: string
    }
  >
) {
  const searchParams = await props.searchParams
  const params = await props.params
  console.log(`[gla-payment-callback] callback started`)
  const lang = params.lang
  const status = searchParams.status
  const confirmationNumber = searchParams.confirmationNumber
  const refId = searchParams.RefId
  if (!status || !confirmationNumber || !refId) {
    notFound()
  }
  const isAncillaryFlow = searchParams.ancillary

  const myStayUrl = `${myStay[lang]}?RefId=${encodeURIComponent(refId)}`
  const searchObject = new URLSearchParams()

  if (status === PaymentCallbackStatusEnum.Success && confirmationNumber) {
    if (isAncillaryFlow) {
      return (
        <GuaranteeCallback
          returnUrl={myStayUrl}
          refId={refId}
          confirmationNumber={confirmationNumber}
          lang={lang}
        />
      )
    }
    console.log(`[gla-payment-callback] redirecting to: ${myStayUrl}`)
    return <TrackGuarantee status={status} redirectUrl={myStayUrl} />
  }

  let errorMessage = undefined

  if (refId) {
    try {
      const caller = await serverClient()
      const bookingStatus = await caller.booking.status({
        refId,
      })

      const { booking } = bookingStatus

      const error = booking.errors.find((e) => e.errorCode)
      errorMessage =
        error?.description ??
        `No error message found for booking ${confirmationNumber}, status: ${status}`

      searchObject.set(
        "errorCode",
        error
          ? error.errorCode.toString()
          : BookingErrorCodeEnum.TransactionFailed
      )
    } catch {
      console.error(
        `[gla-payment-callback] failed to get booking status for ${confirmationNumber}, status: ${status}`
      )
      if (status === PaymentCallbackStatusEnum.Cancel) {
        searchObject.set("errorCode", BookingErrorCodeEnum.TransactionCancelled)
      } else if (status === PaymentCallbackStatusEnum.Error) {
        searchObject.set("errorCode", BookingErrorCodeEnum.TransactionFailed)
        errorMessage = `Failed to get booking status for ${confirmationNumber}, status: ${status}`
      }
    }
    console.log(errorMessage)

    if (isAncillaryFlow) {
      searchObject.set("ancillary", "ancillary")
    }

    return (
      <TrackGuarantee
        status={status}
        isAncillaryFlow={!!isAncillaryFlow}
        redirectUrl={`${myStayUrl}&${searchObject.toString()}`}
        errorMessage={errorMessage}
      />
    )
  }

  return <LoadingSpinner />
}
