import 'reflect-metadata';
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
import { QueryOperationLogsDto } from './dto/operation-log.dto';
import { OperationLogsService } from './operation-logs.service';

const createQb = () => ({
  orderBy: jest.fn().mockReturnThis(),
  andWhere: jest.fn().mockReturnThis(),
  skip: jest.fn().mockReturnThis(),
  take: jest.fn().mockReturnThis(),
  getManyAndCount: jest.fn().mockResolvedValue([[], 0]),
});

describe('operation log query boundaries', () => {
  it.each(['0', '-1', '1.5', 'abc'])('rejects invalid page %s', async (page) => {
    const dto = plainToInstance(QueryOperationLogsDto, { page });
    expect((await validate(dto)).some((error) => error.property === 'page')).toBe(true);
  });

  it.each(['0', '201', '1.5', 'abc'])('rejects invalid page size %s', async (pageSize) => {
    const dto = plainToInstance(QueryOperationLogsDto, { pageSize });
    expect((await validate(dto)).some((error) => error.property === 'pageSize')).toBe(true);
  });


  it.each(['2026-02-31', '2026-07-13T00:00:00Z'])(
    'rejects invalid or non-date-only value %s',
    async (startDate) => {
      const dto = plainToInstance(QueryOperationLogsDto, { startDate });
      expect((await validate(dto)).some((error) => error.property === 'startDate')).toBe(true);
    },
  );

  it('transforms valid pagination and applies its database window', async () => {
    const dto = plainToInstance(QueryOperationLogsDto, { page: '2', pageSize: '20' });
    expect(await validate(dto)).toEqual([]);
    const qb = createQb();
    const service = new OperationLogsService({ createQueryBuilder: jest.fn().mockReturnValue(qb) } as never);
    await service.findAll(dto);
    expect(qb.skip).toHaveBeenCalledWith(20);
    expect(qb.take).toHaveBeenCalledWith(20);
  });

  it('rejects a reversed period before opening a query', async () => {
    const repo = { createQueryBuilder: jest.fn() };
    const service = new OperationLogsService(repo as never);
    await expect(service.findAll({ startDate: '2026-08-01', endDate: '2026-07-31' }))
      .rejects.toThrow('结束日期不能早于开始日期');
    expect(repo.createQueryBuilder).not.toHaveBeenCalled();
  });
});
