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

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

/**
 * Tests de l'invariant "loadSidebar ne reject jamais".
 *
 * Garantie utilisee par le middleware auth.global.ts qui fait un
 * Promise.all([loadSidebar(), loadModules()]) — si l'un throw, le
 * middleware echoue et toute l'app avec. Le swallow interne est donc
 * load-bearing et ce test le verrouille.
 */
describe('useSidebar', () => {
    beforeEach(() => {
        mockApiGet.mockReset()
        const { resetSidebar } = useSidebar()
        resetSidebar()
    })

    it('charge sections et disabledRoutes depuis /api/sidebar', async () => {
        mockApiGet.mockResolvedValueOnce({
            sections: [{ label: 's', icon: 'i', items: [] }],
            disabledRoutes: ['/foo'],
        })
        const { loadSidebar, sections, disabledRoutes, loaded } = useSidebar()

        await loadSidebar()

        expect(sections.value).toHaveLength(1)
        expect(disabledRoutes.value).toEqual(['/foo'])
        expect(loaded.value).toBe(true)
    })

    it('swallow les erreurs reseau sans rejeter (invariant middleware)', async () => {
        mockApiGet.mockRejectedValueOnce(new Error('boom'))
        const { loadSidebar, sections, disabledRoutes, loaded } = useSidebar()

        // Assertion principale : la promise resout normalement meme sur erreur.
        await expect(loadSidebar()).resolves.toBeUndefined()
        expect(sections.value).toEqual([])
        expect(disabledRoutes.value).toEqual([])
        expect(loaded.value).toBe(true)
    })

    it('isRouteDisabled matche exactement un chemin', async () => {
        mockApiGet.mockResolvedValueOnce({ sections: [], disabledRoutes: ['/foo'] })
        const { loadSidebar, isRouteDisabled } = useSidebar()
        await loadSidebar()

        expect(isRouteDisabled('/foo')).toBe(true)
        expect(isRouteDisabled('/foo/bar')).toBe(true)
        expect(isRouteDisabled('/other')).toBe(false)
    })

    it('resetSidebar vide l\'etat', async () => {
        mockApiGet.mockResolvedValueOnce({
            sections: [{ label: 's', icon: 'i', items: [] }],
            disabledRoutes: ['/foo'],
        })
        const { loadSidebar, resetSidebar, sections, loaded } = useSidebar()
        await loadSidebar()
        expect(loaded.value).toBe(true)

        resetSidebar()

        expect(sections.value).toEqual([])
        expect(loaded.value).toBe(false)
    })
})
