"use client";

import { type Dispatch, useEffect, useRef } from "react";

import type { PayChannel } from "@/data/schemas/payment";
import type { PendingPaymentSubscriptionType } from "@/lib/payment/pending_payment_order";
import {
  usePaymentDispatch,
  usePaymentState,
  type PaymentContextState,
} from "@/stores/payment/payment-context";
import type { PaymentEvent } from "@/stores/payment/payment-events";
import type { PaymentPlanCatalog } from "@/stores/payment/payment-state";

import { usePendingPaymentOrderLifecycle } from "./use-pending-payment-order-lifecycle";

export interface UsePaymentRouteFlowInput {
  catalog?: PaymentPlanCatalog;
  initialPayChannel: PayChannel;
  paymentType: PendingPaymentSubscriptionType;
  shouldResumePendingOrder: boolean;
  characterId?: string;
  initialCategory?: string | null;
  initialPlanId?: string | null;
  initialAutoRenew?: boolean | null;
  commercialOfferId?: string | null;
  resumeOrderId?: string | null;
  chatActionId?: string | null;
}

export interface PaymentRouteFlow {
  payment: PaymentContextState;
  paymentDispatch: Dispatch<PaymentEvent>;
}

/**
 * Owns the lifecycle shared by payment entry routes:
 * initialize the requested catalog and restore or clean up redirect orders.
 */
export function usePaymentRouteFlow({
  catalog = "default",
  initialPayChannel,
  paymentType,
  shouldResumePendingOrder,
  characterId,
  initialCategory = null,
  initialPlanId = null,
  initialAutoRenew = null,
  commercialOfferId = null,
  resumeOrderId = null,
  chatActionId = null,
}: UsePaymentRouteFlowInput): PaymentRouteFlow {
  const payment = usePaymentState();
  const paymentDispatch = usePaymentDispatch();
  const initializedCatalogKeyRef = useRef<string | null>(null);
  const resumedOrderIdRef = useRef<string | null>(null);
  const catalogKey = [
    catalog,
    characterId ?? "",
    initialCategory ?? "",
    initialPlanId ?? "",
    initialAutoRenew === null ? "" : String(initialAutoRenew),
    commercialOfferId ?? "",
    chatActionId ?? "",
  ].join(":");

  usePendingPaymentOrderLifecycle({
    payment,
    paymentDispatch,
    paymentType,
    shouldResumePendingOrder,
  });

  useEffect(() => {
    if (initializedCatalogKeyRef.current === catalogKey) return;
    initializedCatalogKeyRef.current = catalogKey;
    paymentDispatch({
      type: "PaymentInit",
      catalog,
      payChannel: initialPayChannel,
      ...(characterId ? { characterId } : {}),
      ...(initialCategory ? { category: initialCategory } : {}),
      ...(initialPlanId ? { planId: initialPlanId } : {}),
      ...(initialAutoRenew === null
        ? {}
        : { autoRenew: initialAutoRenew }),
      ...(commercialOfferId ? { commercialOfferId } : {}),
      ...(chatActionId ? { chatActionId } : {}),
    });
  }, [
    catalog,
    catalogKey,
    characterId,
    commercialOfferId,
    chatActionId,
    initialCategory,
    initialPlanId,
    initialAutoRenew,
    initialPayChannel,
    paymentDispatch,
  ]);

  useEffect(() => {
    if (!resumeOrderId || resumedOrderIdRef.current === resumeOrderId) return;
    resumedOrderIdRef.current = resumeOrderId;
    paymentDispatch({ type: "PaymentReturned", orderId: resumeOrderId });
  }, [paymentDispatch, resumeOrderId]);

  return { payment, paymentDispatch };
}
