"use client";

/**
 * PaymentContext：基于 XState v5 的 React Context Provider
 */
import type { Dispatch, ReactNode } from "react";
import { createActorContext, shallowEqual } from "@xstate/react";
import type { SnapshotFrom } from "xstate";

import { paymentMachine } from "./payment-machine";
import type {
  PaymentEvent,
  PaymentState as MachineContext,
} from "./payment-machine";

export interface PaymentContextState {
  status: string;
  plans: MachineContext["plans"];
  isFirstRecharge: MachineContext["isFirstRecharge"];
  selectedPlanId: string;
  payChannel: MachineContext["payChannel"];
  autoRenew: boolean;
  agreed: boolean;
  currentOrderId: string | null;
  payParams: Record<string, unknown> | null;
  orderStatus: MachineContext["orderStatus"];
  errorMessage: string | null;
  launchNonce: number;
  isLoadingPlans: boolean;
  isCreatingOrder: boolean;
  isPollingOrder: boolean;
  isPaid: boolean;
}

type PaymentSnapshot = SnapshotFrom<typeof paymentMachine>;
type PaymentSelector<T> = (snapshot: PaymentSnapshot) => T;

const PaymentActorContext = createActorContext(paymentMachine);

export interface PaymentProviderProps {
  children: ReactNode;
}

export function PaymentProvider({ children }: PaymentProviderProps) {
  return <PaymentActorContext.Provider>{children}</PaymentActorContext.Provider>;
}

export function usePaymentState(): PaymentContextState {
  return usePaymentSelector(selectPaymentState, shallowEqual);
}

export function usePaymentDispatch(): Dispatch<PaymentEvent> {
  return PaymentActorContext.useActorRef().send;
}

export function usePaymentSelector<T>(
  selector: PaymentSelector<T>,
  compare?: (previous: T, next: T) => boolean,
): T {
  return PaymentActorContext.useSelector(selector, compare);
}

function selectPaymentState(state: PaymentSnapshot): PaymentContextState {
  return {
    status: String(state.value),
    plans: state.context.plans,
    isFirstRecharge: state.context.isFirstRecharge,
    selectedPlanId: state.context.selectedPlanId,
    payChannel: state.context.payChannel,
    autoRenew: state.context.autoRenew,
    agreed: state.context.agreed,
    currentOrderId: state.context.currentOrderId,
    payParams: state.context.payParams,
    orderStatus: state.context.orderStatus,
    errorMessage: state.context.errorMessage,
    launchNonce: state.context.launchNonce,
    isLoadingPlans:
      state.matches("loadingCachedPlans") ||
      state.matches("loadingPlans") ||
      state.matches("refreshingPlans"),
    isCreatingOrder: state.matches("creatingOrder"),
    isPollingOrder:
      state.matches("pollingOrder") || state.matches("waitingForPayment"),
    isPaid: state.matches("paid"),
  };
}
