/**
 * Tests for GET/POST /api/flags
 */

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

const mockRequireAdmin = vi.fn();
vi.mock('@/lib/auth-server', () => ({
  requireAdmin: (...args: unknown[]) => mockRequireAdmin(...args),
  getCurrentUser: (...args: unknown[]) => mockRequireAdmin(...args),
  getCurrentUserFromRequest: (...args: unknown[]) => mockRequireAdmin(...args),
}));

const mockListFlags = vi.fn();
const mockCreateFlag = vi.fn();
vi.mock('@/lib/platform-client', () => ({
  listFlags: (...args: unknown[]) => mockListFlags(...args),
  createFlag: (...args: unknown[]) => mockCreateFlag(...args),
}));

import { GET, POST } from '@/app/api/flags/route';

async function makeGet() {
  const { NextRequest } = await import('next/server');
  return GET(new NextRequest(new Request('http://localhost:3001/api/flags')));
}

async function makePost(body: object) {
  const { NextRequest } = await import('next/server');
  return POST(
    new NextRequest(
      new Request('http://localhost:3001/api/flags', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      })
    )
  );
}

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

  it('returns 401 when not admin', async () => {
    mockRequireAdmin.mockResolvedValue(null);
    const res = await makeGet();
    expect(res.status).toBe(401);
  });

  it('returns flags list on success', async () => {
    mockRequireAdmin.mockResolvedValue({ id: 'admin1', role: 'admin' });
    mockListFlags.mockResolvedValue({ flags: [{ key: 'dark_mode', enabled: true }] });

    const res = await makeGet();
    expect(res.status).toBe(200);
    const data = await res.json();
    expect(data.flags).toHaveLength(1);
    expect(data.flags[0].key).toBe('dark_mode');
  });

  it('returns 500 on error', async () => {
    mockRequireAdmin.mockResolvedValue({ id: 'admin1' });
    mockListFlags.mockRejectedValue(new Error('Service unavailable'));

    const res = await makeGet();
    expect(res.status).toBe(500);
  });
});

describe('POST /api/flags', () => {
  beforeEach(() => vi.clearAllMocks());

  it('returns 401 when not admin', async () => {
    mockRequireAdmin.mockResolvedValue(null);
    const res = await makePost({ key: 'new_flag' });
    expect(res.status).toBe(401);
  });

  it('creates flag and returns 201', async () => {
    mockRequireAdmin.mockResolvedValue({ id: 'admin1' });
    mockCreateFlag.mockResolvedValue({ key: 'new_flag', enabled: true, id: 'f1' });

    const res = await makePost({ key: 'new_flag', enabled: true });
    expect(res.status).toBe(201);
    const data = await res.json();
    expect(data.key).toBe('new_flag');
  });

  it('returns 500 on error', async () => {
    mockRequireAdmin.mockResolvedValue({ id: 'admin1' });
    mockCreateFlag.mockRejectedValue(new Error('Conflict'));

    const res = await makePost({ key: 'dup' });
    expect(res.status).toBe(500);
  });
});
