import os
import httpx
import pytest
from conftest import BASE_URL

def _headers():
    uid = os.getenv("SYNC_TEST_USER_ID", "")
    return {"X-User-ID": uid}

def test_user_admin_list_users():
    with httpx.Client(timeout=10.0) as client:
        r = client.get(f"{BASE_URL}/users/admin/users", headers=_headers())
        assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
        users = r.json()
        assert len(users) > 0
        # Verify admin is in the list
        admin_email = os.getenv("SUPER_ADMINS", "axieyangb@gmail.com").split(',')[0].strip()
        assert any(u["email"] == admin_email for u in users)

def test_group_lifecycle():
    group_data = {
        "name": "Test Admin Group",
        "description": "A group for testing admin APIs",
        "policy": {"llm": ["gemini"]}
    }
    
    with httpx.Client(timeout=10.0) as client:
        # 1. Create Group
        r = client.post(f"{BASE_URL}/users/admin/groups", json=group_data, headers=_headers())
        assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
        
        json_data = r.json()
        assert "id" in json_data
        group_id = json_data["id"]
        
        # 2. List Groups
        r = client.get(f"{BASE_URL}/users/admin/groups", headers=_headers())
        assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
        groups = r.json()
        assert any(g["id"] == group_id for g in groups)
        
        # 3. Update Group
        update_data = {
            "description": "Updated description"
        }
        r = client.put(f"{BASE_URL}/users/admin/groups/{group_id}", json=update_data, headers=_headers())
        assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
        assert r.json()["description"] == "Updated description"
        
        # 4. Delete Group
        r = client.delete(f"{BASE_URL}/users/admin/groups/{group_id}", headers=_headers())
        assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
        
        # Verify deleted
        r = client.get(f"{BASE_URL}/users/admin/groups", headers=_headers())
        groups = r.json()
        assert not any(g["id"] == group_id for g in groups)

def test_admin_update_user_group():
    with httpx.Client(timeout=10.0) as client:
        # 1. List users to get a user ID
        r = client.get(f"{BASE_URL}/users/admin/users", headers=_headers())
        assert r.status_code == 200
        users = r.json()
        assert len(users) > 0
        user_id = users[0]["id"] # Use the first user (likely admin)
        
        # 2. Create a test group
        group_data = {
            "name": "Test Assign Group",
            "description": "Testing group assignment",
            "policy": {}
        }
        r = client.post(f"{BASE_URL}/users/admin/groups", json=group_data, headers=_headers())
        assert r.status_code == 200
        group_id = r.json()["id"]
        
        # 3. Assign user to group
        r = client.put(f"{BASE_URL}/users/admin/users/{user_id}/group", json={"group_id": group_id}, headers=_headers())
        assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
        
        # Verify assignment
        r = client.get(f"{BASE_URL}/users/admin/users", headers=_headers())
        users = r.json()
        updated_user = next(u for u in users if u["id"] == user_id)
        assert updated_user["group_name"] == group_data["name"]
        
        # Cleanup group
        client.delete(f"{BASE_URL}/users/admin/groups/{group_id}", headers=_headers())

def test_admin_update_role_last_admin_protection():
    with httpx.Client(timeout=10.0) as client:
        # Get current admin user
        r = client.get(f"{BASE_URL}/users/admin/users", headers=_headers())
        assert r.status_code == 200
        users = r.json()
        
        # Find the admin user
        admin_user = next((u for u in users if u["role"] == "admin"), None)
        assert admin_user is not None
        
        # Try to demote this admin to user
        r = client.put(f"{BASE_URL}/users/admin/users/{admin_user['id']}/role", json={"role": "user"}, headers=_headers())
        
        # Expect 400 Bad Request due to last admin protection
        assert r.status_code == 400, f"Expected 400 Bad Request, got {r.status_code}: {r.text}"
        assert "Maybe this is the last admin?" in r.text or "Failed to update role" in r.text

