import { GetAuditLogsHandler } from '../queries/get-audit-logs/get-audit-logs.handler';
import { GetAuditLogsQuery } from '../queries/get-audit-logs/get-audit-logs.query';

describe('GetAuditLogsHandler', () => {
  let handler: GetAuditLogsHandler;
  let mockAuditRepo: { findAll: ReturnType<typeof vi.fn> };

  const mockResult = {
    data: [
      {
        id: 'audit-1',
        action: 'USER_BANNED',
        actorId: 'admin-1',
        targetId: 'user-1',
        targetType: 'USER',
        metadata: { reason: 'Spam' },
        ipAddress: null,
        userAgent: null,
        createdAt: new Date('2026-04-10T10:00:00Z'),
      },
    ],
    total: 1,
    page: 1,
    limit: 20,
    totalPages: 1,
  };

  beforeEach(() => {
    mockAuditRepo = {
      findAll: vi.fn().mockResolvedValue(mockResult),
    };

    handler = new GetAuditLogsHandler(mockAuditRepo as any);
  });

  it('returns paginated audit logs', async () => {
    const query = new GetAuditLogsQuery(1, 20);

    const result = await handler.execute(query);

    expect(result).toEqual(mockResult);
    expect(mockAuditRepo.findAll).toHaveBeenCalledWith({
      page: 1,
      limit: 20,
      action: undefined,
      actorId: undefined,
      targetId: undefined,
      targetType: undefined,
      startDate: undefined,
      endDate: undefined,
    });
  });

  it('passes filter parameters to repository', async () => {
    const startDate = new Date('2026-04-01');
    const endDate = new Date('2026-04-10');
    const query = new GetAuditLogsQuery(2, 10, 'USER_BANNED', 'admin-1', 'user-1', 'USER', startDate, endDate);

    await handler.execute(query);

    expect(mockAuditRepo.findAll).toHaveBeenCalledWith({
      page: 2,
      limit: 10,
      action: 'USER_BANNED',
      actorId: 'admin-1',
      targetId: 'user-1',
      targetType: 'USER',
      startDate,
      endDate,
    });
  });

  it('uses default pagination when not specified', async () => {
    const query = new GetAuditLogsQuery();

    await handler.execute(query);

    expect(mockAuditRepo.findAll).toHaveBeenCalledWith(
      expect.objectContaining({ page: 1, limit: 20 }),
    );
  });
});
