import type { PaymentPlan } from "@/data/dto/payment"; import type { CoinsOfferPlanView } from "./components/subscription-coins-offer-section"; import type { SubscriptionPlanView } from "./components/subscription-plan-card"; import type { VipOfferPlanView } from "./components/subscription-vip-offer-section"; export type SubscriptionType = "vip" | "voice"; export const SUBSCRIPTION_BANNER_TITLES: Record = { vip: "Subscribe to become the VIP Member", voice: "Buy Voice Message Package", }; export function isVipPlan(plan: PaymentPlan): boolean { return plan.orderType.startsWith("vip_") || plan.planId.startsWith("vip_"); } export function isCreditPlan(plan: PaymentPlan): boolean { const orderType = plan.orderType.toLowerCase(); const planId = plan.planId.toLowerCase(); return ( plan.dolAmount !== null || orderType.startsWith("dol_") || orderType.startsWith("credit_") || planId.startsWith("dol_") || planId.startsWith("credit_") || orderType.includes("credit") || planId.includes("credit") ); } function isVoicePackagePlan(plan: PaymentPlan): boolean { const orderType = plan.orderType.toLowerCase(); const planId = plan.planId.toLowerCase(); return ( isCreditPlan(plan) || orderType.includes("voice") || planId.includes("voice") ); } export function isPlanForType( plan: PaymentPlan, subscriptionType: SubscriptionType, ): boolean { return subscriptionType === "voice" ? isVoicePackagePlan(plan) : isVipPlan(plan); } function currencySymbol(currency: string): string { const normalized = currency.toUpperCase(); if (normalized === "CNY") return "¥"; if (normalized === "USD") return "$"; return `${currency} `; } function formatAmount(amountCents: number | null): string | null { if (amountCents === null) return null; if (!Number.isFinite(amountCents)) return null; return (amountCents / 100).toFixed(2).replace(/\.?0+$/, ""); } function formatOfferAmount(amountCents: number | null): string { return (formatAmount(amountCents) ?? "").replace(".", ","); } function formatOfferCurrency(currency: string): string { const normalized = currency.toUpperCase(); if (normalized === "USD") return "usd"; return currency.toLowerCase(); } function formatCoinCurrency(currency: string): string { const normalized = currency.toUpperCase(); if (normalized === "USD") return "US$"; if (normalized === "CNY") return "¥"; return `${currency} `; } function vipOfferTitle(plan: PaymentPlan): string { const key = `${plan.planId} ${plan.orderType} ${plan.planName}`.toLowerCase(); if (key.includes("year")) return "Annual"; if (key.includes("quarter")) return "Quarterly"; if (key.includes("month")) return "Monthly"; if (plan.vipDays !== null && plan.vipDays >= 300) return "Annual"; if (plan.vipDays !== null && plan.vipDays >= 80) return "Quarterly"; return plan.planName; } function planCaption( plan: PaymentPlan, subscriptionType: SubscriptionType, ): string { if (subscriptionType === "voice") { return plan.dolAmount === null ? "Voice package" : `${plan.dolAmount} voice messages`; } if (plan.dailyPriceCents !== null) { const dailyPrice = formatAmount(plan.dailyPriceCents); return dailyPrice === null ? "Lifetime" : `${currencySymbol(plan.currency)}${dailyPrice}/day`; } if (plan.vipDays === null) return "Lifetime"; const fallbackDailyPrice = plan.amountCents / Math.max(plan.vipDays, 1); return `${currencySymbol(plan.currency)}${formatAmount(fallbackDailyPrice)}/day`; } export function toPlanView( plan: PaymentPlan, subscriptionType: SubscriptionType, ): SubscriptionPlanView { return { id: plan.planId, name: plan.planName, price: formatAmount(plan.amountCents) ?? "", originalPrice: formatAmount(plan.originalAmountCents), perDay: planCaption(plan, subscriptionType), currencySymbol: currencySymbol(plan.currency), }; } export function toVipOfferPlanView(plan: PaymentPlan): VipOfferPlanView { return { id: plan.planId, title: vipOfferTitle(plan), price: formatOfferAmount(plan.amountCents), currency: formatOfferCurrency(plan.currency), originalPrice: formatOfferAmount(plan.originalAmountCents), }; } export function toCoinsOfferPlanView(plan: PaymentPlan): CoinsOfferPlanView { return { id: plan.planId, coins: plan.dolAmount ?? 0, price: formatOfferAmount(plan.amountCents), currency: formatCoinCurrency(plan.currency), }; }