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

// Mock next/server
vi.mock('next/server', () => ({
  NextResponse: {
    json: (body, init) => ({
      _body: body,
      status: init?.status || 200,
      json: () => Promise.resolve(body),
    }),
  },
}));

// Mock cookies
const mockGet = vi.fn();
vi.mock('next/headers', () => ({
  cookies: vi.fn(() => Promise.resolve({ get: mockGet })),
}));

// Mock JWT
vi.mock('@/lib/auth/jwt', () => ({
  verifyToken: vi.fn(),
}));

describe('GET /api/auth/me', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('returns authenticated:true with user data when token is valid', async () => {
    const { verifyToken } = await import('@/lib/auth/jwt');
    verifyToken.mockResolvedValue({ userId: 'user-1', username: 'alice', role: 'user' });
    mockGet.mockReturnValue({ value: 'valid-token' });

    const { GET } = await import('./route.js');
    const res = await GET();

    expect(res.status).toBe(200);
    expect(res._body.authenticated).toBe(true);
    expect(res._body.user.username).toBe('alice');
    expect(res._body.user.role).toBe('user');
    expect(res._body.user.id).toBe('user-1');
  });

  it('returns authenticated:false when no token cookie', async () => {
    mockGet.mockReturnValue(undefined);

    const { GET } = await import('./route.js');
    const res = await GET();

    expect(res.status).toBe(200);
    expect(res._body.authenticated).toBe(false);
    expect(res._body.user).toBeNull();
  });

  it('returns authenticated:false when token is invalid', async () => {
    const { verifyToken } = await import('@/lib/auth/jwt');
    verifyToken.mockResolvedValue(null);
    mockGet.mockReturnValue({ value: 'bad-token' });

    const { GET } = await import('./route.js');
    const res = await GET();

    expect(res.status).toBe(200);
    expect(res._body.authenticated).toBe(false);
    expect(res._body.user).toBeNull();
  });

  it('returns authenticated:false when verifyToken throws', async () => {
    const { verifyToken } = await import('@/lib/auth/jwt');
    verifyToken.mockRejectedValue(new Error('JWT expired'));
    mockGet.mockReturnValue({ value: 'expired-token' });

    const { GET } = await import('./route.js');
    const res = await GET();

    expect(res.status).toBe(200);
    expect(res._body.authenticated).toBe(false);
    expect(res._body.user).toBeNull();
  });
});
