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

import { UserPasswordFormComponent } from './user-password-form.component';
import { ToastrService } from 'ngx-toastr';
import { AuthFacade } from '../../../adapters/authentification/auth.facade';
import { By } from '@angular/platform-browser';
import { ActionType } from '@app/domain/action-type.util';
import { signal, WritableSignal } from '@angular/core';
import { mockToastR } from '@app/testing/toastr.mock';
import { mockAuthenticationFacade } from '@app/testing/adapters/authentification/auth.facade.mock';

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

  let mockToastrService: jest.Mocked<Partial<ToastrService>> = mockToastR;

  // On mocke la Facade car c'est ce que le composant utilise directement
  let mockAuthFacade: {
    sendRequestPasswordReset: jest.Mock;
    loading: WritableSignal<{ isLoading: boolean; action: ActionType }>;
    error: WritableSignal<{ hasError: boolean }>;
  } = mockAuthenticationFacade;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [UserPasswordFormComponent],
      providers: [
        { provide: ToastrService, useValue: mockToastrService },
        { provide: AuthFacade, useValue: mockAuthFacade }, // On fournit le mock à la place du vrai
      ],
    }).compileComponents();

    fixture = TestBed.createComponent(UserPasswordFormComponent);
    component = fixture.componentInstance;
    // 3. Input obligatoire
    component.user = { email: 'test@example.com' } as any;

    fixture.detectChanges(); // Déclenche le ngOnInit et le premier rendu
  });

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

  // --- TEST DE L'UI (Interaction utilisateur) ---
  it('should call sendRequestPasswordReset when the submit button is clicked', () => {
    // Simulation du clic
    const button = fixture.debugElement.query(By.css('button'));
    button.nativeElement.click();

    // Vérification
    expect(mockAuthFacade.sendRequestPasswordReset).toHaveBeenCalledWith('test@example.com');
  });

  // --- TEST DE L'UI (État de chargement) ---
  it('should show loading spinner when loading action is CREATE', () => {
    // Mise à jour du signal
    mockAuthFacade.loading.set({ isLoading: true, action: ActionType.CREATE });
    fixture.detectChanges(); // Mise à jour du DOM

    const loadingComponent = fixture.debugElement.query(By.css('app-loading'));
    expect(loadingComponent).toBeTruthy(); // Le composant de loading doit être là
  });

  // --- TEST DE LOGIQUE (Effect & Toast) ---
  it('should show success toast when action finishes successfully', () => {
    // 1. On simule la fin du chargement (isLoading: false) avec l'action CREATE
    mockAuthFacade.loading.set({ isLoading: false, action: ActionType.CREATE });
    mockAuthFacade.error.set({ hasError: false });

    // Nécessaire pour déclencher l'effect()
    fixture.detectChanges();

    expect(mockToastrService.success).toHaveBeenCalledWith(
      expect.stringContaining('test@example.com'),
      'Mise à jour',
      expect.anything()
    );
  });
});
