import { BadRequestException } from '@nestjs/common';
import { calcularDv } from 'src/crm/cierre/ruc.util';
import { resolverDatosFiscalesCompra, sinExtracto } from './datos-fiscales-compra';

const base43 = '01' + '80000001' + '9' + '001' + '002' + '0001234' + '1' + '20261015' + '1' + '123456789';
const CDC = base43 + calcularDv(base43);

describe('resolverDatosFiscalesCompra', () => {
  it('sin datos: factura, imputación de la empresa', () => {
    expect(resolverDatosFiscalesCompra({})).toEqual({
      tipo_comprobante: 'FACTURA',
      imputa_iva: null,
      imputa_ire: null,
      imputa_irp_rsp: null,
      no_imputa: false,
      extracto_cuenta: null,
      extracto_entidad: null,
      tipo_timbrado: 'PREIMPRESO',
      cdc: null,
      es_preimpreso: true,
    });
  });

  it('en una edición conserva lo guardado que no vino', () => {
    const r = resolverDatosFiscalesCompra({ imputa_iva: true }, { tipo_comprobante: 'AUTOFACTURA', imputa_ire: false });
    expect(r).toMatchObject({ tipo_comprobante: 'AUTOFACTURA', imputa_iva: true, imputa_ire: false });
  });

  it('rechaza un comprobante sin ningún impuesto', () => {
    expect(() => resolverDatosFiscalesCompra({ imputa_iva: false, imputa_ire: false, imputa_irp_rsp: false })).toThrow(
      BadRequestException,
    );
  });

  it('el extracto de tarjeta pide cuenta y banco', () => {
    expect(() => resolverDatosFiscalesCompra({ tipo_comprobante: 'EXTRACTO_TARJETA', extracto_cuenta: '4111' })).toThrow(
      /número de cuenta o tarjeta y el banco/,
    );
    expect(
      resolverDatosFiscalesCompra({ tipo_comprobante: 'EXTRACTO_TARJETA', extracto_cuenta: ' 4111 ', extracto_entidad: 'BANCO' }),
    ).toMatchObject({ extracto_cuenta: '4111', extracto_entidad: 'BANCO' });
  });

  it('fuera del extracto no guarda cuenta ni banco', () => {
    expect(resolverDatosFiscalesCompra({ extracto_cuenta: '4111', extracto_entidad: 'X' })).toMatchObject({
      extracto_cuenta: null,
      extracto_entidad: null,
    });
  });

  it('Compras no acepta despacho ni extracto', () => {
    expect(() => resolverDatosFiscalesCompra({ tipo_comprobante: 'DESPACHO_IMPORTACION' }, null, { origen: 'compra' })).toThrow(
      /cargalo como gasto/,
    );
    expect(sinExtracto(resolverDatosFiscalesCompra({ tipo_comprobante: 'AUTOFACTURA' }, null, { origen: 'compra' }))).not.toHaveProperty(
      'extracto_cuenta',
    );
  });

  describe('tipo de timbrado y CDC', () => {
    it('un CDC válido lo hace electrónico (fuera del archivo)', () => {
      expect(resolverDatosFiscalesCompra({ cdc: CDC })).toMatchObject({ tipo_timbrado: 'ELECTRONICO', cdc: CDC, es_preimpreso: false });
    });

    it('autoimpreso se declara; virtual y no verificado no', () => {
      expect(resolverDatosFiscalesCompra({ tipo_timbrado: 'AUTOIMPRESO' }).es_preimpreso).toBe(true);
      expect(resolverDatosFiscalesCompra({ tipo_timbrado: 'VIRTUAL' }).es_preimpreso).toBe(false);
      expect(resolverDatosFiscalesCompra({ tipo_timbrado: 'ELECTRONICO_NO_VERIFICADO' }).es_preimpreso).toBe(false);
    });

    it('la marca vieja es_preimpreso sigue funcionando', () => {
      expect(resolverDatosFiscalesCompra({ es_preimpreso: false }).tipo_timbrado).toBe('ELECTRONICO');
      expect(resolverDatosFiscalesCompra({ es_preimpreso: true }, { tipo_timbrado: 'AUTOIMPRESO' }).tipo_timbrado).toBe('AUTOIMPRESO');
    });

    it('rechaza un CDC con el verificador mal', () => {
      const malo = CDC.slice(0, 43) + ((Number(CDC[43]) + 1) % 10);
      expect(() => resolverDatosFiscalesCompra({ cdc: malo })).toThrow(/no es válido/);
    });

    it('el CDC tiene que corresponder al número de factura', () => {
      const numero = { establecimiento: '1', punto_expedicion: '2', numero_factura: '1234' };
      expect(resolverDatosFiscalesCompra({ cdc: CDC }, null, { origen: 'gasto', numero }).cdc).toBe(CDC);
      expect(() =>
        resolverDatosFiscalesCompra({ cdc: CDC }, null, { origen: 'gasto', numero: { ...numero, numero_factura: '9999' } }),
      ).toThrow(/001-002-0001234/);
    });
  });
});
