mod compat;

use compat::helpers::*;
use serde_json::json;

#[tokio::test]
async fn test_global_admin_role_lifecycle_uses_users_role_and_revokes_cleanly() {
    let harness = TestHarness::new().await;
    let bootstrap_admin = harness
        .create_bootstrap_admin("bootstrap_admin", "Bootstrap Admin")
        .await;
    let subject = harness
        .signup_user_fixture("lifecycle_subject", "Lifecycle Subject")
        .await;

    let organization = harness
        .create_organization(
            &subject.token,
            "Lifecycle Org",
            &unique_slug("lifecycle-org"),
        )
        .await;
    harness
        .set_active_organization(&subject.token, &organization.slug)
        .await;

    let org_permission = harness
        .organization_has_permission(&subject.token, json!({ "member": ["create"] }))
        .await;
    assert_eq!(
        org_permission["success"], true,
        "organization owner should have organization member.create permission"
    );

    let (status, body) = harness.admin_list_users(&subject.token).await;
    assert_eq!(
        status, 403,
        "organization ownership alone must not grant global admin access: {}",
        body
    );

    let promoted = harness
        .set_global_role_as_admin(&bootstrap_admin.token, &subject.user_id, "admin")
        .await;
    assert_eq!(
        promoted["user"]["role"], "admin",
        "admin.set-role should promote the subject's global user role"
    );

    let (status, body) = harness.admin_list_users(&subject.token).await;
    assert_eq!(
        status, 200,
        "global athena.users.role=admin should unlock admin actions: {}",
        body
    );

    let managed_email = unique_email("managed_by_subject");
    let managed = harness
        .admin_create_user(
            &subject.token,
            &managed_email,
            "password123",
            "Managed By Subject",
            "member",
        )
        .await;
    let managed_user_id = managed["user"]["id"]
        .as_str()
        .expect("admin create-user response missing user.id")
        .to_string();

    harness
        .admin_remove_user(&subject.token, &managed_user_id)
        .await;
    harness.expect_user_missing(&managed_user_id).await;

    let demoted = harness
        .set_global_role_as_admin(&bootstrap_admin.token, &subject.user_id, "member")
        .await;
    assert_eq!(
        demoted["user"]["role"], "member",
        "admin.set-role should demote the subject's global user role"
    );

    let (status, body) = harness.admin_list_users(&subject.token).await;
    assert_eq!(
        status, 403,
        "demoted global user role must lose admin access immediately: {}",
        body
    );

    harness
        .admin_remove_user(&bootstrap_admin.token, &subject.user_id)
        .await;
    harness.expect_user_missing(&subject.user_id).await;
    harness
        .expect_get_session_unauthorized(&subject.token)
        .await;
}

#[tokio::test]
async fn test_organization_admin_role_does_not_grant_global_admin_until_users_role_is_promoted() {
    let harness = TestHarness::new().await;
    let bootstrap_admin = harness
        .create_bootstrap_admin("role_boundary_admin", "Role Boundary Admin")
        .await;
    let owner = harness
        .signup_user_fixture("org_role_owner", "Org Role Owner")
        .await;
    let org_admin_member = harness
        .signup_user_fixture("org_role_member", "Org Role Member")
        .await;

    harness
        .mark_user_email_verified(&org_admin_member.email)
        .await;

    let organization = harness
        .create_organization(
            &owner.token,
            "Role Boundary Org",
            &unique_slug("role-boundary-org"),
        )
        .await;
    harness
        .set_active_organization(&owner.token, &organization.slug)
        .await;

    let invitation_id = harness
        .invite_member(&owner.token, &org_admin_member.email, "member")
        .await;
    harness
        .accept_invitation(&org_admin_member.token, &invitation_id)
        .await;

    let member_id = harness
        .organization_member_id_by_email(&owner.token, &organization.slug, &org_admin_member.email)
        .await;
    let updated_member = harness
        .update_organization_member_role(&owner.token, &member_id, "admin")
        .await;
    assert_eq!(
        updated_member["member"]["role"], "admin",
        "organization update-member-role should promote the membership to organization admin"
    );

    harness
        .set_active_organization(&org_admin_member.token, &organization.slug)
        .await;

    let org_permission = harness
        .organization_has_permission(&org_admin_member.token, json!({ "member": ["create"] }))
        .await;
    assert_eq!(
        org_permission["success"], true,
        "organization admin should have organization member.create permission"
    );

    let (status, body) = harness.admin_list_users(&org_admin_member.token).await;
    assert_eq!(
        status, 403,
        "organization member.role=admin must not grant global admin access: {}",
        body
    );

    let promoted = harness
        .set_global_role_as_admin(&bootstrap_admin.token, &org_admin_member.user_id, "admin")
        .await;
    assert_eq!(
        promoted["user"]["role"], "admin",
        "global athena.users.role should be promoted through admin.set-role"
    );

    let (status, body) = harness.admin_list_users(&org_admin_member.token).await;
    assert_eq!(
        status, 200,
        "global athena.users.role=admin should unlock admin endpoints even for an org-admin user: {}",
        body
    );
}
