import { AfectacionIva, calcularLineaFiscal, calcularSubtotalFiscal } from './calculo-iva';

describe('cálculo de IVA en el backend (NT 13)', () => {
  it('inmueble: IVA 5 % sobre el 30 % del precio (afectación 4)', () => {
    const l = calcularLineaFiscal({
      cantidad: 1,
      precio_unitario: 100_000_000,
      afectacion_iva: AfectacionIva.GRAVADO_PARCIAL,
      porcentaje_iva: 5,
      proporcion_iva: 30,
    });
    // divisor = 10000 + 5·30 = 10150
    expect(l.base_gravada).toBeCloseTo(29_556_650.25, 2);
    expect(l.liquidacion_iva).toBeCloseTo(1_477_832.51, 2);
    expect(l.base_gravada_exenta).toBeCloseTo(68_965_517.24, 2);
    expect(l.base_gravada + l.liquidacion_iva + l.base_gravada_exenta).toBeCloseTo(100_000_000, 2);

    const s = calcularSubtotalFiscal([l]);
    expect(s.subtotal_5 + s.subtotal_exento).toBeCloseTo(100_000_000, 1);
    expect(s.liquidacion_iva_5).toBe(1_477_832.51);
    expect(s.total_general_operacion).toBe(100_000_000);
    expect(s.total_iva).toBe(1_477_832.51);
  });

  it('gravado 10 %: el subtotal de la tasa es el total de la línea', () => {
    const l = calcularLineaFiscal({
      cantidad: 2,
      precio_unitario: 55_000,
      afectacion_iva: AfectacionIva.GRAVADO,
      porcentaje_iva: 10,
    });
    expect(l.proporcion_iva).toBe(100);
    expect(l.base_gravada).toBe(100_000);
    expect(l.liquidacion_iva).toBe(10_000);
    const s = calcularSubtotalFiscal([l]);
    expect(s.subtotal_10).toBe(110_000);
    expect(s.subtotal_exento).toBe(0);
  });

  it('exento fuerza tasa y proporción en 0', () => {
    const l = calcularLineaFiscal({
      cantidad: 1,
      precio_unitario: 1000,
      afectacion_iva: AfectacionIva.EXENTO,
      porcentaje_iva: 10,
    });
    expect([l.porcentaje_iva, l.proporcion_iva, l.liquidacion_iva]).toEqual([0, 0, 0]);
    expect(calcularSubtotalFiscal([l]).subtotal_exento).toBe(1000);
  });

  it('cuota en USD: total en guaraníes con el tipo de cambio de la factura', () => {
    const l = calcularLineaFiscal({
      cantidad: 1,
      precio_unitario: 500,
      afectacion_iva: AfectacionIva.GRAVADO_PARCIAL,
      porcentaje_iva: 5,
      proporcion_iva: 30,
    });
    expect(calcularSubtotalFiscal([l], 7300).total_gs).toBe(3_650_000);
  });

  it('rechaza datos que SIFEN rechazaría', () => {
    expect(() =>
      calcularLineaFiscal({
        cantidad: 1,
        precio_unitario: 1,
        afectacion_iva: AfectacionIva.GRAVADO_PARCIAL,
        porcentaje_iva: 5,
      }),
    ).toThrow(/proporción/);
    expect(() =>
      calcularLineaFiscal({
        cantidad: 1,
        precio_unitario: 1,
        afectacion_iva: AfectacionIva.GRAVADO,
        porcentaje_iva: 7,
      }),
    ).toThrow(/Tasa/);
  });
});
