import { type IReviewRepository } from '../../domain/repositories/review.repository';
import { GetAverageRatingHandler } from '../queries/get-average-rating/get-average-rating.handler';
import { GetAverageRatingQuery } from '../queries/get-average-rating/get-average-rating.query';

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

  const mockStats = {
    targetType: 'agent',
    targetId: 'agent-1',
    averageRating: 4.3,
    totalReviews: 10,
    distribution: { 1: 0, 2: 1, 3: 1, 4: 3, 5: 5 },
  };

  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 GetAverageRatingHandler(mockReviewRepo as any);
  });

  it('returns rating stats for a target', async () => {
    mockReviewRepo.getStats.mockResolvedValue(mockStats);

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

    expect(result).toEqual(mockStats);
    expect(result.averageRating).toBe(4.3);
    expect(result.totalReviews).toBe(10);
    expect(mockReviewRepo.getStats).toHaveBeenCalledWith('agent', 'agent-1');
  });

  it('returns zero stats when no reviews exist', async () => {
    const emptyStats = {
      targetType: 'property',
      targetId: 'prop-1',
      averageRating: 0,
      totalReviews: 0,
      distribution: { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 },
    };
    mockReviewRepo.getStats.mockResolvedValue(emptyStats);

    const query = new GetAverageRatingQuery('property', 'prop-1');
    const result = await handler.execute(query);

    expect(result.averageRating).toBe(0);
    expect(result.totalReviews).toBe(0);
  });
});
