import { describe, expect, it } from "vitest";

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

import {
  findSelectedSubscriptionPlan,
  getDefaultSubscriptionPlanId,
  getFirstRechargeOfferView,
  toCoinsOfferPlanViews,
  toVipOfferPlanViews,
} from "../subscription-screen.helpers";

function makePlan(overrides: Partial<PaymentPlanInput>): PaymentPlan {
  return PaymentPlanSchema.parse({
    planId: "plan",
    planName: "Plan",
    orderType: "vip_monthly",
    vipDays: 30,
    dolAmount: null,
    creditBalance: 0,
    amountCents: 1990,
    originalAmountCents: null,
    dailyPriceCents: null,
    currency: "USD",
    ...overrides,
  });
}

describe("subscription screen helpers", () => {
  it("maps at most three VIP plans and all coin plans", () => {
    const plans = [
      makePlan({ planId: "vip_monthly", planName: "Monthly" }),
      makePlan({ planId: "vip_quarterly", planName: "Quarterly", vipDays: 90 }),
      makePlan({ planId: "vip_annual", planName: "Annual", vipDays: 365 }),
      makePlan({ planId: "vip_extra", planName: "Extra", vipDays: 30 }),
      makePlan({
        planId: "coin_1000",
        planName: "Coins",
        orderType: "coins_1000",
        vipDays: null,
        dolAmount: 1000,
        amountCents: 990,
      }),
    ];

    expect(toVipOfferPlanViews(plans).map((plan) => plan.id)).toEqual([
      "vip_monthly",
      "vip_quarterly",
      "vip_annual",
    ]);
    expect(toCoinsOfferPlanViews(plans)).toMatchObject([
      {
        id: "coin_1000",
        coins: 1000,
        price: "9.9",
        currency: "US$",
      },
    ]);
  });

  it("finds selected coin plans in VIP mode", () => {
    const selected = findSelectedSubscriptionPlan({
      canSubscribeVip: true,
      selectedPlanId: "coin_1000",
      vipPlans: [
        {
          id: "vip_monthly",
          title: "Monthly",
          price: "19.90",
          currency: "usd",
          originalPrice: "",
        },
      ],
      coinPlans: [
        { id: "coin_1000", coins: 1000, price: "9.90", currency: "US$" },
      ],
    });

    expect(selected?.id).toBe("coin_1000");
  });

  it("formats plan amounts from cents with a dot decimal separator", () => {
    expect(
      toVipOfferPlanViews([
        makePlan({
          planId: "vip_test",
          amountCents: 7790,
        }),
      ]),
    ).toMatchObject([
      {
        id: "vip_test",
        price: "77.9",
      },
    ]);
  });

  it("maps first recharge offer fields to plan views", () => {
    const vipViews = toVipOfferPlanViews([
      makePlan({
        planId: "vip_monthly",
        amountCents: 995,
        originalAmountCents: 1990,
        isFirstRechargeOffer: true,
        firstRechargeDiscountPercent: 50,
        promotionType: "first_recharge_half_price",
      }),
    ]);
    const coinViews = toCoinsOfferPlanViews([
      makePlan({
        planId: "coin_1000",
        orderType: "coins_1000",
        vipDays: null,
        dolAmount: 1000,
        amountCents: 495,
        originalAmountCents: 990,
        isFirstRechargeOffer: true,
        firstRechargeDiscountPercent: 50,
        promotionType: "first_recharge_half_price",
      }),
    ]);

    expect(vipViews[0]).toMatchObject({
      price: "9.95",
      originalPrice: "19.9",
      isFirstRechargeOffer: true,
      firstRechargeDiscountPercent: 50,
    });
    expect(coinViews[0]).toMatchObject({
      price: "4.95",
      originalPrice: "9.9",
      isFirstRechargeOffer: true,
      firstRechargeDiscountPercent: 50,
    });
    expect(
      getFirstRechargeOfferView({
        isFirstRecharge: true,
        subscriptionType: "vip",
        vipPlans: vipViews,
        coinPlans: coinViews,
      }),
    ).toMatchObject({
      badgeText: "50% OFF",
      title: "First Recharge Offer",
      renewalNotice:
        "First month 50% off. Renews at the regular price from the second month.",
    });
    expect(
      getFirstRechargeOfferView({
        isFirstRecharge: true,
        subscriptionType: "topup",
        vipPlans: vipViews,
        coinPlans: coinViews,
      }),
    ).toMatchObject({
      badgeText: "50% OFF",
      title: "First Recharge Offer",
      renewalNotice: null,
    });
    expect(
      getFirstRechargeOfferView({
        isFirstRecharge: false,
        subscriptionType: "vip",
        vipPlans: vipViews,
        coinPlans: coinViews,
      }),
    ).toBeNull();
  });

  it("maps the backend most popular flag to VIP and coin views", () => {
    const popularVip = toVipOfferPlanViews([
      makePlan({ planId: "vip_monthly", mostPopular: true }),
    ]);
    const popularCoins = toCoinsOfferPlanViews([
      makePlan({
        planId: "coin_1000",
        orderType: "coins_1000",
        vipDays: null,
        dolAmount: 1000,
        mostPopular: true,
      }),
    ]);

    expect(popularVip[0]?.mostPopular).toBe(true);
    expect(popularCoins[0]?.mostPopular).toBe(true);
  });

  it("maps normal VIP original price outside first recharge activity", () => {
    expect(
      toVipOfferPlanViews([
        makePlan({
          planId: "vip_monthly",
          amountCents: 1990,
          originalAmountCents: 2499,
          isFirstRechargeOffer: false,
        }),
      ]),
    ).toMatchObject([
      {
        id: "vip_monthly",
        price: "19.9",
        originalPrice: "24.99",
        isFirstRechargeOffer: false,
      },
    ]);
  });

  it("selects the first VIP plan by default when VIP can be purchased", () => {
    expect(
      getDefaultSubscriptionPlanId({
        canSubscribeVip: true,
        selectedPlanId: "",
        status: "ready",
        isLoadingPlans: false,
        selectedPlan: null,
        vipPlans: [
          {
            id: "vip_monthly",
            title: "Monthly",
            price: "19.90",
            currency: "usd",
            originalPrice: "",
          },
        ],
        coinPlans: [],
      }),
    ).toBe("vip_monthly");
  });

  it("selects the first coin plan by default in top-up-only mode", () => {
    expect(
      getDefaultSubscriptionPlanId({
        canSubscribeVip: false,
        selectedPlanId: "",
        status: "ready",
        isLoadingPlans: false,
        selectedPlan: null,
        vipPlans: [],
        coinPlans: [
          {
            id: "coin_1000",
            coins: 1000,
            price: "9.9",
            currency: "US$",
          },
        ],
      }),
    ).toBe("coin_1000");
  });

  it("does not override an existing selected plan", () => {
    expect(
      getDefaultSubscriptionPlanId({
        canSubscribeVip: false,
        selectedPlanId: "coin_1000",
        status: "ready",
        isLoadingPlans: false,
        selectedPlan: {
          id: "coin_1000",
          coins: 1000,
          price: "9.9",
          currency: "US$",
        },
        vipPlans: [],
        coinPlans: [
          {
            id: "coin_1000",
            coins: 1000,
            price: "9.9",
            currency: "US$",
          },
        ],
      }),
    ).toBeNull();
  });

});
