import { provideHttpClient } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { ApiConfigService } from '../core/config/api-config.service';
import { LocalStorageService } from '../core/storage/local-storage.service';
import { LocationService } from './location.service';

/**
 * FH-1.1. detectLocation() used to call http://ip-api.com directly. On an
 * HTTPS storefront the browser blocks mixed active content, so the request
 * never completed and region auto-detect silently did nothing in production
 * - and the attempt still exposed the visitor's IP to a third party.
 *
 * These tests pin both halves of the fix: geo resolution goes to our own
 * tenant API, and nothing in this service reaches a foreign origin.
 */
describe('LocationService', () => {
  const baseUrl = 'https://api.gorbushka.market';
  let service: LocationService;
  let httpTesting: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        LocationService,
        provideHttpClient(),
        provideHttpClientTesting(),
        { provide: ApiConfigService, useValue: { getBaseUrl: () => baseUrl } },
        {
          provide: LocalStorageService,
          useValue: { getJSON: () => null, setJSON: () => {}, removeItem: () => {} },
        },
      ],
    });

    service = TestBed.inject(LocationService);
    httpTesting = TestBed.inject(HttpTestingController);
    // The constructor loads regions; flush it so each test starts clean.
    httpTesting.expectOne(`${baseUrl}/regions`).flush([]);
  });

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

  it('resolves geo through the tenant API, not a third-party host', () => {
    service.detectLocation();

    const request = httpTesting.expectOne(`${baseUrl}/geo/resolve`);
    expect(request.request.method).toBe('GET');
    request.flush({ city: 'Москва', country: 'Россия', countryCode: 'RU' });
  });

  it('issues no request to a foreign or plaintext origin', () => {
    service.detectLocation();

    for (const request of httpTesting.match(() => true)) {
      expect(request.request.url.startsWith(baseUrl))
        .withContext(`unexpected off-origin request: ${request.request.url}`)
        .toBe(true);
      expect(request.request.url.startsWith('http://'))
        .withContext(`plaintext request: ${request.request.url}`)
        .toBe(false);
      request.flush({});
    }
  });

  it('degrades to the manual picker when geo resolution fails', () => {
    service.detectLocation();
    httpTesting
      .expectOne(`${baseUrl}/geo/resolve`)
      .flush(null, { status: 503, statusText: 'Service Unavailable' });

    expect(service.region()).toBeNull();
    expect(service.detecting()).toBe(false);
    expect(service.autoDetected()).toBe(true);
  });

  it('does not re-request geo once detection has been attempted', () => {
    service.detectLocation();
    httpTesting.expectOne(`${baseUrl}/geo/resolve`).flush({
      city: 'Ереван',
      country: 'Армения',
      countryCode: 'AM',
    });

    service.detectLocation();

    httpTesting.expectNone(`${baseUrl}/geo/resolve`);
  });
});
