import { redirect } from "next/navigation"

import {
  BOOKING_CONFIRMATION_NUMBER,
  PaymentErrorCodeEnum,
} from "@/constants/booking"
import {
  bookingConfirmation,
  payment,
} from "@/constants/routes/hotelReservation"
import { serverClient } from "@/lib/trpc/server"

import PaymentCallback from "@/components/HotelReservation/EnterDetails/Payment/PaymentCallback"
import { trackPaymentEvent } from "@/utils/tracking"

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

export default async function PaymentCallbackPage({
  params,
  searchParams,
}: PageArgs<
  LangParams,
  { status: "error" | "success" | "cancel"; confirmationNumber?: string }
>) {
  console.log(`[payment-callback] callback started`)
  const lang = params.lang
  const status = searchParams.status
  const confirmationNumber = searchParams.confirmationNumber

  if (status === "success" && confirmationNumber) {
    const confirmationUrl = `${bookingConfirmation(lang)}?${BOOKING_CONFIRMATION_NUMBER}=${confirmationNumber}`

    console.log(`[payment-callback] redirecting to: ${confirmationUrl}`)
    redirect(confirmationUrl)
  }

  const returnUrl = payment(lang)
  const searchObject = new URLSearchParams()

  if (confirmationNumber) {
    try {
      const bookingStatus = await serverClient().booking.status({
        confirmationNumber,
      })
      searchObject.set(
        "errorCode",
        bookingStatus?.metadata?.errorCode
          ? bookingStatus.metadata.errorCode.toString()
          : PaymentErrorCodeEnum.Failed.toString()
      )
      trackPaymentEvent({
        event: "paymentFail",
        hotelId: searchObject.get("hotel"),
        errorMessage:
          bookingStatus?.metadata?.errorMessage ??
          `No error message found for booking ${confirmationNumber}, status: ${status}`,
      })
    } catch (error) {
      console.error(
        `[payment-callback] failed to get booking status for ${confirmationNumber}, status: ${status}`
      )
      if (status === "cancel") {
        searchObject.set("errorCode", PaymentErrorCodeEnum.Cancelled.toString())
        trackPaymentEvent({
          event: "paymentCancel",
          hotelId: searchObject.get("hotel"),
        })
      }
      if (status === "error") {
        searchObject.set("errorCode", PaymentErrorCodeEnum.Failed.toString())
        trackPaymentEvent({
          event: "paymentFail",
          hotelId: searchObject.get("hotel"),
          errorMessage: `Failed to get booking status for ${confirmationNumber}, status: ${status}`,
        })
      }
    }
  }

  return (
    <PaymentCallback
      returnUrl={returnUrl.toString()}
      searchObject={searchObject}
    />
  )
}
