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

const { requireAuthMock ,getAvenantsByContratIdFeedMock } = vi.hoisted(() => ({
    requireAuthMock: vi.fn(),
    getAvenantsByContratIdFeedMock: vi.fn(),
}));

vi.mock('../../../../src/lib/requireAuth', () => ({
    requireAuth: requireAuthMock,
}));

vi.mock('../../../../src/server/avenants.server', () => ({
    getAvenantsByContratIdFeed: getAvenantsByContratIdFeedMock
}));

import { GET } from '../../../../src/app/api/contrats/[id]/avenants/route';

const makeCtx = <T extends (...args: any[]) => any>(fn: T, params: Record<string, string>) => ({ params: Promise.resolve(params) } as unknown as Parameters<T>[1]);

describe('Unit — /api/avenants/[id] route', () => {
    beforeEach(() => {
        vi.resetAllMocks();
        requireAuthMock.mockReturnValue(null);
    });

    it('GET returns 200 when avenant exists', async () => {
            getAvenantsByContratIdFeedMock.mockResolvedValue({
                contrat: { id: 123 },
                items: [
                    { id: 1, id_avenant: 4, id_contrat: 123, avenant_type: 'Changement de poste + Classification' },
                    { id: 2, id_avenant: 5, id_contrat: 123, avenant_type: 'Changement de poste + Classification' },
                ],
                count: 2,
            });

        const res = await GET(new Request('http://localhost/api/contrats/123/avenants'), makeCtx(GET, { id: '123' }));

        expect(res.status).toBe(200);
        const body = await res.json();
        expect(body).toEqual({
            message: 'Avenants by contrat retrieved successfully',
            items: [
                { id: 1, id_avenant: 4, id_contrat: 123, avenant_type: 'Changement de poste + Classification' },
                { id: 2, id_avenant: 5, id_contrat: 123, avenant_type: 'Changement de poste + Classification' },
            ],
            count: 2,
        });
    });

    it('GET returns 400 when id param is invalid', async () => {
        const res = await GET(new Request('http://localhost/api/contrats/abc/avenants'), makeCtx(GET, { id: 'abc' }));

        expect(res.status).toBe(400);
        const body = await res.json();
        expect(body.message).toBe('Invalid ID parameter');
    });
    it('GET returns auth error when request is unauthorized', async () => {
        // simulate requireAuth returning an HTTP 401 Response
        requireAuthMock.mockReturnValue(new Response('Unauthorized', { status: 401 }));

        const res = await GET(new Request('http://localhost/api/contrats/1/avenants'), makeCtx(GET, { id: '1' }));

        expect(res.status).toBe(401);
        expect(getAvenantsByContratIdFeedMock).not.toHaveBeenCalled();
    });
    it('GET returns 404 when not found', async () => {
        getAvenantsByContratIdFeedMock.mockResolvedValue({ contrat: null });

        const res = await GET(new Request('http://localhost/api/contrats/999/avenants'), makeCtx(GET, { id: '999' }));

        expect(res.status).toBe(404);
        const body = await res.json();
        expect(body.message).toBe('Contrat not found');
    });


});
