"use client"; import { type Dispatch, useEffect, useRef } from "react"; import { clearPendingPaymentOrder, getPendingPaymentOrderForType, type PendingPaymentSubscriptionType, } from "@/lib/payment/pending_payment_order"; import type { PaymentEvent } from "@/stores/payment/payment-events"; export interface PaymentOrderLifecycleState { currentOrderId: string | null; isPaid: boolean; isPollingOrder: boolean; status: string; } export interface ShouldInspectPendingPaymentOrderInput extends PaymentOrderLifecycleState { shouldResumePendingOrder: boolean; } export interface UsePendingPaymentOrderLifecycleInput { payment: PaymentOrderLifecycleState; paymentDispatch: Dispatch; paymentType: PendingPaymentSubscriptionType; shouldResumePendingOrder: boolean; } export function shouldInspectPendingPaymentOrder({ isPaid, isPollingOrder, shouldResumePendingOrder, status, }: ShouldInspectPendingPaymentOrderInput): boolean { return ( status === "ready" || (!shouldResumePendingOrder && (isPollingOrder || isPaid || status === "failed")) ); } export function usePendingPaymentOrderLifecycle({ payment, paymentDispatch, paymentType, shouldResumePendingOrder, }: UsePendingPaymentOrderLifecycleInput): void { const resumedPendingOrderRef = useRef(null); useEffect(() => { if ( !shouldInspectPendingPaymentOrder({ currentOrderId: payment.currentOrderId, isPaid: payment.isPaid, isPollingOrder: payment.isPollingOrder, shouldResumePendingOrder, status: payment.status, }) ) { return; } let cancelled = false; const handlePendingOrder = async () => { const result = await getPendingPaymentOrderForType(paymentType); if (cancelled || !result.success || result.data === null) return; if (!shouldResumePendingOrder) { await clearPendingPaymentOrder(); if ( payment.currentOrderId === result.data.orderId && (payment.isPollingOrder || payment.isPaid || payment.status === "failed") ) { paymentDispatch({ type: "PaymentReset" }); } return; } if (payment.currentOrderId === result.data.orderId) return; if (resumedPendingOrderRef.current === result.data.orderId) return; resumedPendingOrderRef.current = result.data.orderId; paymentDispatch({ type: "PaymentReturned", orderId: result.data.orderId, createdAt: result.data.createdAt, }); }; void handlePendingOrder(); return () => { cancelled = true; }; }, [ payment.currentOrderId, payment.isPaid, payment.isPollingOrder, payment.status, paymentDispatch, paymentType, shouldResumePendingOrder, ]); useEffect(() => { if (!payment.currentOrderId) return; if (!payment.isPaid && payment.status !== "failed") return; void clearPendingPaymentOrder(); }, [payment.currentOrderId, payment.isPaid, payment.status]); }