const {
  outstandingForFee,
  outstandingForInvoice,
  statusForPaid,
} = require('../src/lib/outstanding');

describe('outstandingForFee', () => {
  it('defaults missing fee fields to zero', () => {
    expect(outstandingForFee({})).toEqual({ total_due: 0, outstanding: 0, paid: 0 });
  });

  it('applies a discount when no fine is present', () => {
    expect(outstandingForFee({ amount: 100, discount_amount: 15, paid_amount: 20 })).toEqual({
      total_due: 85,
      outstanding: 65,
      paid: 20,
    });
  });

  it('applies a fine when no discount is present', () => {
    expect(outstandingForFee({ amount: 100, fine_amount: 10, paid_amount: 20 })).toEqual({
      total_due: 110,
      outstanding: 90,
      paid: 20,
    });
  });

  it('applies both fine and discount', () => {
    expect(outstandingForFee({ amount: 100, fine_amount: 10, discount_amount: 15, paid_amount: 20 })).toEqual({
      total_due: 95,
      outstanding: 75,
      paid: 20,
    });
  });

  it('clamps negative outstanding to zero when overpaid', () => {
    expect(outstandingForFee({ amount: 100, paid_amount: 125 })).toEqual({
      total_due: 100,
      outstanding: 0,
      paid: 125,
    });
  });
});

describe('statusForPaid', () => {
  it('returns pending with no payment and partial below the due amount', () => {
    expect(statusForPaid(100, 0)).toBe('pending');
    expect(statusForPaid(100, 40)).toBe('partial');
  });

  it('returns paid when the due amount is fully covered', () => {
    expect(statusForPaid(100, 100)).toBe('paid');
  });
});

describe('outstandingForInvoice', () => {
  it('subtracts discount and paid amount from the invoice total', () => {
    expect(outstandingForInvoice({ total: 250, discount_amount: 30, paid_amount: 100 })).toEqual({
      net_due: 220,
      outstanding: 120,
      paid: 100,
    });
  });
});
