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

describe('MediaViewModel', () => {
  it('should create instance with all properties', () => {
    const dto = {
      id: 'media-123',
      url: 'https://example.com/image.jpg',
      type: 'image',
      category: 'avatar',
      uploadedAt: '2023-01-15T00:00:00.000Z',
      size: 2048000,
    };

    const viewModel = new MediaViewModel(dto);

    expect(viewModel.id).toBe('media-123');
    expect(viewModel.url).toBe('https://example.com/image.jpg');
    expect(viewModel.type).toBe('image');
    expect(viewModel.category).toBe('avatar');
    expect(viewModel.uploadedAt).toEqual(new Date('2023-01-15'));
    expect(viewModel.size).toBe(2048000);
  });

  it('should create instance without optional properties', () => {
    const dto = {
      id: 'media-123',
      url: 'https://example.com/image.jpg',
      type: 'image',
      uploadedAt: '2023-01-15T00:00:00.000Z',
    };

    const viewModel = new MediaViewModel(dto);

    expect(viewModel.category).toBeUndefined();
    expect(viewModel.size).toBeUndefined();
  });

  it('should return "Unknown" for formattedSize when size is undefined', () => {
    const viewModel = new MediaViewModel({
      id: 'media-123',
      url: 'https://example.com/image.jpg',
      type: 'image',
      uploadedAt: new Date().toISOString(),
    });

    expect(viewModel.formattedSize).toBe('Unknown');
  });

  it('should format size in KB when less than 1 MB', () => {
    const viewModel = new MediaViewModel({
      id: 'media-123',
      url: 'https://example.com/image.jpg',
      type: 'image',
      uploadedAt: new Date().toISOString(),
      size: 512000, // 500 KB
    });

    expect(viewModel.formattedSize).toBe('500.00 KB');
  });

  it('should format size in MB when 1 MB or larger', () => {
    const viewModel = new MediaViewModel({
      id: 'media-123',
      url: 'https://example.com/image.jpg',
      type: 'image',
      uploadedAt: new Date().toISOString(),
      size: 2048000, // 2 MB in base-10, ~1.95 MB in base-2
    });
 
    expect(viewModel.formattedSize).toBe('1.95 MB');
  });

  it('should handle very small file sizes', () => {
    const viewModel = new MediaViewModel({
      id: 'media-123',
      url: 'https://example.com/image.jpg',
      type: 'image',
      uploadedAt: new Date().toISOString(),
      size: 1024, // 1 KB
    });

    expect(viewModel.formattedSize).toBe('1.00 KB');
  });

  it('should handle very large file sizes', () => {
    const viewModel = new MediaViewModel({
      id: 'media-123',
      url: 'https://example.com/video.mp4',
      type: 'video',
      uploadedAt: new Date().toISOString(),
      size: 104857600, // 100 MB
    });

    expect(viewModel.formattedSize).toBe('100.00 MB');
  });

  it('should support all media types', () => {
    const imageVm = new MediaViewModel({
      id: '1',
      url: 'image.jpg',
      type: 'image',
      uploadedAt: new Date().toISOString(),
    });
    const videoVm = new MediaViewModel({
      id: '2',
      url: 'video.mp4',
      type: 'video',
      uploadedAt: new Date().toISOString(),
    });
    const docVm = new MediaViewModel({
      id: '3',
      url: 'doc.pdf',
      type: 'document',
      uploadedAt: new Date().toISOString(),
    });

    expect(imageVm.type).toBe('image');
    expect(videoVm.type).toBe('video');
    expect(docVm.type).toBe('document');
  });

  it('should support all media categories', () => {
    const categories = ['avatar', 'team-logo', 'league-cover', 'race-result'] as const;

    categories.forEach(category => {
      const viewModel = new MediaViewModel({
        id: 'media-123',
        url: 'https://example.com/image.jpg',
        type: 'image',
        category,
        uploadedAt: new Date().toISOString(),
      });

      expect(viewModel.category).toBe(category);
    });
  });
});