// tests/unit/routes/diplomes.route.spec.ts
import { beforeEach, describe, expect, it, vi } from 'vitest';

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

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

vi.mock('../../../../src/server/diplomes.server', () => ({
  getDiplomesFeed: getDiplomesFeedMock,
  createDiplomeFeed: createDiplomeFeedMock,
}));

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

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

  it('GET returns 200 and default pagination values', async () => {
    getDiplomesFeedMock.mockResolvedValue({
      items: [{ id: 1, diplome: 'Alice' }],
      count: 1,
    });

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

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

    const body = await res.json();
    expect(body).toEqual({
      message: 'Diplomes retrieved successfully',
      items: [{ id: 1, diplome: 'Alice' }],
      count: 1,
    });
  });

  it('GET returns 400 when query params are invalid', async () => {
    const res = await GET(new Request('http://localhost/api/diplomes?limit=0&offset=-1'));

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

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

  it('GET returns auth error when request is unauthorized', async () => {
    requireAuthMock.mockReturnValue(new Response('Unauthorized', { status: 401 }));

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

    expect(res.status).toBe(401);
    expect(getDiplomesFeedMock).not.toHaveBeenCalled();
  });

  it('POST returns 201 when body is valid', async () => {
    const dateobtentionIso = '2026-05-26T00:00:00.000Z';

    createDiplomeFeedMock.mockResolvedValue({
      diplome: { id_salarie: 1, diplome: 'Master', dateobtention: dateobtentionIso },
    });

    const res = await POST(
      new Request('http://localhost/api/diplomes', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ id_salarie: 1, diplome: 'Master', dateobtention: dateobtentionIso }),
      }),
    );

    expect(res.status).toBe(201);
    expect(createDiplomeFeedMock).toHaveBeenCalledWith(
      expect.objectContaining({
        id_salarie: 1,
        diplome: 'Master',
        dateobtention: new Date(dateobtentionIso),
      }),
    );

    const body = await res.json();
    expect(body).toEqual({
      message: 'Diplome created successfully',
      diplome: { id_salarie: 1, diplome: 'Master', dateobtention: dateobtentionIso },
    });
  });

  it('POST returns 400 when JSON is malformed', async () => {
    const res = await POST(
      new Request('http://localhost/api/diplomes', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: '{"id": 1',
      }),
    );

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

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

  it('POST returns 400 when body validation fails', async () => {
    const res = await POST(
      new Request('http://localhost/api/diplomes', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ diplome: 'Missing id' }),
      }),
    );

    expect(res.status).toBe(400);
    expect(createDiplomeFeedMock).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/diplomes'));

    expect(res.status).toBe(401);
    expect(getDiplomesFeedMock).not.toHaveBeenCalled();
  });
});