import {getSubdivision, getCommunesDeSubdivision, getEvenementsDeSubdivision} from './subdivisionService';
import http from '@/http';

const mockedHttp = http as jest.Mocked<typeof http>;

describe('subdivisionService (spec L156)', () => {
  beforeEach(() => jest.clearAllMocks());

  it('shouldFetchARegionOrADepartment', async () => {
    const finistere = {subId: 29, subNom: 'Finistère', subNiveau: 2, subMere: {subId: 12, subNom: 'Bretagne'}};
    mockedHttp.get.mockResolvedValueOnce({status: 200, data: finistere});

    expect(await getSubdivision('29')).toEqual(finistere);
    expect(mockedHttp.get).toHaveBeenCalledWith('/geolocale_subdivisions/29');
  });

  it('shouldThrowANotFoundErrorForAnUnknownSubdivision', async () => {
    mockedHttp.get.mockRejectedValueOnce({response: {status: 404}});

    await expect(getSubdivision('999')).rejects.toThrow('not found');
  });

  it('shouldListTheCommunesOfADepartmentAlphabeticallyWithTheTotal', async () => {
    mockedHttp.get.mockResolvedValueOnce({status: 200, data: {'hydra:member': [{vilId: 1, vilNom: 'Brest'}], 'hydra:totalItems': 277}});

    const page = await getCommunesDeSubdivision({subId: 29, subNiveau: 2}, 2);

    expect(mockedHttp.get).toHaveBeenCalledWith('/geolocale_villes?vilSub2=29&order%5BvilNom%5D=asc&page=2&itemsPerPage=60');
    expect(page).toEqual({communes: [{vilId: 1, vilNom: 'Brest'}], total: 277, page: 2, itemsPerPage: 60});
  });

  it('shouldListTheCommunesOfARegionThroughTheFirstLevelFilter', async () => {
    mockedHttp.get.mockResolvedValueOnce({status: 200, data: {'hydra:member': [], 'hydra:totalItems': 0}});

    await getCommunesDeSubdivision({subId: 12, subNiveau: 1});

    expect(mockedHttp.get).toHaveBeenCalledWith('/geolocale_villes?vilSub1=12&order%5BvilNom%5D=asc&page=1&itemsPerPage=60');
  });

  it('shouldFetchTheUpcomingEventsOfTheDepartment', async () => {
    jest.useFakeTimers().setSystemTime(new Date('2026-09-21T10:00:00Z'));
    mockedHttp.get.mockResolvedValueOnce({status: 200, data: {'hydra:member': [{eveId: 1}]}});

    expect(await getEvenementsDeSubdivision({subId: 29, subNiveau: 2})).toEqual([{eveId: 1}]);
    expect(mockedHttp.get).toHaveBeenCalledWith('/evenements?page=1&itemsPerPage=4&eveVil.vilSub2=29&eveValide=1&eveDate%5Bafter%5D=2026-09-21');
    jest.useRealTimers();
  });

  it('shouldReturnEmptyResultsWhenTheApiFails', async () => {
    mockedHttp.get.mockRejectedValue(new Error('boom'));

    expect(await getCommunesDeSubdivision({subId: 29, subNiveau: 2})).toEqual({communes: [], total: 0, page: 1, itemsPerPage: 60});
    expect(await getEvenementsDeSubdivision({subId: 29, subNiveau: 2})).toEqual([]);
  });
});
