import { TaxSnapshotService } from './tax-snapshot.service';

/**
 * Focused unit tests for the pure math in TaxSnapshotService —
 * `sumRates` and `computeAmount`. Both are side-effect-free (no repo,
 * no CLS), so the service is instantiated with the DB/CLS deps stubbed
 * out; only these two methods are exercised.
 *
 * Core invariant under test: line subtotals are tax-INCLUSIVE, so
 * `computeAmount` must EXTRACT the embedded tax, never add it on top.
 */
describe('TaxSnapshotService (tax math)', () => {
  let service: TaxSnapshotService;

  // GST 18% split into CGST 9 + SGST 9.
  const GST_18 = { 'gst-type': { 'cgst-comp': 9, 'sgst-comp': 9 } };
  // VAT 5% single component.
  const VAT_5 = { 'vat-type': { 'vat-comp': 5 } };
  // Two tax types on one line: VAT 5% + Tourism 7% → 12% total.
  const MIXED_12 = {
    'vat-type': { 'vat-comp': 5 },
    'tourism-type': { 'tourism-comp': 7 },
  };

  beforeEach(() => {
    // slabRepo + cls are unused by the pure methods under test.
    service = new TaxSnapshotService(null as never, null as never);
  });

  describe('sumRates', () => {
    it('sums components across every tax type', () => {
      expect(service.sumRates(GST_18)).toBe(18);
      expect(service.sumRates(MIXED_12)).toBe(12);
    });

    it('returns 0 for null / empty breakdowns', () => {
      expect(service.sumRates(null)).toBe(0);
      expect(service.sumRates(undefined)).toBe(0);
      expect(service.sumRates({})).toBe(0);
    });
  });

  describe('computeAmount — extracts embedded tax from an inclusive subtotal', () => {
    it('118 inclusive @ 18% → 18.00 (base 100), NOT 21.24 on-top', () => {
      expect(service.computeAmount(118, GST_18)).toBe(18);
    });

    it('105 inclusive @ 5% → 5.00 (base 100)', () => {
      expect(service.computeAmount(105, VAT_5)).toBe(5);
    });

    it('112 inclusive @ 12% (mixed slabs) → 12.00 (base 100)', () => {
      expect(service.computeAmount(112, MIXED_12)).toBe(12);
    });

    it('base + extracted tax reconstructs the inclusive subtotal', () => {
      const subtotal = 236; // 200 base + 36 tax @ 18%
      const tax = service.computeAmount(subtotal, GST_18)!;
      expect(tax).toBe(36);
      expect(subtotal - tax).toBe(200);
    });

    it('rounds to two decimals', () => {
      // 100 inclusive @ 18% → 100 × 18 / 118 = 15.2542… → 15.25
      expect(service.computeAmount(100, GST_18)).toBe(15.25);
    });

    it('returns 0 when the total rate is 0 (exempt)', () => {
      expect(service.computeAmount(100, {})).toBe(0);
    });

    it('returns null when subtotal or breakdown is missing', () => {
      expect(service.computeAmount(null, GST_18)).toBeNull();
      expect(service.computeAmount(100, null)).toBeNull();
    });
  });
});
