import { TestBed } from '@angular/core/testing';
import { provideHttpClient } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { ActivatedRoute, convertToParamMap, provideRouter } from '@angular/router';
import { ConfirmEmail } from './confirm-email';
import { environment } from '../../../../environments/environment';

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

  function setup(hash: string | null) {
    return TestBed.configureTestingModule({
      imports: [ConfirmEmail],
      providers: [
        provideHttpClient(),
        provideHttpClientTesting(),
        provideRouter([]),
        {
          provide: ActivatedRoute,
          useValue: { snapshot: { paramMap: convertToParamMap(hash ? { hash } : {}) } },
        },
      ],
    }).compileComponents();
  }

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

  it('confirms the route hash and shows the success state', async () => {
    await setup('confirm-hash');
    httpMock = TestBed.inject(HttpTestingController);
    const fixture = TestBed.createComponent(ConfirmEmail);
    fixture.detectChanges();

    expect(fixture.componentInstance['confirming']()).toBe(true);

    const request = httpMock.expectOne(`${environment.apiUrl}auth/email/confirm`);
    expect(request.request.body).toEqual({ hash: 'confirm-hash' });
    request.flush(null);

    expect(fixture.componentInstance['confirming']()).toBe(false);
    expect(fixture.componentInstance['errorMessage']()).toBeNull();
  });

  it('shows an error state when the hash is invalid or expired', async () => {
    await setup('bad-hash');
    httpMock = TestBed.inject(HttpTestingController);
    const fixture = TestBed.createComponent(ConfirmEmail);
    fixture.detectChanges();

    const request = httpMock.expectOne(`${environment.apiUrl}auth/email/confirm`);
    request.flush(null, { status: 404, statusText: 'Not Found' });

    expect(fixture.componentInstance['confirming']()).toBe(false);
    expect(fixture.componentInstance['errorMessage']()).toBe(
      'Der Bestätigungslink ist ungültig oder abgelaufen.',
    );
  });

  it('shows an error state without making a request when the hash is missing', async () => {
    await setup(null);
    httpMock = TestBed.inject(HttpTestingController);
    const fixture = TestBed.createComponent(ConfirmEmail);
    fixture.detectChanges();

    httpMock.expectNone(`${environment.apiUrl}auth/email/confirm`);
    expect(fixture.componentInstance['confirming']()).toBe(false);
    expect(fixture.componentInstance['errorMessage']()).toBe('Der Bestätigungslink ist unvollständig.');
  });
});
