"use client"; import { useEffect, useMemo } from "react"; import { BackButton } from "@/app/_components"; import { Checkbox, MobileShell } from "@/app/_components/core"; import { PaymentMethodSelector } from "@/app/_components/payment/payment-method-selector"; import { usePaymentMethodSelection } from "@/app/_hooks/use-payment-method-selection"; import { usePaymentPlanAnalytics } from "@/app/_hooks/use-payment-plan-analytics"; import { AppConstants } from "@/core/app_constants"; import type { PayChannel } from "@/data/schemas/payment"; import type { SubscriptionReturnTo } from "@/lib/navigation/subscription_exit"; import { DEFAULT_CHARACTER_SLUG } from "@/data/constants/character"; import { behaviorAnalytics, getDefaultPaymentAnalyticsContext, type PaymentAnalyticsContext, } from "@/lib/analytics"; import { getPaymentMethodConfig } from "@/lib/payment/payment_method"; import { useUserState } from "@/stores/user/user-context"; import { SubscriptionCheckoutButton, SubscriptionCoinsOfferSection, SubscriptionPaymentSuccessDialog, SubscriptionVipOfferSection, } from "./components"; import styles from "./components/subscription-screen.module.css"; import { findSelectedSubscriptionPlan, getFirstRechargeOfferView, getDefaultSubscriptionPlanId, toCoinsOfferPlanViews, toVipOfferPlanViews, type SubscriptionType, } from "./subscription-screen.helpers"; import { useSubscriptionPaymentFlow } from "./use-subscription-payment-flow"; export type { SubscriptionType } from "./subscription-screen.helpers"; export interface SubscriptionScreenProps { subscriptionType?: SubscriptionType; shouldResumePendingOrder?: boolean; returnTo?: SubscriptionReturnTo; initialPayChannel?: PayChannel | null; analyticsContext?: PaymentAnalyticsContext; characterSlug?: string; } export function SubscriptionScreen({ subscriptionType = "vip", shouldResumePendingOrder = false, returnTo = null, initialPayChannel = null, analyticsContext: providedAnalyticsContext, characterSlug = DEFAULT_CHARACTER_SLUG, }: SubscriptionScreenProps) { const userState = useUserState(); const countryCode = userState.currentUser?.countryCode; const paymentMethodConfig = getPaymentMethodConfig({ countryCode, requestedPayChannel: initialPayChannel, }); const { payment, paymentDispatch, showPaymentSuccessDialog, handleBackClick, handlePaymentSuccessClose, } = useSubscriptionPaymentFlow({ subscriptionType, shouldResumePendingOrder, returnTo, characterSlug, initialPayChannel: paymentMethodConfig.initialPayChannel, }); const canSubscribeVip = subscriptionType === "vip"; const analyticsContext = providedAnalyticsContext ?? getDefaultPaymentAnalyticsContext(subscriptionType); const vipOfferPlans = useMemo( () => toVipOfferPlanViews(payment.plans), [payment.plans], ); const directCoinsPlans = useMemo( () => toCoinsOfferPlanViews(payment.plans), [payment.plans], ); const displayedPlans = useMemo(() => { const displayedPlanIds = [ ...(canSubscribeVip ? vipOfferPlans : []), ...directCoinsPlans, ].map((plan) => plan.id); return displayedPlanIds.flatMap((planId) => { const plan = payment.plans.find((item) => item.planId === planId); return plan ? [plan] : []; }); }, [canSubscribeVip, directCoinsPlans, payment.plans, vipOfferPlans]); usePaymentPlanAnalytics(displayedPlans, analyticsContext); const firstRechargeOffer = useMemo( () => getFirstRechargeOfferView({ isFirstRecharge: payment.isFirstRecharge, subscriptionType, vipPlans: vipOfferPlans, coinPlans: directCoinsPlans, }), [ directCoinsPlans, payment.isFirstRecharge, subscriptionType, vipOfferPlans, ], ); const selectedPlan = findSelectedSubscriptionPlan({ canSubscribeVip, selectedPlanId: payment.selectedPlanId, vipPlans: vipOfferPlans, coinPlans: directCoinsPlans, }); const isPaymentBusy = payment.isCreatingOrder || payment.isPollingOrder; const canActivate = selectedPlan !== null && payment.agreed && !isPaymentBusy; const handleSelectPlan = (planId: string) => { const plan = payment.plans.find((item) => item.planId === planId); if (plan) behaviorAnalytics.planClick(plan, analyticsContext); paymentDispatch({ type: "PaymentPlanSelected", planId }); }; const handlePaymentMethodChange = (payChannel: PayChannel) => { paymentDispatch({ type: "PaymentPayChannelChanged", payChannel, }); }; usePaymentMethodSelection({ config: paymentMethodConfig, currentPayChannel: payment.payChannel, isPaymentBusy, requestedPayChannel: initialPayChannel, onChange: handlePaymentMethodChange, }); useEffect(() => { const defaultPlanId = getDefaultSubscriptionPlanId({ canSubscribeVip, selectedPlanId: payment.selectedPlanId, status: payment.status, isLoadingPlans: payment.isLoadingPlans, selectedPlan, vipPlans: vipOfferPlans, coinPlans: directCoinsPlans, }); if (!defaultPlanId) return; paymentDispatch({ type: "PaymentPlanSelected", planId: defaultPlanId, }); }, [ canSubscribeVip, directCoinsPlans, payment.isLoadingPlans, paymentDispatch, payment.selectedPlanId, payment.status, selectedPlan, vipOfferPlans, ]); return (
{firstRechargeOffer ? (
{firstRechargeOffer.badgeText}

{firstRechargeOffer.title}

{firstRechargeOffer.subtitle}

{firstRechargeOffer.renewalNotice ? (

{firstRechargeOffer.renewalNotice}

) : null}
) : null}
{canSubscribeVip ? ( ) : null}
{paymentMethodConfig.canChoosePaymentMethod ? (
) : null}
paymentDispatch({ type: "PaymentAgreementChanged", agreed, }) } label={ I agree to the{" "} VIP Membership Benefits Agreement {" "} and{" "} Automatic renewal Agreement } />
); }