import { describe, it, expect, vi, Mocked } from 'vitest';
import { DashboardService } from './DashboardService';
import { AnalyticsApiClient } from '../../api/analytics/AnalyticsApiClient';
import { AnalyticsDashboardViewModel, AnalyticsMetricsViewModel } from '../../view-models';

describe('DashboardService', () => {
  let mockApiClient: Mocked<AnalyticsApiClient>;
  let service: DashboardService;

  beforeEach(() => {
    mockApiClient = {
      getDashboardData: vi.fn(),
      getAnalyticsMetrics: vi.fn(),
      recordPageView: vi.fn(),
      recordEngagement: vi.fn(),
    } as Mocked<AnalyticsApiClient>;

    service = new DashboardService(mockApiClient);
  });

  describe('getDashboardData', () => {
    it('should call apiClient.getDashboardData and return AnalyticsDashboardViewModel', async () => {
      const dto = {
        totalUsers: 100,
        activeUsers: 50,
        totalRaces: 20,
        totalLeagues: 5,
      };
      mockApiClient.getDashboardData.mockResolvedValue(dto);

      const result = await service.getDashboardData();

      expect(mockApiClient.getDashboardData).toHaveBeenCalled();
      expect(result).toBeInstanceOf(AnalyticsDashboardViewModel);
      expect(result.totalUsers).toBe(100);
      expect(result.activeUsers).toBe(50);
      expect(result.totalRaces).toBe(20);
      expect(result.totalLeagues).toBe(5);
    });
  });

  describe('getAnalyticsMetrics', () => {
    it('should call apiClient.getAnalyticsMetrics and return AnalyticsMetricsViewModel', async () => {
      const dto = {
        pageViews: 1000,
        uniqueVisitors: 500,
        averageSessionDuration: 300,
        bounceRate: 0.25,
      };
      mockApiClient.getAnalyticsMetrics.mockResolvedValue(dto);

      const result = await service.getAnalyticsMetrics();

      expect(mockApiClient.getAnalyticsMetrics).toHaveBeenCalled();
      expect(result).toBeInstanceOf(AnalyticsMetricsViewModel);
      expect(result.pageViews).toBe(1000);
      expect(result.uniqueVisitors).toBe(500);
      expect(result.averageSessionDuration).toBe(300);
      expect(result.bounceRate).toBe(0.25);
    });
  });

});
