import { vi, type Mock } from 'vitest';
import { GetCurrentSessionUseCase } from './GetCurrentSessionUseCase';
import { User } from '../../domain/entities/User';
import { IUserRepository, StoredUser } from '../../domain/repositories/IUserRepository';

describe('GetCurrentSessionUseCase', () => {
  let useCase: GetCurrentSessionUseCase;
  let mockUserRepo: {
    findByEmail: Mock;
    findById: Mock;
    create: Mock;
    update: Mock;
    emailExists: Mock;
  };

  beforeEach(() => {
    mockUserRepo = {
      findByEmail: vi.fn(),
      findById: vi.fn(),
      create: vi.fn(),
      update: vi.fn(),
      emailExists: vi.fn(),
    };
    useCase = new GetCurrentSessionUseCase(mockUserRepo as IUserRepository);
  });

  it('should return User when user exists', async () => {
    const userId = 'user-123';
    const storedUser: StoredUser = {
      id: userId,
      email: 'test@example.com',
      displayName: 'Test User',
      passwordHash: 'hash',
      salt: 'salt',
      primaryDriverId: 'driver-123',
      createdAt: new Date(),
    };
    mockUserRepo.findById.mockResolvedValue(storedUser);

    const result = await useCase.execute(userId);

    expect(mockUserRepo.findById).toHaveBeenCalledWith(userId);
    expect(result).toBeInstanceOf(User);
    expect(result?.getId().value).toBe(userId);
    expect(result?.getDisplayName()).toBe('Test User');
  });

  it('should return null when user does not exist', async () => {
    const userId = 'user-123';
    mockUserRepo.findById.mockResolvedValue(null);

    const result = await useCase.execute(userId);

    expect(mockUserRepo.findById).toHaveBeenCalledWith(userId);
    expect(result).toBeNull();
  });
});