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

/**
 * Tests du composable d'upload générique (ERP-171) :
 *  - succès : POST multipart /uploaded_documents (champ « file »), toast désactivé,
 *    renvoie l'IRI (@id) du document créé, `uploading` retombe à false ;
 *  - erreur MIME hors whitelist → 422 : l'erreur est RELAYÉE à l'appelant (pour un
 *    affichage inline sous le champ), `uploading` ré-armé via le finally.
 */

const mockPost = vi.hoisted(() => vi.fn())

vi.stubGlobal('useApi', () => ({
    get: vi.fn(),
    post: mockPost,
    put: vi.fn(),
    patch: vi.fn(),
    delete: vi.fn(),
}))

const { useUpload } = await import('../useUpload')

describe('useUpload', () => {
    beforeEach(() => {
        mockPost.mockReset()
    })

    it('succès : POST multipart champ « file » + toast:false → renvoie l\'IRI', async () => {
        mockPost.mockResolvedValue({ '@id': '/api/uploaded_documents/9', originalFilename: 'decharge.pdf' })
        const { upload, uploading } = useUpload()
        const file = new File(['contenu'], 'decharge.pdf', { type: 'application/pdf' })

        const iri = await upload(file)

        expect(iri).toBe('/api/uploaded_documents/9')

        const [url, body, options] = mockPost.mock.calls[0]
        expect(url).toBe('/uploaded_documents')
        expect(body).toBeInstanceOf(FormData)
        const stored = (body as FormData).get('file')
        expect(stored).toBeInstanceOf(File)
        expect((stored as File).name).toBe('decharge.pdf')
        expect(options).toMatchObject({ toast: false })

        expect(uploading.value).toBe(false)
    })

    it('erreur MIME → 422 : l\'erreur est remontée à l\'appelant', async () => {
        const error = Object.assign(new Error('422'), {
            data: { 'hydra:description': 'Type de fichier non autorisé.' },
        })
        mockPost.mockRejectedValue(error)
        const { upload, uploading } = useUpload()
        const file = new File(['x'], 'malware.exe', { type: 'application/x-msdownload' })

        await expect(upload(file)).rejects.toBe(error)
        expect(uploading.value).toBe(false)
    })
})
