import { describe, it, expect, vi, beforeEach } from 'vitest'

// `useApi` est un auto-import Nuxt : on le stubbe globalement pour intercepter
// les appels de chargement des referentiels et simuler un endpoint en echec
// (ex: 403 sur /categories pour un role sans la permission de lecture).
// Meme pattern que useClientsRepository.spec.ts.
const mockGet = vi.hoisted(() => vi.fn())
vi.stubGlobal('useApi', () => ({
    get: mockGet,
    post: vi.fn(),
    put: vi.fn(),
    patch: vi.fn(),
    delete: vi.fn(),
}))

// Import APRES le stub pour que useApi soit bien resolu au top-level du module.
const { useClientReferentials } = await import('../useClientReferentials')

describe('useClientReferentials.loadCommon (resilience ERP-102)', () => {
    beforeEach(() => {
        mockGet.mockReset()
    })

    it('un referentiel en echec (403) ne vide QUE son select, pas les autres', async () => {
        // /categories rejette (simulateur d'un 403), tous les autres repondent.
        mockGet.mockImplementation((url: string) => {
            if (url === '/categories') {
                return Promise.reject(new Error('403 Forbidden'))
            }
            if (url === '/sites') {
                return Promise.resolve({ member: [{ '@id': '/api/sites/1', name: 'Chatellerault', postalCode: '86100' }] })
            }
            if (url === '/countries') {
                // Pays : value === label === name (l'adresse stocke le nom).
                return Promise.resolve({ member: [{ '@id': '/api/countries/1', code: 'FR', name: 'France' }] })
            }
            return Promise.resolve({
                member: [{ '@id': '/api/x/1', code: 'X', label: 'Libelle X' }],
            })
        })

        const refs = useClientReferentials()
        // loadCommon ne doit JAMAIS rejeter : l'echec d'un referentiel est isole.
        await refs.loadCommon()

        // Resilience : les referentiels OK sont peuples malgre l'echec de /categories.
        // Le libelle d'un site est son numero de departement (2 premiers chiffres du code postal).
        expect(refs.sites.value).toEqual([{ value: '/api/sites/1', label: '86' }])
        expect(refs.tvaModes.value).toEqual([{ value: '/api/x/1', label: 'Libelle X' }])
        expect(refs.banks.value).toEqual([{ value: '/api/x/1', label: 'Libelle X' }])
        // Pays : value = nom du pays (et non l'IRI).
        expect(refs.countries.value).toEqual([{ value: 'France', label: 'France' }])

        // Seul le select en echec reste vide.
        expect(refs.categories.value).toEqual([])
    })

    it('charge tous les referentiels quand tout repond', async () => {
        mockGet.mockImplementation((url: string) => {
            if (url === '/categories') {
                return Promise.resolve({
                    member: [{ '@id': '/api/categories/1', code: 'SECTEUR', name: 'Secteur' }],
                })
            }
            if (url === '/sites') {
                return Promise.resolve({ member: [{ '@id': '/api/sites/1', name: 'Chatellerault', postalCode: '86100' }] })
            }
            return Promise.resolve({ member: [] })
        })

        const refs = useClientReferentials()
        await refs.loadCommon()

        expect(refs.categories.value).toEqual([
            { value: '/api/categories/1', label: 'Secteur', code: 'SECTEUR' },
        ])
        // Le libelle d'un site est son numero de departement (2 premiers chiffres du code postal).
        expect(refs.sites.value).toEqual([{ value: '/api/sites/1', label: '86' }])
    })
})
