"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<PaymentEvent>;
  paymentType: PendingPaymentSubscriptionType;
  shouldResumePendingOrder: boolean;
}

export function shouldInspectPendingPaymentOrder({
  isPaid,
  isPollingOrder,
  shouldResumePendingOrder,
  status,
}: ShouldInspectPendingPaymentOrderInput): boolean {
  return (
    status === "ready" ||
    (!shouldResumePendingOrder &&
      (isPollingOrder || isPaid || status === "failed" || status === "expired"))
  );
}

export function usePendingPaymentOrderLifecycle({
  payment,
  paymentDispatch,
  paymentType,
  shouldResumePendingOrder,
}: UsePendingPaymentOrderLifecycleInput): void {
  const resumedPendingOrderRef = useRef<string | null>(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" ||
            payment.status === "expired")
        ) {
          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" &&
      payment.status !== "expired"
    ) {
      return;
    }

    void clearPendingPaymentOrder();
  }, [payment.currentOrderId, payment.isPaid, payment.status]);
}
