/**
 * RED PHASE - Pricing Calculation Tests
 *
 * These tests validate the pricing calculation utilities:
 * - Monthly subscription cost calculation
 * - Yearly discount application (7% = 0.93 multiplier)
 * - Currency exchange rate conversion
 * - Setup fee logic by tier
 * - Total cost calculation
 * - Edge case handling
 *
 * Expected: ALL TESTS FAIL initially (RED phase)
 */

import { calculateSubscriptionCost, getSetupFee } from "@/lib/stripe";

describe("Pricing Calculations", () => {
  const mockExchangeRates = {
    gbp: 1,
    usd: 1.27,
    eur: 1.17,
    sar: 4.76,
    aed: 4.66,
    qar: 4.62,
    kwd: 0.39,
    bhd: 0.48,
    omr: 0.49,
  };

  describe("Subscription Cost Calculation", () => {
    test("TEST #12: Should calculate monthly subscription cost without currency conversion", () => {
      const basePrice = 99; // £99 base price
      const result = calculateSubscriptionCost(
        basePrice,
        "monthly",
        "gbp",
        mockExchangeRates,
      );

      // Monthly: no discount, GBP rate = 1
      expect(result).toBe(99);
    });

    test("TEST #13: Should calculate yearly subscription cost with 7% discount (0.93 multiplier)", () => {
      const basePrice = 99; // £99 base price
      const result = calculateSubscriptionCost(
        basePrice,
        "yearly",
        "gbp",
        mockExchangeRates,
      );

      // Yearly: 7% discount = 0.93 multiplier
      // £99 * 0.93 = £92.07
      expect(result).toBe(92.07);
    });

    test("TEST #14: Should apply currency exchange rates correctly", () => {
      const basePrice = 100; // £100 base price

      // USD conversion
      const usdResult = calculateSubscriptionCost(
        basePrice,
        "monthly",
        "usd",
        mockExchangeRates,
      );
      expect(usdResult).toBe(127); // £100 * 1.27

      // EUR conversion
      const eurResult = calculateSubscriptionCost(
        basePrice,
        "monthly",
        "eur",
        mockExchangeRates,
      );
      expect(eurResult).toBe(117); // £100 * 1.17

      // SAR conversion
      const sarResult = calculateSubscriptionCost(
        basePrice,
        "monthly",
        "sar",
        mockExchangeRates,
      );
      expect(sarResult).toBe(476); // £100 * 4.76
    });

    test("TEST #15: Should handle missing exchange rates with fallback to 1", () => {
      const basePrice = 100;
      const result = calculateSubscriptionCost(
        basePrice,
        "monthly",
        "unknown_currency", // Not in exchange rates
        mockExchangeRates,
      );

      // Missing rate should default to 1 (same as base price)
      expect(result).toBe(100);
    });

    test("TEST #18: Should calculate yearly cost with both discount and currency conversion", () => {
      const basePrice = 199; // £199 base price

      // Yearly USD: £199 * 0.93 * 1.27
      const yearlyUSD = calculateSubscriptionCost(
        basePrice,
        "yearly",
        "usd",
        mockExchangeRates,
      );
      expect(yearlyUSD).toBeCloseTo(235.05, 0); // £185.07 * 1.27

      // Yearly EUR: £199 * 0.93 * 1.17
      const yearlyEUR = calculateSubscriptionCost(
        basePrice,
        "yearly",
        "eur",
        mockExchangeRates,
      );
      expect(yearlyEUR).toBe(216.53); // £185.07 * 1.17
    });
  });

  describe("Setup Fee Calculation", () => {
    test("TEST #16: Should get setup fee for each tier (tier1-4 = £199, tier5 = £299)", () => {
      // Tier 1-4 should have £199 setup fee
      expect(getSetupFee("tier1")).toBe(199);
      expect(getSetupFee("tier2")).toBe(199);
      expect(getSetupFee("tier3")).toBe(199);
      expect(getSetupFee("tier4")).toBe(199);

      // Tier 5 should have £299 setup fee
      expect(getSetupFee("tier5")).toBe(299);
    });

    test("TEST #17: Should return default setup fee (£199) for unknown tier", () => {
      // Unknown tier should default to £199
      expect(getSetupFee("tier_unknown")).toBe(199);
      expect(getSetupFee("")).toBe(199);
      expect(getSetupFee("invalid")).toBe(199);
    });
  });

  describe("Edge Cases", () => {
    test("TEST #19: Should handle edge cases (zero prices, negative rates, missing data)", () => {
      // Zero base price
      const zeroCost = calculateSubscriptionCost(
        0,
        "monthly",
        "gbp",
        mockExchangeRates,
      );
      expect(zeroCost).toBe(0);

      // Very small price with yearly discount
      const smallCost = calculateSubscriptionCost(
        0.01,
        "yearly",
        "gbp",
        mockExchangeRates,
      );
      expect(smallCost).toBe(0.01); // 0.01 * 0.93 = 0.0093 → rounded to 0.01

      // Large price with currency conversion
      const largeCost = calculateSubscriptionCost(
        10000,
        "yearly",
        "sar",
        mockExchangeRates,
      );
      // £10,000 * 0.93 * 4.76 = 44,268
      expect(largeCost).toBe(44268);

      // Empty exchange rates object
      const emptyRates = calculateSubscriptionCost(
        100,
        "monthly",
        "usd",
        {}, // Empty rates
      );
      expect(emptyRates).toBe(100); // Fallback to rate = 1

      // Null/undefined handling - should use fallback
      const undefinedRate = calculateSubscriptionCost(
        100,
        "monthly",
        "unknown",
        { unknown: undefined as any },
      );
      expect(undefinedRate).toBe(100); // Fallback to 1
    });

    test("TEST #20: Should round currency conversions to 2 decimal places", () => {
      const basePrice = 99.99;

      // Test rounding with yearly discount and currency conversion
      const result = calculateSubscriptionCost(
        basePrice,
        "yearly",
        "usd",
        { usd: 1.2734 }, // Exchange rate with many decimals
      );

      // £99.99 * 0.93 * 1.2734 ≈ 118.38 (rounding may vary)
      expect(result).toBeCloseTo(118.38, 0);

      // Verify exactly 2 decimal places
      expect(result.toString().split(".")[1]?.length || 0).toBeLessThanOrEqual(
        2,
      );
    });
  });

  describe("Integration Scenarios", () => {
    test("TEST #21: Should calculate realistic pricing table scenarios", () => {
      // Starter monthly GBP (no discount, no conversion)
      const starterMonthly = calculateSubscriptionCost(
        99,
        "monthly",
        "gbp",
        mockExchangeRates,
      );
      expect(starterMonthly).toBe(99);

      // Starter yearly GBP (7% discount)
      const starterYearly = calculateSubscriptionCost(
        99,
        "yearly",
        "gbp",
        mockExchangeRates,
      );
      expect(starterYearly).toBe(92.07); // 99 * 0.93

      // Enterprise monthly USD (conversion only)
      const enterpriseMonthlyUSD = calculateSubscriptionCost(
        499,
        "monthly",
        "usd",
        mockExchangeRates,
      );
      expect(enterpriseMonthlyUSD).toBe(633.73); // 499 * 1.27

      // Enterprise yearly SAR (discount + conversion)
      const enterpriseYearlySAR = calculateSubscriptionCost(
        499,
        "yearly",
        "sar",
        mockExchangeRates,
      );
      // Rounding may differ with exchange rate precision
      expect(enterpriseYearlySAR).toBeCloseTo(2209, -1); // ~499 * 0.93 * 4.76
    });

    test("TEST #22: Should calculate setup fees consistently across all scenarios", () => {
      // Tier 1 starter setup
      const tier1Setup = getSetupFee("tier1");
      expect(tier1Setup).toBe(199);

      // Tier 5 enterprise setup
      const tier5Setup = getSetupFee("tier5");
      expect(tier5Setup).toBe(299);

      // Total first payment for tier1 monthly GBP
      // Subscription: £99/month, Setup: £199
      const tier1Monthly = calculateSubscriptionCost(
        99,
        "monthly",
        "gbp",
        mockExchangeRates,
      );
      const tier1TotalFirst = tier1Monthly + tier1Setup;
      expect(tier1TotalFirst).toBe(298); // 99 + 199

      // Total first payment for tier5 yearly SAR
      // Subscription: £999 yearly with 7% discount, Setup: £299
      const tier5YearlySAR = calculateSubscriptionCost(
        999,
        "yearly",
        "sar",
        mockExchangeRates,
      );
      const tier5SetupFee = getSetupFee("tier5");
      const tier5TotalFirstSAR =
        tier5YearlySAR + tier5SetupFee * mockExchangeRates.sar;
      // Rounding may differ with exchange rate precision
      expect(tier5TotalFirstSAR).toBeCloseTo(5850, -2); // ~(999 * 0.93 * 4.76) + (299 * 4.76)
    });
  });
});
