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

describe('Team', () => {
  it('should create a team', () => {
    const team = Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: ['league1', 'league2'],
      createdAt: new Date('2020-01-01'),
    });

    expect(team.id).toBe('team1');
    expect(team.name.toString()).toBe('Team Alpha');
    expect(team.tag.toString()).toBe('TA');
    expect(team.description.toString()).toBe('A great team');
    expect(team.ownerId.toString()).toBe('driver1');
    expect(team.leagues).toHaveLength(2);
    expect(team.leagues[0]!.toString()).toBe('league1');
    expect(team.leagues[1]!.toString()).toBe('league2');
    expect(team.createdAt.toDate()).toEqual(new Date('2020-01-01'));
  });

  it('should create team with default createdAt', () => {
    const before = new Date();
    const team = Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: [],
    });
    const after = new Date();

    expect(team.createdAt.toDate().getTime()).toBeGreaterThanOrEqual(before.getTime());
    expect(team.createdAt.toDate().getTime()).toBeLessThanOrEqual(after.getTime());
  });

  it('should update name', () => {
    const team = Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: [],
    });

    const updated = team.update({ name: 'Team Beta' });
    expect(updated.name.toString()).toBe('Team Beta');
    expect(updated.id).toBe('team1');
  });

  it('should update tag', () => {
    const team = Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: [],
    });

    const updated = team.update({ tag: 'TB' });
    expect(updated.tag.toString()).toBe('TB');
  });

  it('should update description', () => {
    const team = Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: [],
    });

    const updated = team.update({ description: 'Updated description' });
    expect(updated.description.toString()).toBe('Updated description');
  });

  it('should update ownerId', () => {
    const team = Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: [],
    });

    const updated = team.update({ ownerId: 'driver2' });
    expect(updated.ownerId.toString()).toBe('driver2');
  });

  it('should update leagues', () => {
    const team = Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: ['league1'],
    });

    const updated = team.update({ leagues: ['league2', 'league3'] });
    expect(updated.leagues).toHaveLength(2);
    expect(updated.leagues[0]!.toString()).toBe('league2');
    expect(updated.leagues[1]!.toString()).toBe('league3');
  });

  it('should throw on invalid id', () => {
    expect(() => Team.create({
      id: '',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: [],
    })).toThrow('Team ID is required');
  });

  it('should throw on invalid name', () => {
    expect(() => Team.create({
      id: 'team1',
      name: '',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: [],
    })).toThrow('Team name is required');
  });

  it('should throw on invalid tag', () => {
    expect(() => Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: '',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: [],
    })).toThrow('Team tag is required');
  });

  it('should throw on invalid description', () => {
    expect(() => Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: '',
      ownerId: 'driver1',
      leagues: [],
    })).toThrow('Team description is required');
  });

  it('should throw on invalid ownerId', () => {
    expect(() => Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: '',
      leagues: [],
    })).toThrow('Driver ID cannot be empty');
  });

  it('should throw on invalid leagues', () => {
    expect(() => Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: 'not an array' as unknown as string[],
    })).toThrow('Team leagues must be an array');
  });

  it('should throw on future createdAt', () => {
    const future = new Date();
    future.setFullYear(future.getFullYear() + 1);
    expect(() => Team.create({
      id: 'team1',
      name: 'Team Alpha',
      tag: 'TA',
      description: 'A great team',
      ownerId: 'driver1',
      leagues: [],
      createdAt: future,
    })).toThrow('Created date cannot be in the future');
  });
});