import { TestBed } from '@angular/core/testing';
import { provideHttpClient } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { TeamsApi } from './teams-api';
import { environment } from '../../../environments/environment';
import { Player } from '../../models/player.model';
import { Team } from '../../models/team.model';

describe('TeamsApi', () => {
  let service: TeamsApi;
  let httpMock: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [provideHttpClient(), provideHttpClientTesting()],
    });
    service = TestBed.inject(TeamsApi);
    httpMock = TestBed.inject(HttpTestingController);
  });

  afterEach(() => {
    httpMock.verify();
  });

  it('fetches the reduced bootstrap memberships belonging to a user', () => {
    const players = [{ id: 1, firstName: 'A', lastName: 'B', team: { id: 5, name: 'Team A' } }];

    service.loadMyTeams(42).subscribe((response) => {
      expect(response).toEqual(players);
    });

    const request = httpMock.expectOne(`${environment.apiUrl}users/42/teams`);
    expect(request.request.method).toBe('GET');
    request.flush(players);
  });

  it('fetches a team overview by id', () => {
    const team: Team = { id: 5, name: 'Team A', alias: 'team-a', balance: 0 };

    service.loadTeamOverview(5).subscribe((response) => {
      expect(response).toEqual(team);
    });

    const request = httpMock.expectOne(`${environment.apiUrl}teams/5/overview`);
    expect(request.request.method).toBe('GET');
    request.flush(team);
  });

  it('creates a player in a team', () => {
    const player = { firstName: 'Alex', lastName: 'Muster', teamRole: 1 };
    service.createPlayer(5, player).subscribe();
    const request = httpMock.expectOne(`${environment.apiUrl}teams/5/players`);
    expect(request.request.method).toBe('POST');
    expect(request.request.body).toEqual(player);
    request.flush({ id: 7, ...player, balance: 0, active: true });
  });

  it('updates an existing player', () => {
    const player: Player = {
      id: 7,
      firstName: 'Alex',
      lastName: 'Muster',
      balance: 0,
      active: false,
    };
    service.updatePlayer(5, player).subscribe();
    const request = httpMock.expectOne(`${environment.apiUrl}teams/5/players`);
    expect(request.request.method).toBe('PUT');
    expect(request.request.body).toEqual(player);
    request.flush(player);
  });

  it('loads an authenticated player history through the team id', () => {
    service.loadPlayerTransactions(5, 7).subscribe();
    const request = httpMock.expectOne(`${environment.apiUrl}teams/5/players/7/transactions`);
    expect(request.request.method).toBe('GET');
    request.flush([]);
  });

  it('sets a player active/inactive', () => {
    service.setPlayerActive(5, 7, false).subscribe();
    const request = httpMock.expectOne(`${environment.apiUrl}teams/5/players/7/active`);
    expect(request.request.method).toBe('PATCH');
    expect(request.request.body).toEqual({ active: false });
    request.flush({ id: 7, active: false });
  });

  it('changes a player team-role', () => {
    service.setPlayerTeamRole(5, 7, 4).subscribe();
    const request = httpMock.expectOne(`${environment.apiUrl}teams/5/players/7/team-role`);
    expect(request.request.method).toBe('PATCH');
    expect(request.request.body).toEqual({ teamRoleId: 4 });
    request.flush({ id: 7, teamRole: { id: 4 } });
  });

  it('creates a team', () => {
    const request = { name: '1. Herren' };
    service.createTeam(request).subscribe();
    const req = httpMock.expectOne(`${environment.apiUrl}teams`);
    expect(req.request.method).toBe('POST');
    expect(req.request.body).toEqual(request);
    req.flush({ id: 7, name: '1. Herren', alias: 'a', balance: 0 });
  });
});
