import { describe, it, expect, vi, Mocked } from 'vitest';
import { SessionService } from './SessionService';
import { AuthApiClient } from '../../api/auth/AuthApiClient';
import { SessionViewModel } from '../../view-models/SessionViewModel';

describe('SessionService', () => {
  let mockApiClient: Mocked<AuthApiClient>;
  let service: SessionService;

  beforeEach(() => {
    mockApiClient = {
      getSession: vi.fn(),
    } as Mocked<AuthApiClient>;

    service = new SessionService(mockApiClient);
  });

  describe('getSession', () => {
    it('should call apiClient.getSession and return SessionViewModel when session exists', async () => {
      const mockResponse = {
        token: 'jwt-token',
        user: {
          userId: 'user-123',
          email: 'test@example.com',
          displayName: 'Test User',
        },
      };

      mockApiClient.getSession.mockResolvedValue(mockResponse);

      const result = await service.getSession();

      expect(mockApiClient.getSession).toHaveBeenCalled();
      expect(result).toBeInstanceOf(SessionViewModel);
      expect(result?.userId).toBe('user-123');
      expect(result?.email).toBe('test@example.com');
      expect(result?.displayName).toBe('Test User');
      expect(result?.isAuthenticated).toBe(true);
    });

    it('should return null when apiClient.getSession returns null', async () => {
      mockApiClient.getSession.mockResolvedValue(null);

      const result = await service.getSession();

      expect(mockApiClient.getSession).toHaveBeenCalled();
      expect(result).toBeNull();
    });

    it('should throw error when apiClient.getSession fails', async () => {
      const error = new Error('Get session failed');
      mockApiClient.getSession.mockRejectedValue(error);

      await expect(service.getSession()).rejects.toThrow('Get session failed');
    });
  });
});