import { describe, it, expect, vi, beforeEach } from 'vitest'
import { useProvidersRepository, type Provider } from '../useProvidersRepository'

const mockApiGet = vi.hoisted(() => vi.fn())
vi.stubGlobal('useApi', () => ({ get: mockApiGet }))

/**
 * Tests du repertoire prestataires (ERP-140).
 *
 * `useProvidersRepository` est une fine enveloppe de `usePaginatedList<Provider>`
 * sur `/providers`. Les invariants generiques de pagination sont deja couverts
 * par `usePaginatedList.test.ts` ; on verifie ici le CONTRAT propre au repertoire :
 *  - la ressource ciblee est bien `/providers`
 *  - l'enveloppe Hydra (member / totalItems) est consommee
 *  - le header `Accept: application/ld+json` est envoye (sinon API Platform 4
 *    renvoie un tableau plat sans pagination)
 *  - EXCLUSION DES ARCHIVES PAR DEFAUT : aucun `archivedOnly` n'est envoye
 *    tant que l'utilisateur ne coche pas le filtre (le back masque alors les
 *    archives) ; le filtre `archivedOnly` est bien transmis une fois applique.
 */
describe('useProvidersRepository', () => {
    beforeEach(() => {
        mockApiGet.mockReset()
    })

    /** Une page de prestataires Hydra, avec categories[] et sites[] embarques. */
    const PAGE: Provider[] = [
        {
            id: 1,
            companyName: 'ACME MAINTENANCE',
            categories: [{ code: 'MAINTENANCE_INDUSTRIELLE', name: 'Maintenance industrielle' }],
            sites: [{ id: 4, name: 'Chatellerault', color: '#056CF2' }],
            updatedAt: '2026-06-15T08:12:01+02:00',
            isArchived: false,
        },
    ]

    it('cible /providers, consomme l\'enveloppe Hydra et envoie l\'Accept ld+json', async () => {
        mockApiGet.mockResolvedValueOnce({ member: PAGE, totalItems: 1 })
        const repo = useProvidersRepository()

        await repo.fetch()

        expect(mockApiGet).toHaveBeenCalledTimes(1)
        const [url, query, opts] = mockApiGet.mock.calls[0]
        expect(url).toBe('/providers')
        expect(query).toMatchObject({ page: 1, itemsPerPage: 25 })
        expect(opts).toMatchObject({
            toast: false,
            headers: { Accept: 'application/ld+json' },
        })
        expect(repo.items.value).toEqual(PAGE)
        expect(repo.totalItems.value).toBe(1)
    })

    it('exclut les archives par defaut : aucun archivedOnly au premier fetch', async () => {
        mockApiGet.mockResolvedValueOnce({ member: PAGE, totalItems: 1 })
        const repo = useProvidersRepository()

        await repo.fetch()

        const query = mockApiGet.mock.calls[0][1] as Record<string, unknown>
        expect(query.archivedOnly).toBeUndefined()
    })

    it('transmet archivedOnly une fois le filtre applique (retour page 1)', async () => {
        mockApiGet.mockResolvedValueOnce({ member: PAGE, totalItems: 1 })
        const repo = useProvidersRepository()
        await repo.fetch()

        mockApiGet.mockResolvedValueOnce({ member: PAGE, totalItems: 1 })
        await repo.setFilters({ archivedOnly: true })

        expect(repo.currentPage.value).toBe(1)
        const query = mockApiGet.mock.calls.at(-1)?.[1] as Record<string, unknown>
        expect(query.archivedOnly).toBe(true)
    })
})
