import { GetModerationAuditLogsHandler } from '../queries/get-moderation-audit-logs/get-moderation-audit-logs.handler';
import { GetModerationAuditLogsQuery } from '../queries/get-moderation-audit-logs/get-moderation-audit-logs.query';

describe('GetModerationAuditLogsHandler', () => {
  let handler: GetModerationAuditLogsHandler;
  let mockRepo: { findAll: ReturnType<typeof vi.fn> };
  let mockLogger: {
    log: ReturnType<typeof vi.fn>;
    error: ReturnType<typeof vi.fn>;
  };

  const mockResult = {
    data: [
      {
        id: 'mod-1',
        targetType: 'listing',
        targetId: 'listing-1',
        action: 'approve',
        moderatorId: 'admin-1',
        reason: null,
        metadata: null,
        createdAt: new Date('2026-04-10T10:00:00Z'),
      },
    ],
    total: 1,
    page: 1,
    limit: 20,
    totalPages: 1,
  };

  beforeEach(() => {
    mockRepo = { findAll: vi.fn().mockResolvedValue(mockResult) };
    mockLogger = { log: vi.fn(), error: vi.fn() };

    handler = new GetModerationAuditLogsHandler(
      mockRepo as any,
      mockLogger as any,
    );
  });

  it('returns paginated moderation audit logs with default filters', async () => {
    const result = await handler.execute(new GetModerationAuditLogsQuery());

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

  it('passes filters through to the repository', async () => {
    const start = new Date('2026-04-01');
    const end = new Date('2026-04-30');

    await handler.execute(
      new GetModerationAuditLogsQuery(
        2,
        50,
        'listing',
        'listing-1',
        'reject',
        'mod-9',
        start,
        end,
      ),
    );

    expect(mockRepo.findAll).toHaveBeenCalledWith({
      page: 2,
      limit: 50,
      targetType: 'listing',
      targetId: 'listing-1',
      action: 'reject',
      moderatorId: 'mod-9',
      startDate: start,
      endDate: end,
    });
  });

  it('wraps unexpected errors as InternalServerErrorException', async () => {
    mockRepo.findAll.mockRejectedValue(new Error('boom'));

    await expect(
      handler.execute(new GetModerationAuditLogsQuery()),
    ).rejects.toThrow('Lỗi khi lấy nhật ký kiểm duyệt');
    expect(mockLogger.error).toHaveBeenCalled();
  });
});
