import { ComponentFixture, TestBed } from '@angular/core/testing';

import { MyProfileUpdateFormComponent } from './my-profile-update-form.component';
import { provideRouter } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
import { FormBuilder } from '@angular/forms';
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
import { ProfileRepository } from '@app/domain/profiles/profile.repository';
import { of } from 'rxjs';
import { Profile } from '@app/domain/profiles/profile.model';
import { SectorRepository } from '@app/domain/sectors/sector.repository';
import { Sector } from '@app/domain/sectors/sector.model';
import { SECTOR_REPOSITORY_TOKEN } from '@app/infrastructure/sectors/sector-repository.token';

describe('MyProfileUpdateFormComponent', () => {
  let component: MyProfileUpdateFormComponent;
  let fixture: ComponentFixture<MyProfileUpdateFormComponent>;

  let mockToastrService: Partial<ToastrService>;
  let mockProfileRepo: ProfileRepository;
  let mockSectorRepo: SectorRepository;

  const mockProfileData = {
    profession: '',
    secteur: '',
    bio: '',
    apropos: '',
    reseaux: { facebook: '', github: '', instagram: '', linkedIn: '', web: '', x: '', youTube: '' },
  };

  beforeEach(async () => {
    mockToastrService = {
      warning: jest.fn(),
      success: jest.fn(),
      error: jest.fn(),
    };

    mockProfileRepo = {
      create: jest.fn(),
      list: jest.fn(),
      update: jest.fn().mockReturnValue(of({} as Profile)),
      getByUserId: jest.fn().mockReturnValue(of({} as Profile)),
    };

    mockSectorRepo = {
      list: jest.fn().mockReturnValue(of([])),
      getOne: jest.fn().mockReturnValue(of({} as Sector)),
    };

    await TestBed.configureTestingModule({
      imports: [MyProfileUpdateFormComponent],
      providers: [
        FormBuilder,
        provideRouter([]),
        { provide: ToastrService, useValue: mockToastrService },
        { provide: PROFILE_REPOSITORY_TOKEN, useValue: mockProfileRepo },
        { provide: SECTOR_REPOSITORY_TOKEN, useValue: mockSectorRepo },
      ],
    }).compileComponents();

    fixture = TestBed.createComponent(MyProfileUpdateFormComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

    await fixture.whenStable();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should submit invalid update form', () => {
    component.profileForm.setValue(mockProfileData);

    const spyUpdateProfile = jest.spyOn(component, 'onSubmit');
    component.onSubmit();
    expect(component.profileForm.valid).toEqual(false);
    expect(spyUpdateProfile).toHaveBeenCalled();
  });

  it('should submit valid update form', () => {
    mockProfileData.profession = 'developer';
    mockProfileData.secteur = 'technology';
    mockProfileData.bio = 'A passionate developer';
    mockProfileData.apropos = 'About me';
    component.profileForm.setValue(mockProfileData);

    const spyUpdateProfile = jest.spyOn(component, 'onSubmit');
    component.onSubmit();
    expect(component.profileForm.valid).toEqual(true);
    expect(spyUpdateProfile).toHaveBeenCalled();
  });
});
