import { ProfileFacade } from '@app/adapters/profiles/profile.facade';
import { TestBed } from '@angular/core/testing';
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
import { FakeProfileRepository } from '@app/testing/domain/profiles/fake-profile.repository';
import { mockProfiles } from '@app/testing/profile.mock';
import { Profile } from '@app/domain/profiles/profile.model';
import { ProfileDTO } from '@app/domain/profiles/dto/create-profile.dto';
import { ToastrService } from 'ngx-toastr';
import { mockToastR } from '@app/testing/toastr.mock';
import { SearchService } from '@app/infrastructure/search/search.service';
import { mockSearchService } from '@app/testing/search.service.mock';
import { FeedbackService } from '@app/adapters/shared/services/feedback.service';
import { mockFeedbackService } from '@app/testing/feedback.service.mock';

describe('ProfileFacade', () => {
  let facade: ProfileFacade;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        ProfileFacade,
        { provide: PROFILE_REPOSITORY_TOKEN, useClass: FakeProfileRepository },
        { provide: SearchService, useValue: mockSearchService },
        { provide: FeedbackService, useValue: mockFeedbackService },
        { provide: ToastrService, useValue: mockToastR },
      ],
    });

    facade = TestBed.inject(ProfileFacade);
  });

  it('doit charger la liste des profils', () => {
    facade.load();

    // attendre un peu le .subscribe
    setTimeout(() => {
      expect(facade.profiles().length).toBe(2);
      expect(facade.loading().isLoading).toBe(false);
    }, 0);
  });

  it("doit charger le profile d'un utilisateur ", () => {
    facade.loadOne('1');
    const expectedProfile = mockProfiles[0];

    // attendre un peu le .subscribe
    setTimeout(() => {
      expect(facade.profile()).toBe(expectedProfile);
      expect(facade.loading().isLoading).toBe(false);
      expect(facade.error().hasError).toBe(false);
    }, 0);
  });

  it('doit mettre à jour un profile ', () => {
    expect(mockProfiles[0].profession).toBe('Développeur Web');

    const profileUpdated: Profile = {
      ...mockProfiles[0],
      profession: 'Devops',
    };

    facade.update('1', profileUpdated);

    // attendre un peu le .subscribe
    setTimeout(() => {
      expect(facade.profile().profession).toBe('Devops');
      expect(facade.loading().isLoading).toBe(false);
      expect(facade.error().hasError).toBe(false);
    }, 0);
  });

  it('doit creer un nouveau profile ', () => {
    const profile: ProfileDTO = {
      utilisateur: 'john doe',
      reseaux: {},
      profession: 'Journaliste',
    };

    facade.create(profile);

    // attendre un peu le .subscribe
    setTimeout(() => {
      expect(mockProfiles.find((profile) => profile.id === facade.profile().id)).toBeDefined();
      expect(facade.profile().profession).toBe('Journaliste');
      expect(facade.loading().isLoading).toBe(false);
      expect(facade.error().hasError).toBe(false);
    }, 0);
  });
});
