import {
  PaymentPlan,
  PaymentPlanSchema,
  type PaymentPlansResponse,
} from "@/data/schemas/payment";

import type { PaymentState } from "../payment-state";
import { resetOrderState } from "./order";

export function defaultAutoRenewForPlan(
  planId: string,
  plans: readonly PaymentPlan[] = [],
): boolean {
  const plan = plans.find((item) => item.planId === planId);
  if (plan?.orderType === "tip") return false;
  if (plan?.dolAmount !== null && plan?.dolAmount !== undefined) return false;
  return (
    !planId.includes("lifetime") &&
    !planId.startsWith("dol_") &&
    !planId.startsWith("points_") &&
    !planId.startsWith("credit_")
  );
}

export function getDefaultPlanId(plans: readonly PaymentPlan[]): string {
  return (
    plans.find((plan) => plan.planId === "vip_monthly")?.planId ??
    plans.find((plan) => plan.orderType.startsWith("vip_"))?.planId ??
    plans[0]?.planId ??
    ""
  );
}

export function hydratePlansState(
  plans: readonly PaymentPlan[],
  selectedPlanId: string,
): Pick<
  PaymentState,
  "plans" | "selectedPlanId" | "autoRenew" | "errorMessage"
> {
  const nextSelectedPlanId = selectedPlanId || getDefaultPlanId(plans);
  return {
    plans,
    selectedPlanId: nextSelectedPlanId,
    autoRenew: defaultAutoRenewForPlan(nextSelectedPlanId, plans),
    errorMessage: null,
  };
}

export function hydratePlansResponseState(
  response: PaymentPlansResponse,
  selectedPlanId: string,
): Pick<
  PaymentState,
  "plans" | "isFirstRecharge" | "commercialOffer" | "selectedPlanId" | "autoRenew" | "errorMessage"
> {
  const plans = normalizeFirstRechargePlans(
    response.plans,
    response.isFirstRecharge,
  );
  return {
    ...hydratePlansState(plans, selectedPlanId),
    isFirstRecharge: response.isFirstRecharge,
    commercialOffer: response.commercialOffer,
  };
}

export function refreshPlansState(
  plans: readonly PaymentPlan[],
  selectedPlanId: string,
): Pick<
  PaymentState,
  "plans" | "selectedPlanId" | "autoRenew" | "errorMessage"
> {
  const nextSelectedPlanId = plans.some(
    (plan) => plan.planId === selectedPlanId,
  )
    ? selectedPlanId
    : getDefaultPlanId(plans);
  return {
    plans,
    selectedPlanId: nextSelectedPlanId,
    autoRenew: defaultAutoRenewForPlan(nextSelectedPlanId, plans),
    errorMessage: null,
  };
}

export function refreshPlansResponseState(
  response: PaymentPlansResponse,
  selectedPlanId: string,
): Pick<
  PaymentState,
  "plans" | "isFirstRecharge" | "commercialOffer" | "selectedPlanId" | "autoRenew" | "errorMessage"
> {
  const plans = normalizeFirstRechargePlans(
    response.plans,
    response.isFirstRecharge,
  );
  return {
    ...refreshPlansState(plans, selectedPlanId),
    isFirstRecharge: response.isFirstRecharge,
    commercialOffer: response.commercialOffer,
  };
}

export function normalizeFirstRechargePlans(
  plans: readonly PaymentPlan[],
  isFirstRecharge: boolean,
): readonly PaymentPlan[] {
  if (isFirstRecharge) return [...plans];
  return plans.map(consumeFirstRechargePlan);
}

export function consumeFirstRechargePlan(plan: PaymentPlan): PaymentPlan {
  if (!plan.isFirstRechargeOffer) {
    return PaymentPlanSchema.parse({
      ...plan,
      isFirstRechargeOffer: false,
      firstRechargeDiscountPercent: null,
      promotionType: null,
    });
  }

  const originalAmountCents = plan.originalAmountCents;
  return PaymentPlanSchema.parse({
    ...plan,
    amountCents: originalAmountCents ?? plan.amountCents,
    originalAmountCents: originalAmountCents ?? plan.originalAmountCents,
    isFirstRechargeOffer: false,
    firstRechargeDiscountPercent: null,
    promotionType: null,
  });
}

export function consumeFirstRechargeState(
  context: PaymentState,
): Pick<
  PaymentState,
  | "plans"
  | "isFirstRecharge"
  | "commercialOffer"
  | "commercialOfferId"
  | "selectedPlanId"
  | "autoRenew"
  | "errorMessage"
> {
  const plans = context.plans.map(consumeFirstRechargePlan);
  return {
    ...refreshPlansState(plans, context.selectedPlanId),
    isFirstRecharge: false,
    commercialOffer: null,
    commercialOfferId: null,
  };
}

export function selectPlanState(
  planId: string,
  plans: readonly PaymentPlan[],
): Partial<PaymentState> {
  return {
    ...resetOrderState(),
    selectedPlanId: planId,
    autoRenew: defaultAutoRenewForPlan(planId, plans),
  };
}
