import {
  DEFAULT_TAX_RATE,
  computeTax,
  computeTotal,
  resolveTaxRate,
  surchargeApplies,
  taxableBase,
} from "./premium";

/**
 * The reference case is policy 7006785 (MULT, semestral, GMX, two payments) as
 * it stands in the Access books — the screen Jorge sent. Both of its money
 * rows are asserted, because the second one is the case that proves the
 * surcharge belongs in the taxable base and that a zero policy fee is a real
 * value rather than a missing one.
 */
describe("premium arithmetic", () => {
  it("matches the first payment of policy 7006785", () => {
    const parts = { netPremium: 610.86, surcharge: 8.55, policyFee: 31.0 };
    expect(taxableBase(parts)).toBe(650.41);
    expect(computeTax(parts, 0.08)).toBe(52.03);
    expect(computeTotal(parts, 0.08)).toBe(702.44);
  });

  it("matches the second payment of policy 7006785", () => {
    const parts = { netPremium: 589.71, surcharge: 8.26, policyFee: 0 };
    expect(computeTax(parts, 0.08)).toBe(47.84);
    expect(computeTotal(parts, 0.08)).toBe(645.81);
  });

  it("excluding the surcharge does NOT reconcile", () => {
    // Guards the one decision in this module that is easy to get wrong: the
    // spoken-language version of the rule ("prima neta + derecho * 8%") gives
    // 51.35, and the printed policy says 52.03.
    const withoutSurcharge = { netPremium: 610.86, surcharge: 0, policyFee: 31.0 };
    expect(computeTax(withoutSurcharge, 0.08)).not.toBe(52.03);
  });

  it("treats blank and null money as zero, not NaN", () => {
    expect(taxableBase({ netPremium: "610.86", surcharge: null, policyFee: "" })).toBe(
      610.86,
    );
    expect(computeTax({ netPremium: undefined, surcharge: null, policyFee: null }, 0.08))
      .toBe(0);
  });

  it("rounds half-up to cents", () => {
    // 100.06 * 0.08 = 8.0048 -> 8.00; 100.13 * 0.08 = 8.0104 -> 8.01.
    expect(computeTax({ netPremium: 100.06, surcharge: 0, policyFee: 0 }, 0.08)).toBe(8);
    expect(computeTax({ netPremium: 100.13, surcharge: 0, policyFee: 0 }, 0.08)).toBe(8.01);
  });

  describe("surchargeApplies", () => {
    it("is false for the two single-payment frequencies", () => {
      expect(surchargeApplies("ANNUAL")).toBe(false);
      expect(surchargeApplies("SINGLE")).toBe(false);
    });
    it("is true for every split frequency", () => {
      expect(surchargeApplies("SEMIANNUAL")).toBe(true);
      expect(surchargeApplies("QUARTERLY")).toBe(true);
      expect(surchargeApplies("MONTHLY")).toBe(true);
    });
    it("allows it when the frequency is unknown", () => {
      // Every migrated policy is null here — the original ETL dropped FORMA
      // PAGO — and those rows DO carry recargo figures in the legacy data.
      expect(surchargeApplies(null)).toBe(true);
      expect(surchargeApplies(undefined)).toBe(true);
    });
  });

  describe("resolveTaxRate", () => {
    it("prefers the rate the policy was issued at", () => {
      expect(resolveTaxRate(0.16, 0.08)).toBe(0.16);
    });
    it("falls back to the line of business", () => {
      expect(resolveTaxRate(null, 0.08)).toBe(0.08);
    });
    it("falls back to the default when nothing is configured", () => {
      expect(resolveTaxRate(null, null)).toBe(DEFAULT_TAX_RATE);
      expect(resolveTaxRate(undefined, "")).toBe(DEFAULT_TAX_RATE);
    });
    it("accepts a zero rate as a real choice, not as absent", () => {
      // An exempt line of business must read 0, not silently fall through to 8%.
      expect(resolveTaxRate(null, 0)).toBe(0);
    });
    it("accepts Prisma's decimal strings", () => {
      expect(resolveTaxRate(null, "0.0800")).toBe(0.08);
    });
  });
});
