import { describe, it, expect, vi, beforeEach } from 'vitest'
import { useCarriersRepository, type Carrier } from '../useCarriersRepository'

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

/**
 * Tests du repertoire transporteurs (ERP-164).
 *
 * `useCarriersRepository` est une fine enveloppe de `usePaginatedList<Carrier>`
 * sur `/carriers`. 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 `/carriers` ;
 *  - 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 « Voir les archivés » est bien transmis une fois
 *    applique (aligne sur Client / Fournisseur / Prestataire).
 */
describe('useCarriersRepository', () => {
    beforeEach(() => {
        mockApiGet.mockReset()
    })

    /** Une page de transporteurs Hydra, avec qualimatCarrier embarque (RG-4.04). */
    const PAGE: Carrier[] = [
        {
            id: 1,
            name: 'TRANSPORTS ACME',
            certificationType: 'QUALIMAT',
            qualimatCarrier: {
                id: '42',
                name: 'TRANSPORTS ACME',
                validityDate: '2027-01-15',
                status: 'VALIDE',
            },
            updatedAt: '2026-06-15T08:12:01+02:00',
            isArchived: false,
        },
    ]

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

        await repo.fetch()

        expect(mockApiGet).toHaveBeenCalledTimes(1)
        const [url, query, opts] = mockApiGet.mock.calls[0]
        expect(url).toBe('/carriers')
        expect(query).toMatchObject({ page: 1, itemsPerPage: 10 })
        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 = useCarriersRepository()

        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 = useCarriersRepository()
        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)
    })

    it('transmet les certifications multiples + la recherche', async () => {
        mockApiGet.mockResolvedValueOnce({ member: PAGE, totalItems: 1 })
        const repo = useCarriersRepository()
        await repo.fetch()

        mockApiGet.mockResolvedValueOnce({ member: PAGE, totalItems: 1 })
        await repo.setFilters({ search: 'acme', 'certificationType[]': ['QUALIMAT', 'AUTRE'] })

        const query = mockApiGet.mock.calls.at(-1)?.[1] as Record<string, unknown>
        expect(query.search).toBe('acme')
        expect(query['certificationType[]']).toEqual(['QUALIMAT', 'AUTRE'])
    })
})
