import { NumeracionInmService } from './numeracion-inm.service';

describe('NumeracionInmService', () => {
  const crear = (fila: { prefijo?: string; numero_actual?: number; relleno?: number } = {}) => {
    const cliente: any = {
      inm_numeracion: {
        createMany: jest.fn().mockResolvedValue({ count: 0 }),
        update: jest.fn().mockImplementation(({ data }) => Promise.resolve(data)),
      },
      $queryRaw: jest.fn().mockResolvedValue([
        {
          id: 'num-1',
          prefijo: fila.prefijo ?? 'OPI',
          numero_actual: fila.numero_actual ?? 0,
          relleno: fila.relleno ?? 7,
        },
      ]),
    };
    const prisma: any = { ...cliente, $transaction: jest.fn().mockImplementation((cb: any) => cb(cliente)) };
    return { service: new NumeracionInmService(prisma), prisma, cliente };
  };

  it('primer número de la empresa y avance del contador', async () => {
    expect(await crear().service.siguiente('emp-1', 'OPI')).toBe('OPI-0000001');
    const { service, cliente } = crear({ prefijo: 'RES', numero_actual: 41 });
    expect(await service.siguiente('emp-1', 'RES')).toBe('RES-0000042');
    expect(cliente.inm_numeracion.update.mock.calls[0][0].data.numero_actual).toBe(42);
  });

  it('crea la fila sola la primera vez y bloquea con FOR UPDATE', async () => {
    const { service, cliente } = crear();
    await service.siguiente('emp-1', 'COT');
    expect(cliente.inm_numeracion.createMany).toHaveBeenCalledWith({
      data: [{ empresa_id: 'emp-1', tipo: 'COT', prefijo: 'COT' }],
      skipDuplicates: true,
    });
    expect(cliente.$queryRaw.mock.calls[0][0].join('')).toMatch(/FOR UPDATE/);
  });

  it('dentro de una transacción ajena no abre otra', async () => {
    const { service, prisma, cliente } = crear();
    await service.siguiente('emp-1', 'OPI', cliente);
    expect(prisma.$transaction).not.toHaveBeenCalled();
  });
});
