from conftest import ADMIN_PASSWORD, DIRECTOR_PASSWORD, OTHER_DIRECTOR_PASSWORD, SCHOOL, OTHER_SCHOOL


async def test_login_wrong_password_401(client):
    r = await client.post("/api/admin/login", json={"password": "not-the-password"})
    assert r.status_code == 401


async def test_login_operator_ok(client):
    r = await client.post("/api/admin/login", json={"password": ADMIN_PASSWORD})
    assert r.status_code == 200
    body = r.json()
    assert body["role"] == "operator"
    assert body["token"]


async def test_login_director_needs_school_and_matching_password(client):
    ok = await client.post("/api/admin/login", json={"password": DIRECTOR_PASSWORD, "school": SCHOOL})
    assert ok.status_code == 200
    assert ok.json()["role"] == "director" and ok.json()["school"] == SCHOOL
    # sans code école
    assert (await client.post("/api/admin/login", json={"password": DIRECTOR_PASSWORD})).status_code == 401
    # mot de passe d'une autre école
    r = await client.post("/api/admin/login", json={"password": OTHER_DIRECTOR_PASSWORD, "school": SCHOOL})
    assert r.status_code == 401
    # école inconnue
    r = await client.post("/api/admin/login", json={"password": DIRECTOR_PASSWORD, "school": "nope"})
    assert r.status_code == 401


async def test_login_brute_force_blocked_after_5_attempts(client):
    statuses = [
        (await client.post("/api/admin/login", json={"password": "wrong"})).status_code
        for _ in range(7)
    ]
    assert statuses[:5] == [401] * 5
    assert 429 in statuses[5:]


async def test_protected_route_requires_token(client):
    assert (await client.get("/api/admin/stats")).status_code == 401


async def test_protected_route_rejects_invalid_token(client):
    r = await client.get("/api/admin/stats", headers={"Authorization": "Bearer not-a-real-token"})
    assert r.status_code == 401


async def test_operator_must_select_a_school(client, admin_token):
    r = await client.get("/api/admin/stats", headers={"Authorization": f"Bearer {admin_token}"})
    assert r.status_code == 400
    r = await client.get("/api/admin/stats", headers={"Authorization": f"Bearer {admin_token}", "X-School": "nope"})
    assert r.status_code == 404


async def test_protected_route_accepts_valid_token(client, admin_headers):
    assert (await client.get("/api/admin/stats", headers=admin_headers)).status_code == 200


async def test_director_cannot_use_operator_routes(client, director_headers):
    assert (await client.get("/api/admin/stats", headers=director_headers)).status_code == 403
    assert (await client.get("/api/admin/schools", headers=director_headers)).status_code == 403
    assert (await client.get("/api/director/dashboard", headers=director_headers)).status_code == 200


async def test_director_is_locked_to_own_school_even_with_header(client, director_headers):
    """Un directeur ne peut pas viser une autre école en forgeant X-School."""
    r = await client.get("/api/admin/settings", headers={**director_headers, "X-School": OTHER_SCHOOL})
    assert r.status_code == 200
    assert r.json()["school"]["id"] == SCHOOL
