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

import { LoginComponent } from './login.component';
import { ToastrService } from 'ngx-toastr';
import { FormBuilder } from '@angular/forms';
import { provideRouter } from '@angular/router';
import { AuthRepository } from '@app/domain/authentification/auth.repository';
import { AUTH_REPOSITORY_TOKEN } from '@app/infrastructure/authentification/auth-repository.token';
import { ProfileRepository } from '@app/domain/profiles/profile.repository';
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
import { mockAuthRepo } from '@app/testing/auth.mock';
import { mockProfileRepo } from '@app/testing/profile.mock';
import { mockToastR } from '@app/testing/toastr.mock';

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

  // Mocks des services
  let mockToastrService: Partial<ToastrService> = mockToastR;
  let mockAuthRepository: jest.Mocked<Partial<AuthRepository>> = mockAuthRepo;
  let mockProfileRepository: jest.Mocked<Partial<ProfileRepository>> = mockProfileRepo;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [LoginComponent],
      providers: [
        FormBuilder,
        provideRouter([]),
        { provide: ToastrService, useValue: mockToastrService },
        { provide: AUTH_REPOSITORY_TOKEN, useValue: mockAuthRepository },
        { provide: PROFILE_REPOSITORY_TOKEN, useValue: mockProfileRepository },
      ],
    }).compileComponents();

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

    await fixture.whenStable();
  });

  afterEach(() => {
    // si le composant instancie subscriptions/timers
    fixture.destroy();
  });

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

  it('should invalid form if empty', () => {
    expect(component.loginForm.valid).toBeFalsy();
  });

  /*it('should call onSubmit action and nothing if form is invalid', () => {
    component.loginForm.setValue({ email: '', password: '' });
    const spyLogin = jest.spyOn(component, 'login');
    component.onSubmit();
    expect(spyLogin).not.toHaveBeenCalled();
  });

  it('should submit form and call login ', () => {
    // Spion sur l'EventEmitter formSubmitted
    const emitSpy = jest.spyOn(component.formSubmitted, 'emit');

    const loginDto = { email: 'test@test.com', password: '123456' };
    component.loginForm.setValue(loginDto);

    // Mock login retourne une Promise réussie
    (mockAuthService.login as jest.Mock).mockResolvedValue({
      isValid: true,
      record: { name: 'John', email: 'test@test.com' },
    });

    component.onSubmit();

    expect(emitSpy).toHaveBeenCalledWith({ email: 'test@test.com', password: '123456' });
    // login est appelée
    expect(mockAuthService.login).toHaveBeenCalledWith({
      email: 'test@test.com',
      password: '123456',
    });
  });

  it('should make warning toast if invalid login and password ', async () => {
   (mockAuthService.login as jest.Mock).mockResolvedValue({ isValid: false });

   await component.login({ email: 'fail@test.com', password: 'fail' });

   expect(mockToastrService.info).toHaveBeenCalledWith(
     'Vous devez vérifier votre adresse e-mail avant de vous connecter.',
     'Information de connexion',
     {
       closeButton: true,
       progressAnimation: 'decreasing',
       progressBar: true,
     }
   );
 });

it('should make succes toast if valid login and password', async () => {
   const user = { name: 'John', email: 'john@test.com' };
   (mockAuthService.login as jest.Mock).mockResolvedValue({ isValid: true, record: user });

   await component.login({ email: 'john@test.com', password: 'pass' });

   expect(mockToastrService.success).toHaveBeenCalledWith(
     `Bienvenue ${user.name ? user.name : user.email}!`,
     'Connexion',
     {
       closeButton: true,
       progressAnimation: 'decreasing',
       progressBar: true,
     }
   );
 });

 it('should make error toast if wrong login or password', async () => {
   (mockAuthService.login as jest.Mock).mockRejectedValue(new Error('fail'));

   await component.login({ email: 'fail@test.com', password: 'fail' });

   expect(mockToastrService.error).toHaveBeenCalledWith(
     'Identifiants incorrects. Veuillez réessayer.',
     'Erreur de connexion',
     {
       closeButton: true,
       progressAnimation: 'decreasing',
       progressBar: true,
     }
   );
 });*/
});
