"""Members + RBAC enforcement on member management."""

from __future__ import annotations


def test_owner_can_invite_member(client, helpers):
    ctx = helpers.bootstrap_owner(client)
    member = helpers.add_member(
        client, ctx["access_token"], email="builder@example.com", role="builder"
    )
    assert member["membership"]["role"] == "builder"
    assert member["membership"]["email"] == "builder@example.com"


def test_members_list_visible_to_any_role(client, helpers):
    ctx = helpers.bootstrap_owner(client)
    viewer = helpers.add_member(
        client, ctx["access_token"], email="viewer@example.com", role="viewer"
    )
    resp = client.get("/members", headers=helpers.headers(viewer["access_token"]))
    assert resp.status_code == 200
    emails = {m["email"] for m in resp.json()}
    assert {"owner@example.com", "viewer@example.com"} <= emails


def test_builder_cannot_invite_members(client, helpers):
    ctx = helpers.bootstrap_owner(client)
    builder = helpers.add_member(
        client, ctx["access_token"], email="builder@example.com", role="builder"
    )
    resp = client.post(
        "/members/invite",
        json={"email": "intruder@example.com", "role": "viewer"},
        headers=helpers.headers(builder["access_token"]),
    )
    assert resp.status_code == 403


def test_admin_can_invite_members(client, helpers):
    ctx = helpers.bootstrap_owner(client)
    admin = helpers.add_member(client, ctx["access_token"], email="admin@example.com", role="admin")
    resp = client.post(
        "/members/invite",
        json={"email": "newbie@example.com", "role": "viewer"},
        headers=helpers.headers(admin["access_token"]),
    )
    assert resp.status_code == 201


def test_update_member_role(client, helpers):
    ctx = helpers.bootstrap_owner(client)
    member = helpers.add_member(client, ctx["access_token"], email="op@example.com", role="viewer")
    membership_id = member["membership"]["id"]
    resp = client.patch(
        f"/members/{membership_id}/role",
        json={"role": "operator"},
        headers=helpers.headers(ctx["access_token"]),
    )
    assert resp.status_code == 200
    assert resp.json()["role"] == "operator"


def test_cannot_demote_last_owner(client, helpers):
    ctx = helpers.bootstrap_owner(client)
    members = client.get("/members", headers=helpers.headers(ctx["access_token"])).json()
    owner_membership = next(m for m in members if m["email"] == "owner@example.com")
    resp = client.patch(
        f"/members/{owner_membership['id']}/role",
        json={"role": "viewer"},
        headers=helpers.headers(ctx["access_token"]),
    )
    assert resp.status_code == 400


def test_duplicate_invite_conflicts(client, helpers):
    ctx = helpers.bootstrap_owner(client)
    helpers.add_member(client, ctx["access_token"], email="dup@example.com", role="viewer")
    resp = client.post(
        "/members/invite",
        json={"email": "dup@example.com", "role": "admin"},
        headers=helpers.headers(ctx["access_token"]),
    )
    assert resp.status_code == 409
