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

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

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

vi.mock('@/services/reference-lookups.service', () => ({
  listEtablissements: listTypeEtablissementMock,
  createEtablissement: createTypesEtablissementMock,
}));

import { GET, POST } from '../../../../src/app/api/etablissements/route';

describe('Unit — /api/types-etablissement route', () => {
  beforeEach(() => {
    vi.resetAllMocks();
    requireAuthMock.mockReturnValue(null);
  });

  it('GET returns the paginated types etablissementlist', async () => {
    listTypeEtablissementMock.mockResolvedValue([
      {
        id: 1,
        typeetablissement: 'etablissementautorisee',
        libetablissement: 'AA',
        date_creation: '2026-05-21T08:16:08.000Z',
      },
    ]);

    const res = await GET(new Request('http://localhost/api/types-etablissement'));

    expect(res.status).toBe(200);
    expect(listTypeEtablissementMock).toHaveBeenCalledWith(20, 0);

    const body = await res.json();
    expect(body).toEqual({
      message: 'Etablissements retrieved successfully',
      items: [
        {
          id: 1,
          typeetablissement: 'etablissementautorisee',
          libetablissement: 'AA',
          date_creation: '2026-05-21T08:16:08.000Z',
        },
      ],
      count: 1,
    });
  });

  it('GET returns 400 for invalid query parameters', async () => {
    const res = await GET(new Request('http://localhost/api/types-etablissement?limit=abc'));

    expect(res.status).toBe(400);
    expect(listTypeEtablissementMock).not.toHaveBeenCalled();

    const body = await res.json();
    expect(body.message).toBe('Invalid query parameters');
  });

  it('POST creates a TypeEtablissement', async () => {
    createTypesEtablissementMock.mockResolvedValue({
      id: 1,
      etb: "Etablissement",
      entreprise: "Ici",
      directeur: "moi",
      adressesiege: "pas loin",
      adresseetb:"loin"
    });

    const res = await POST(
      new Request('http://localhost/api/types-etablissement', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({
          etb: "Etablissement",
      entreprise: "Ici",
      directeur: "moi",
      adressesiege: "pas loin",
      adresseetb:"loin"
        }),
      }),
    );

    expect(res.status).toBe(201);
    expect(createTypesEtablissementMock).toHaveBeenCalledWith({
      etb: "Etablissement",
      entreprise: "Ici",
      directeur: "moi",
      adressesiege: "pas loin",
      adresseetb:"loin"
    });

    const body = await res.json();
    expect(body).toEqual({
      message: 'Etablissement created successfully',
      etablissement: {
        id: 1,
        etb: "Etablissement",
      entreprise: "Ici",
      directeur: "moi",
      adressesiege: "pas loin",
      adresseetb:"loin"
      },
    });
  });

  it('POST returns 400 for invalid JSON', async () => {
    const res = await POST(
      new Request('http://localhost/api/types-etablissement', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: '{"TypeEtablissement": "etablissementautorisee"',
      }),
    );

    expect(res.status).toBe(400);
    expect(createTypesEtablissementMock).not.toHaveBeenCalled();

    const body = await res.json();
    expect(body.message).toBe('Invalid JSON body');
  });

  it('POST returns 400 for invalid body', async () => {
    const res = await POST(
      new Request('http://localhost/api/types-etablissement', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ libetablissement: 'Missing TypeEtablissement' }),
      }),
    );

    expect(res.status).toBe(400);
    expect(createTypesEtablissementMock).not.toHaveBeenCalled();

    const body = await res.json();
    expect(body.message).toBe('Invalid body parameters');
  });
  it('Post returns auth error when request is unauthorized', async () => {
      requireAuthMock.mockReturnValue(new Response('Unauthorized', { status: 401 }));
  
      const res = await POST(new Request('http://localhost/api/type-etablissement'));
  
      expect(res.status).toBe(401);
      expect(createTypesEtablissementMock).not.toHaveBeenCalled();
    });
});