import { validarCoherenciaIva, porcentajesValidosPara } from './iva-coherencia';

describe('validarCoherenciaIva', () => {
  describe('afectación código 1 (Gravado)', () => {
    it('acepta IVA 10 con proporción 100', () => {
      expect(validarCoherenciaIva(1, 10, 100)).toEqual({ ok: true });
    });

    it('acepta IVA 5 con proporción 100', () => {
      expect(validarCoherenciaIva(1, 5, 100)).toEqual({ ok: true });
    });

    it('rechaza IVA 0', () => {
      const r = validarCoherenciaIva(1, 0, 100);
      expect(r.ok).toBe(false);
      expect((r as any).mensaje).toContain('5 o 10');
    });

    it('rechaza proporción distinta de 100', () => {
      const r = validarCoherenciaIva(1, 10, 80);
      expect(r.ok).toBe(false);
      expect((r as any).mensaje).toContain('100');
    });
  });

  describe('afectación códigos 2 y 3 (Exonerado)', () => {
    it.each([2, 3])('código %i acepta IVA 0 con proporción 0', (codigo) => {
      expect(validarCoherenciaIva(codigo, 0, 0)).toEqual({ ok: true });
    });

    it.each([2, 3])('código %i rechaza IVA 10', (codigo) => {
      expect(validarCoherenciaIva(codigo, 10, 0).ok).toBe(false);
    });

    it.each([2, 3])('código %i rechaza proporción 100', (codigo) => {
      expect(validarCoherenciaIva(codigo, 0, 100).ok).toBe(false);
    });
  });

  describe('afectación código 4 (Exento)', () => {
    it('acepta IVA 10 con proporción menor a 100', () => {
      expect(validarCoherenciaIva(4, 10, 80)).toEqual({ ok: true });
    });

    it('rechaza proporción 100', () => {
      expect(validarCoherenciaIva(4, 10, 100).ok).toBe(false);
    });

    it('rechaza IVA 0', () => {
      expect(validarCoherenciaIva(4, 0, 80).ok).toBe(false);
    });
  });

  describe('normalización del código', () => {
    it('trata el código string "1" igual que el número 1', () => {
      expect(validarCoherenciaIva('1', 10, 100)).toEqual({ ok: true });
      expect(validarCoherenciaIva('1', 0, 100).ok).toBe(false);
    });
  });
});

describe('etiqueta de afectación en el mensaje de error', () => {
  it('código 1 nombra "Gravado" cuando el porcentaje no coincide', () => {
    const r = validarCoherenciaIva(1, 0, 100);
    expect((r as any).mensaje).toContain('Gravado');
    expect((r as any).mensaje).not.toContain('Gravado parcial');
  });

  it('código 2 nombra "Exonerado" cuando el porcentaje no coincide', () => {
    const r = validarCoherenciaIva(2, 10, 0);
    expect((r as any).mensaje).toContain('Exonerado');
  });

  it('código 3 nombra "Exento" cuando el porcentaje no coincide', () => {
    const r = validarCoherenciaIva(3, 10, 0);
    expect((r as any).mensaje).toContain('Exento');
    expect((r as any).mensaje).not.toContain('Exonerado');
  });

  it('código 4 nombra "Gravado parcial" cuando el porcentaje no coincide', () => {
    const r = validarCoherenciaIva(4, 0, 80);
    expect((r as any).mensaje).toContain('Gravado parcial');
  });
});

describe('porcentajesValidosPara', () => {
  it('devuelve [10, 5] para Gravado', () => {
    expect(porcentajesValidosPara(1)).toEqual([10, 5]);
  });

  it('devuelve [0] para Exonerado', () => {
    expect(porcentajesValidosPara(2)).toEqual([0]);
  });

  it('devuelve [10, 5] para Exento', () => {
    expect(porcentajesValidosPara(4)).toEqual([10, 5]);
  });
});
