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

const createPrizeDto = (overrides: Partial<any> = {}): any => ({
  id: 'prize-1',
  leagueId: 'league-1',
  seasonId: 'season-1',
  position: 1,
  name: 'Main Prize',
  amount: 100,
  type: 'cash',
  description: 'Top prize',
  awarded: false,
  awardedTo: undefined,
  awardedAt: undefined,
  createdAt: new Date('2024-01-01T00:00:00Z'),
  ...overrides,
});

describe('PrizeViewModel', () => {
  it('maps DTO fields via Object.assign', () => {
    const dto = createPrizeDto();

    const vm = new PrizeViewModel(dto);

    expect(vm.id).toBe('prize-1');
    expect(vm.leagueId).toBe('league-1');
    expect(vm.position).toBe(1);
    expect(vm.amount).toBe(100);
  });

  it('formats amount as EUR currency string', () => {
    const vm = new PrizeViewModel(createPrizeDto({ amount: 50.25 }));

    expect(vm.formattedAmount).toBe('€50.25');
  });

  it('formats positionDisplay based on position', () => {
    const first = new PrizeViewModel(createPrizeDto({ position: 1 }));
    const second = new PrizeViewModel(createPrizeDto({ position: 2 }));
    const third = new PrizeViewModel(createPrizeDto({ position: 3 }));
    const other = new PrizeViewModel(createPrizeDto({ position: 4 }));

    expect(first.positionDisplay).toBe('1st Place');
    expect(second.positionDisplay).toBe('2nd Place');
    expect(third.positionDisplay).toBe('3rd Place');
    expect(other.positionDisplay).toBe('4th Place');
  });

  it('maps type to human readable typeDisplay', () => {
    const cash = new PrizeViewModel(createPrizeDto({ type: 'cash' }));
    const merchandise = new PrizeViewModel(createPrizeDto({ type: 'merchandise' }));
    const other = new PrizeViewModel(createPrizeDto({ type: 'other' }));
    const unknown = new PrizeViewModel(createPrizeDto({ type: 'custom' }));

    expect(cash.typeDisplay).toBe('Cash Prize');
    expect(merchandise.typeDisplay).toBe('Merchandise');
    expect(other.typeDisplay).toBe('Other');
    expect(unknown.typeDisplay).toBe('custom');
  });

  it('derives statusDisplay and statusColor from awarded flag', () => {
    const available = new PrizeViewModel(createPrizeDto({ awarded: false }));
    const awarded = new PrizeViewModel(createPrizeDto({ awarded: true }));

    expect(available.statusDisplay).toBe('Available');
    expect(available.statusColor).toBe('blue');
    expect(awarded.statusDisplay).toBe('Awarded');
    expect(awarded.statusColor).toBe('green');
  });

  it('builds prizeDescription from name and amount', () => {
    const vm = new PrizeViewModel(createPrizeDto({ name: 'Bonus', amount: 25 }));

    expect(vm.prizeDescription).toBe('Bonus - €25.00');
  });

  it('formats awardedAt and createdAt timestamps', () => {
    const awardedAt = new Date('2024-01-02T00:00:00Z');
    const vm = new PrizeViewModel(createPrizeDto({ awarded: true, awardedAt }));

    expect(typeof vm.formattedAwardedAt).toBe('string');
    expect(typeof vm.formattedCreatedAt).toBe('string');

    const notAwarded = new PrizeViewModel(createPrizeDto({ awarded: false, awardedAt: undefined }));
    expect(notAwarded.formattedAwardedAt).toBe('Not awarded');
  });
});
