import { BadRequestException } from '@nestjs/common';
import { ParametrosService } from './parametros.service';

describe('ParametrosService — crear (versionado temporal)', () => {
  const EMPRESA_ID = 'empresa-1';

  const buildPrisma = () => {
    const updateMany = jest.fn().mockResolvedValue({ count: 1 });
    const create = jest.fn().mockImplementation(({ data }: any) => Promise.resolve({ id: 'nuevo', ...data }));
    const tx = { rrhh_parametros_sistema: { updateMany, create } };
    return {
      rrhh_parametros_sistema: {
        findFirst: jest.fn().mockResolvedValue(null), // sin duplicado exacto
      },
      $transaction: jest.fn().mockImplementation(async (cb: any) => cb(tx)),
      _tx: tx,
      _updateMany: updateMany,
      _create: create,
    };
  };

  const dto = {
    clave: 'LIMITE_DESCUENTO_SALARIO',
    nombre: 'Límite máximo de descuentos sobre salario',
    valor: '0.5',
    tipo_dato: 'PORCENTAJE' as const,
    categoria: 'LIMITE' as const,
    vigencia_desde: '2026-07-06',
  };

  it('cierra las versiones abiertas anteriores de la misma clave al crear una nueva vigencia', async () => {
    const prisma = buildPrisma();
    const service = new ParametrosService(prisma as any);

    await service.crear(EMPRESA_ID, dto as any, 'user-1');

    expect(prisma._updateMany).toHaveBeenCalledTimes(1);
    const arg = prisma._updateMany.mock.calls[0][0];
    // Filtra por misma clave/empresa y versiones que empiezan antes y siguen abiertas/solapadas
    expect(arg.where.clave).toBe('LIMITE_DESCUENTO_SALARIO');
    expect(arg.where.empresa_id).toBe(EMPRESA_ID);
    expect(arg.where.vigencia_desde.lt).toEqual(new Date('2026-07-06'));
    // Cierra el día previo a la nueva vigencia (05/07/2026)
    expect(arg.data.vigencia_hasta).toEqual(new Date('2026-07-05'));
    // Y crea la nueva versión
    expect(prisma._create).toHaveBeenCalledTimes(1);
    expect(prisma._create.mock.calls[0][0].data.valor).toBe('0.5');
  });

  it('rechaza una vigencia duplicada exacta de la misma clave', async () => {
    const prisma = buildPrisma();
    prisma.rrhh_parametros_sistema.findFirst.mockResolvedValue({ id: 'existente' });
    const service = new ParametrosService(prisma as any);

    await expect(service.crear(EMPRESA_ID, dto as any, 'user-1')).rejects.toThrow(BadRequestException);
    expect(prisma._create).not.toHaveBeenCalled();
  });

  it('rechaza vigencia_hasta anterior a vigencia_desde', async () => {
    const prisma = buildPrisma();
    const service = new ParametrosService(prisma as any);

    await expect(
      service.crear(EMPRESA_ID, { ...dto, vigencia_hasta: '2026-07-01' } as any, 'user-1'),
    ).rejects.toThrow(BadRequestException);
  });
});
