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

const { verifyJwtTokenMock, extractAuthTokenMock } = vi.hoisted(() => ({
  verifyJwtTokenMock: vi.fn(),
  extractAuthTokenMock: vi.fn(),
}));

vi.mock('@/lib/jwt', () => ({
  verifyJwtToken: verifyJwtTokenMock,
  extractAuthToken: extractAuthTokenMock,
}));

import { GET } from '../../../../../src/app/api/auth/me/route';

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

  it('returns 401 when no token is provided', async () => {
    const res = await GET(new Request('http://localhost/api/auth/me'));

    expect(res.status).toBe(401);
    expect(await res.json()).toEqual({ message: 'Unauthorized' });
  });

  it('returns 200 when cookie token is valid', async () => {
    verifyJwtTokenMock.mockReturnValue({ sub: 'admin', role: 'admin' });

    const res = await GET(
      new Request('http://localhost/api/auth/me', {
        headers: { cookie: 'auth_token=token-123' },
      }),
    );

    expect(res.status).toBe(200);
    expect(verifyJwtTokenMock).toHaveBeenCalledWith('token-123');
    expect(await res.json()).toEqual({
      message: 'Token valid',
      user: { username: 'admin', role: 'admin' },
    });
  });

  it('returns 200 when authorization token is valid', async () => {
    extractAuthTokenMock.mockReturnValue('token-abc');
    verifyJwtTokenMock.mockReturnValue({ sub: 'user', role: 'viewer' });

    const res = await GET(
      new Request('http://localhost/api/auth/me', {
        headers: { authorization: 'Bearer token-abc' },
      }),
    );

    expect(res.status).toBe(200);
    expect(extractAuthTokenMock).toHaveBeenCalledWith('Bearer token-abc');
    expect(await res.json()).toEqual({
      message: 'Token valid',
      user: { username: 'user', role: 'viewer' },
    });
  });

  it('returns 401 when token verification fails', async () => {
    verifyJwtTokenMock.mockImplementation(() => {
      throw new Error('bad token');
    });

    const res = await GET(
      new Request('http://localhost/api/auth/me', {
        headers: { cookie: 'auth_token=token-123' },
      }),
    );

    expect(res.status).toBe(401);
    expect(await res.json()).toEqual({ message: 'Unauthorized' });
  });
});