import { HttpClient, HttpErrorResponse, provideHttpClient, withInterceptors } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import {
  HttpProblemDetailsError,
  problemDetailsInterceptor,
} from './problem-details.interceptor';

describe('problemDetailsInterceptor', () => {
  let http: HttpClient;
  let controller: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        provideHttpClient(withInterceptors([problemDetailsInterceptor])),
        provideHttpClientTesting(),
      ],
    });
    http = TestBed.inject(HttpClient);
    controller = TestBed.inject(HttpTestingController);
  });

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

  it('normalizes a problem-details response and retains the original HTTP error', () => {
    let capturedError: unknown;
    http.get('/api/payments').subscribe({
      error: (error: unknown) => capturedError = error,
    });

    controller.expectOne('/api/payments').flush(
      { title: 'Payment rejected', detail: 'Insufficient balance', status: 422 },
      { status: 422, statusText: 'Unprocessable Entity' }
    );

    expect(capturedError).toBeInstanceOf(HttpProblemDetailsError);
    const problemError = capturedError as HttpProblemDetailsError;
    expect(problemError.problem.title).toBe('Payment rejected');
    expect(problemError.originalError).toBeInstanceOf(HttpErrorResponse);
    expect(problemError.originalError.status).toBe(422);
  });

  it('rethrows non-problem errors unchanged', () => {
    let capturedError: unknown;
    http.get('/api/payments').subscribe({
      error: (error: unknown) => capturedError = error,
    });

    controller.expectOne('/api/payments').flush('Server error', {
      status: 500,
      statusText: 'Server Error',
    });

    expect(capturedError).toBeInstanceOf(HttpErrorResponse);
    expect(capturedError).not.toBeInstanceOf(HttpProblemDetailsError);
  });
});
