import type { PayChannel, PaymentPlan } from "@/data/dto/payment";

import type { CoinsOfferPlanView } from "./components/subscription-coins-offer-section";
import type { VipOfferPlanView } from "./components/subscription-vip-offer-section";

export type SubscriptionType = "vip" | "topup";

export function getDefaultPayChannelForCountryCode(
  countryCode: string | null | undefined,
): PayChannel {
  return countryCode?.trim().toUpperCase() === "PH" ? "ezpay" : "stripe";
}

export function isVipPlan(plan: PaymentPlan): boolean {
  return plan.vipDays !== null;
}

export function isCreditPlan(plan: PaymentPlan): boolean {
  return plan.dolAmount !== null;
}

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;
}

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),
  };
}

export function toVipOfferPlanViews(
  plans: readonly PaymentPlan[],
): VipOfferPlanView[] {
  return plans.filter(isVipPlan).slice(0, 3).map(toVipOfferPlanView);
}

export function toCoinsOfferPlanViews(
  plans: readonly PaymentPlan[],
): CoinsOfferPlanView[] {
  return plans.filter(isCreditPlan).map(toCoinsOfferPlanView);
}

export function findSelectedSubscriptionPlan(input: {
  canSubscribeVip: boolean;
  selectedPlanId: string;
  vipPlans: readonly VipOfferPlanView[];
  coinPlans: readonly CoinsOfferPlanView[];
}): VipOfferPlanView | CoinsOfferPlanView | null {
  const plans = input.canSubscribeVip
    ? [...input.vipPlans, ...input.coinPlans]
    : input.coinPlans;
  return plans.find((plan) => plan.id === input.selectedPlanId) ?? null;
}

export function getDefaultSubscriptionPlanId(input: {
  canSubscribeVip: boolean;
  selectedPlanId: string;
  status: string;
  isLoadingPlans: boolean;
  selectedPlan: VipOfferPlanView | CoinsOfferPlanView | null;
  vipPlans: readonly VipOfferPlanView[];
  coinPlans: readonly CoinsOfferPlanView[];
}): string | null {
  if (input.canSubscribeVip) {
    const firstVipPlanId = input.vipPlans[0]?.id ?? "";
    const hasSelectedVipPlan = input.vipPlans.some(
      (plan) => plan.id === input.selectedPlanId,
    );
    const hasSelectedCoinsPlan = input.coinPlans.some(
      (plan) => plan.id === input.selectedPlanId,
    );
    const canSelectPlan =
      firstVipPlanId.length > 0 &&
      (input.status === "ready" ||
        input.status === "paid" ||
        input.status === "failed");

    if (!canSelectPlan || hasSelectedVipPlan || hasSelectedCoinsPlan) {
      return null;
    }
    return firstVipPlanId;
  }

  if (input.isLoadingPlans || input.coinPlans.length === 0) return null;
  if (input.selectedPlan !== null) return null;
  return input.coinPlans[0]?.id ?? null;
}
