import {
  bifurcatePricingRow,
  bifurcatePricingRowBoth,
  SELL_PRICE_FIELDS,
  FLOOR_PRICE_FIELDS,
} from './pricing-bifurcation.helper';
import type { TaxSlabSnapshotInput } from './tax-bifurcation.helper';

const VAT_5: TaxSlabSnapshotInput = {
  slab_id: 'slab-vat',
  slab_name: 'VAT 5%',
  total_rate: 5,
  components: [{ name: 'VAT', rate: 5 }],
};

describe('SELL_PRICE_FIELDS / FLOOR_PRICE_FIELDS', () => {
  it('covers default + 4 seasons per side (5 cells each, matching migration 1781100000000)', () => {
    expect(SELL_PRICE_FIELDS).toEqual([
      'default_price',
      'season_1_price',
      'season_2_price',
      'season_3_price',
      'season_4_price',
    ]);
    expect(FLOOR_PRICE_FIELDS).toEqual([
      'floor_default_price',
      'floor_season_1_price',
      'floor_season_2_price',
      'floor_season_3_price',
      'floor_season_4_price',
    ]);
  });
});

describe('bifurcatePricingRow (sell side)', () => {
  it('emits base + tax for each present sell cell, null for the rest', () => {
    const out = bifurcatePricingRow(
      { default_price: 105, season_1_price: 210 },
      VAT_5,
      1,
      'sell',
    );
    expect(out.default_base_price).toBe(100);
    expect(out.default_tax_amount).toBe(5);
    expect(out.season_1_base_price).toBe(200);
    expect(out.season_1_tax_amount).toBe(10);
    // Untouched cells get null on both derived columns so a previously
    // saved value can't linger as a stale bifurcation.
    expect(out.season_2_base_price).toBeNull();
    expect(out.season_2_tax_amount).toBeNull();
    expect(out.season_3_base_price).toBeNull();
    expect(out.season_4_base_price).toBeNull();
  });

  it('null / empty / non-numeric inclusive cells produce null on both derived columns', () => {
    const out = bifurcatePricingRow(
      { default_price: null, season_1_price: '', season_2_price: 'oops' },
      VAT_5,
      1,
      'sell',
    );
    expect(out.default_base_price).toBeNull();
    expect(out.default_tax_amount).toBeNull();
    expect(out.season_1_base_price).toBeNull();
    expect(out.season_1_tax_amount).toBeNull();
    expect(out.season_2_base_price).toBeNull();
    expect(out.season_2_tax_amount).toBeNull();
  });

  it('slab=null → base = inclusive, tax = 0 (exempt destinations)', () => {
    const out = bifurcatePricingRow({ default_price: 100 }, null, 1, 'sell');
    expect(out.default_base_price).toBe(100);
    expect(out.default_tax_amount).toBe(0);
  });
});

describe('bifurcatePricingRow (floor side)', () => {
  it('floor_-prefixed cells get floor_*_base_price + floor_*_tax_amount', () => {
    const out = bifurcatePricingRow(
      { floor_default_price: 84, floor_season_2_price: 168 },
      VAT_5,
      1,
      'floor',
    );
    expect(out.floor_default_base_price).toBe(80);
    expect(out.floor_default_tax_amount).toBe(4);
    expect(out.floor_season_2_base_price).toBe(160);
    expect(out.floor_season_2_tax_amount).toBe(8);
  });

  it('does NOT touch the sell-side derived columns', () => {
    const out = bifurcatePricingRow({ floor_default_price: 84 }, VAT_5, 1, 'floor');
    expect(out.default_base_price).toBeUndefined();
    expect(out.default_tax_amount).toBeUndefined();
  });
});

describe('bifurcatePricingRowBoth', () => {
  it('combines sell + floor in a single call', () => {
    const out = bifurcatePricingRowBoth(
      { default_price: 105, floor_default_price: 84 },
      VAT_5,
      1,
    );
    expect(out.default_base_price).toBe(100);
    expect(out.floor_default_base_price).toBe(80);
    expect(out.default_tax_amount).toBe(5);
    expect(out.floor_default_tax_amount).toBe(4);
  });

  it('honours the rounding step (INR 5-step)', () => {
    // 1000 inclusive at GST 18% → base 845 (nearest 5), tax 155
    const out = bifurcatePricingRowBoth(
      { default_price: 1000 },
      {
        slab_id: 'gst',
        slab_name: 'GST 18%',
        total_rate: 18,
        components: [
          { name: 'CGST', rate: 9 },
          { name: 'SGST', rate: 9 },
        ],
      },
      5,
    );
    expect(out.default_base_price).toBe(845);
    expect(out.default_tax_amount).toBe(155);
  });
});
