import { describe, it, expect } from 'vitest';
import { UserProfileViewModel } from './UserProfileViewModel';

describe('UserProfileViewModel', () => {
  it('maps required properties from the DTO', () => {
    const dto = {
      id: 'user-1',
      name: 'Roo Racer',
    };

    const viewModel = new UserProfileViewModel(dto);

    expect(viewModel.id).toBe('user-1');
    expect(viewModel.name).toBe('Roo Racer');
    expect(viewModel.avatarUrl).toBeUndefined();
    expect(viewModel.iracingId).toBeUndefined();
    expect(viewModel.rating).toBeUndefined();
  });

  it('maps optional properties only when provided', () => {
    const dto = {
      id: 'user-2',
      name: 'Rated Driver',
      avatarUrl: 'https://example.com/avatar.jpg',
      iracingId: '12345',
      rating: 2734,
    };

    const viewModel = new UserProfileViewModel(dto);

    expect(viewModel.avatarUrl).toBe('https://example.com/avatar.jpg');
    expect(viewModel.iracingId).toBe('12345');
    expect(viewModel.rating).toBe(2734);
  });

  it('formats rating as whole-number string when present, or Unrated otherwise', () => {
    const unrated = new UserProfileViewModel({ id: 'user-1', name: 'Unrated Driver' });
    const rated = new UserProfileViewModel({ id: 'user-2', name: 'Rated Driver', rating: 2734.56 });

    expect(unrated.formattedRating).toBe('Unrated');
    expect(rated.formattedRating).toBe('2735');
  });

  it('indicates whether an iRacing ID is present', () => {
    const withoutId = new UserProfileViewModel({ id: 'user-1', name: 'No ID' });
    const withId = new UserProfileViewModel({ id: 'user-2', name: 'Has ID', iracingId: '67890' });

    expect(withoutId.hasIracingId).toBe(false);
    expect(withId.hasIracingId).toBe(true);
  });

  it('computes profile completeness based on available optional fields', () => {
    const base = new UserProfileViewModel({ id: 'user-1', name: 'Base User' });
    const withAvatar = new UserProfileViewModel({ id: 'user-2', name: 'Avatar User', avatarUrl: 'url' });
    const withAvatarAndId = new UserProfileViewModel({
      id: 'user-3',
      name: 'Avatar + ID',
      avatarUrl: 'url',
      iracingId: '123',
    });
    const withAll = new UserProfileViewModel({
      id: 'user-4',
      name: 'Full Profile',
      avatarUrl: 'url',
      iracingId: '123',
      rating: 2000,
    });

    expect(base.profileCompleteness).toBe(25);
    expect(withAvatar.profileCompleteness).toBe(50);
    expect(withAvatarAndId.profileCompleteness).toBe(75);
    expect(withAll.profileCompleteness).toBe(100);
  });

  it('derives avatar initials from the name', () => {
    const viewModel = new UserProfileViewModel({ id: 'user-1', name: 'Roo Racer' });

    expect(viewModel.avatarInitials).toBe('RR');
  });
});
