import { setupTestDb, cleanUpTestDb } from "../helpers/dbSetup.js";
import { calculateSaaSFee } from "../../src/utils/feeCalculator.js";
import db from "../../src/models/index.js";

describe("Fee Calculator (Unit Tests)", () => {
  beforeAll(async () => {
    await setupTestDb();
  });

  afterAll(async () => {
    await cleanUpTestDb();
  });

  describe("Deposit (Pay-in) Fees", () => {
    it("should calculate standard 0.5% fee on a deposit", async () => {
      const { fee, stampDuty } = await calculateSaaSFee("deposit", 1000);
      expect(fee).toBe(5);
      expect(stampDuty).toBe(0);
    });

    it("should respect the deposit fee cap of 100 NGN", async () => {
      const { fee, stampDuty } = await calculateSaaSFee("deposit", 50000);
      expect(fee).toBe(100);
      expect(stampDuty).toBe(0);
    });
  });

  describe("Payout (Pay-out) Fees & Stamp Duty", () => {
    it("should calculate standard flat fee of 20 NGN for payout", async () => {
      const { fee, stampDuty } = await calculateSaaSFee("payout", 5000);
      expect(fee).toBe(20);
      expect(stampDuty).toBe(0);
    });

    it("should add 50 NGN stamp duty for payout >= 10,000 NGN", async () => {
      const { fee, stampDuty } = await calculateSaaSFee("payout", 15000);
      expect(fee).toBe(20);
      expect(stampDuty).toBe(50);
    });
  });

  describe("Merchant Custom Fee Overrides", () => {
    let merchant;

    beforeAll(async () => {
      merchant = await db.Merchant.create({
        businessName: "Override Merchant",
        email: "override@merchant.com",
        password: "dummy",
        customDepositFeePercent: 1.0, // 1%
        customDepositFeeCap: 250, // 250 NGN cap
        customPayoutFeeFlat: 15, // 15 NGN flat payout
      });
    });

    it("should use merchant custom deposit fee percent and cap", async () => {
      // 1% of 10,000 is 100
      const { fee: fee1 } = await calculateSaaSFee("deposit", 10000, merchant.id);
      expect(fee1).toBe(100);

      // 1% of 50,000 is 500, but cap is 250
      const { fee: fee2 } = await calculateSaaSFee("deposit", 50000, merchant.id);
      expect(fee2).toBe(250);
    });

    it("should use merchant custom payout flat fee and apply stamp duty threshold", async () => {
      // Below 10k threshold
      const { fee: fee1, stampDuty: stamp1 } = await calculateSaaSFee("payout", 5000, merchant.id);
      expect(fee1).toBe(15);
      expect(stamp1).toBe(0);

      // Above 10k threshold
      const { fee: fee2, stampDuty: stamp2 } = await calculateSaaSFee("payout", 12000, merchant.id);
      expect(fee2).toBe(15);
      expect(stamp2).toBe(50);
    });
  });
});
