import { MiddlewareSifenService } from './middleware-sifen.service';

/**
 * Factura que el middleware frenó antes de mandarla a SIFEN (estado_sifen
 * "Error"): el número quedó usado sin documento y el ERP la tenía como venta
 * (deuda, stock, asiento). Caso DOBA 001-001-0001964, rechazada por un celular
 * de 8 dígitos. Sólo se deja inutilizar si SIFEN confirma que no la tiene.
 */
describe('MiddlewareSifenService.enviarEvento — inutilizar factura con Error', () => {
  const facturaError = {
    id: 'fac-1',
    empresa_id: 'emp-1',
    estado_sifen: 'Error',
    cdc: 'CDC-1964',
    dest: '001',
    dpunexp: '001',
    dnumdoc: '0001964',
    evento_aplicado: null,
    estado_evento: null,
  };

  const crear = (codSifen: string | null, documento: Record<string, unknown> = facturaError) => {
    const prisma: any = {
      factura_cab: {
        findFirst: jest.fn().mockResolvedValue(documento),
        updateMany: jest.fn().mockResolvedValue({ count: 1 }),
        update: jest.fn().mockResolvedValue({}),
      },
      documentos_electronicos: { findFirst: jest.fn().mockResolvedValue({ num_timbrado: '17389000' }) },
      empresas_timbrado: { findFirst: jest.fn().mockResolvedValue(null) },
    };
    const audit = { log: jest.fn().mockResolvedValue(undefined) };
    const service = new MiddlewareSifenService({} as any, prisma, audit as any, {} as any, {} as any, {} as any, {} as any, {} as any, {} as any);
    jest.spyOn(service, 'empresaUsaSifen').mockResolvedValue(true);
    const consulta = jest.spyOn(service as any, 'consultarCdcEnSifen').mockResolvedValue(codSifen);
    jest.spyOn(service as any, 'esperarYConsultarEstado').mockResolvedValue({ estado: 'Pendiente', mensaje: 'Esperando' });
    const enviar = jest.spyOn(service as any, 'sendEventoToMiddleware').mockResolvedValue({ ok: true });
    return { service, prisma, consulta, enviar };
  };

  it('SIFEN no la tiene (0420): manda la inutilización', async () => {
    const { service, consulta, enviar } = crear('0420');
    await service.enviarEvento('emp-1', 'factura', 'inutilizacion', 'fac-1', 'Duplicado de la 0001960');
    expect(consulta).toHaveBeenCalledWith('emp-1', 'CDC-1964');
    expect((enviar.mock.calls[0][1] as any).tipoEve).toBe('EINU');
  });

  it('SIFEN la tiene aprobada (0422): no la inutiliza', async () => {
    const { service, enviar, prisma } = crear('0422');
    const r = await service.enviarEvento('emp-1', 'factura', 'inutilizacion', 'fac-1', 'motivo');
    expect(r.success).toBe(false);
    expect(r.message).toMatch(/aprobada/);
    expect(enviar).not.toHaveBeenCalled();
    expect(prisma.factura_cab.updateMany).not.toHaveBeenCalled();
  });

  it('si no se puede consultar SIFEN, no arriesga', async () => {
    const { service, enviar } = crear(null);
    const r = await service.enviarEvento('emp-1', 'factura', 'inutilizacion', 'fac-1', 'motivo');
    expect(r.success).toBe(false);
    expect(r.message).toMatch(/No se pudo confirmar/);
    expect(enviar).not.toHaveBeenCalled();
  });

  it('un documento en vuelo (Enviado) sigue sin poder inutilizarse', async () => {
    const { service, consulta, enviar } = crear('0420', { ...facturaError, estado_sifen: 'Enviado' });
    const r = await service.enviarEvento('emp-1', 'factura', 'inutilizacion', 'fac-1', 'motivo');
    expect(r).toMatchObject({ success: false, message: 'Solo se pueden inutilizar documentos rechazados' });
    expect(consulta).not.toHaveBeenCalled();
    expect(enviar).not.toHaveBeenCalled();
  });
});
