import { type IReviewRepository } from '../../domain/repositories/review.repository';
import { GetReviewsByTargetHandler } from '../queries/get-reviews-by-target/get-reviews-by-target.handler';
import { GetReviewsByTargetQuery } from '../queries/get-reviews-by-target/get-reviews-by-target.query';

describe('GetReviewsByTargetHandler', () => {
  let handler: GetReviewsByTargetHandler;
  let mockReviewRepo: { [K in keyof IReviewRepository]: ReturnType<typeof vi.fn> };

  const mockPaginatedResult = {
    data: [
      {
        id: 'review-1',
        userId: 'user-1',
        userName: 'Nguyen Van A',
        targetType: 'agent',
        targetId: 'agent-1',
        rating: 5,
        comment: 'Excellent!',
        createdAt: '2026-01-01T00:00:00.000Z',
      },
    ],
    total: 1,
    page: 1,
    limit: 20,
    totalPages: 1,
  };

  beforeEach(() => {
    mockReviewRepo = {
      findById: vi.fn(),
      findByUserAndTarget: vi.fn(),
      save: vi.fn(),
      delete: vi.fn(),
      findByTarget: vi.fn(),
      findByUserId: vi.fn(),
      getStats: vi.fn(),
    };

    handler = new GetReviewsByTargetHandler(mockReviewRepo as any);
  });

  it('returns paginated reviews for a target', async () => {
    mockReviewRepo.findByTarget.mockResolvedValue(mockPaginatedResult);

    const query = new GetReviewsByTargetQuery('agent', 'agent-1', 1, 20);
    const result = await handler.execute(query);

    expect(result).toEqual(mockPaginatedResult);
    expect(mockReviewRepo.findByTarget).toHaveBeenCalledWith('agent', 'agent-1', 1, 20);
  });

  it('passes custom pagination params', async () => {
    mockReviewRepo.findByTarget.mockResolvedValue({ ...mockPaginatedResult, page: 2 });

    const query = new GetReviewsByTargetQuery('property', 'prop-1', 2, 10);
    await handler.execute(query);

    expect(mockReviewRepo.findByTarget).toHaveBeenCalledWith('property', 'prop-1', 2, 10);
  });
});
