import { describe, expect, inject, it } from "vitest";
import { createGraphQLClient, graphql } from "@/tests/utils/graphql-client";

const listRoles = graphql(`
  query {
    roles {
      edges {
        node {
          id
        }
      }
    }
  }
`);

const createUser = graphql(`
  mutation ($name: String!, $email: String!, $roleIds: [String!]) {
    createUser(name: $name, email: $email, roleIds: $roleIds) {
      id
    }
  }
`);

const revokeRoleFromUser = graphql(`
  mutation ($userId: String!, $roleId: String!) {
    revokeRoleFromUser(userId: $userId, roleId: $roleId) {
      userId
      roleId
    }
  }
`);

const listUserRoles = graphql(`
  query ListUserRoles($userId: ID!) {
    userRoles(query: { userId: { eq: $userId } }) {
      edges {
        node {
          roleId
        }
      }
    }
  }
`);

describe("user--remove-role-from-user", () => {
  const gql = createGraphQLClient(inject("url"), inject("token"));

  it("Select an assigned role on a user, click Remove, and confirm; verify the role no longer appears in the user's role list", async () => {
    const rolesResult = await gql.query(listRoles, {}).toPromise();
    const roleId = rolesResult.data!.roles.edges[0].node.id;

    const createResult = await gql
      .mutation(createUser, {
        name: "Remove Role User",
        email: `remove-role-${Date.now()}@example.com`,
        roleIds: [roleId],
      })
      .toPromise();
    const userId = createResult.data!.createUser.id;

    await gql.mutation(revokeRoleFromUser, { userId, roleId }).toPromise();

    const userRolesResult = await gql.query(listUserRoles, { userId }).toPromise();

    const assignedRoleIds = userRolesResult.data?.userRoles.edges.map((edge) => edge.node.roleId);
    expect(assignedRoleIds).not.toContain(roleId);
  });

  it("Select an assigned role on a user, click Remove, and cancel; verify the role still appears in the user's role list", async () => {
    // "Cancel" is a frontend-only action. Verify that without calling revoke, the role remains.
    const rolesResult = await gql.query(listRoles, {}).toPromise();
    const roleId = rolesResult.data!.roles.edges[0].node.id;

    const createResult = await gql
      .mutation(createUser, {
        name: "Cancel Remove User",
        email: `cancel-remove-${Date.now()}@example.com`,
        roleIds: [roleId],
      })
      .toPromise();
    const userId = createResult.data!.createUser.id;

    // Do NOT call revoke — simulate cancel
    const userRolesResult = await gql.query(listUserRoles, { userId }).toPromise();

    const assignedRoleIds = userRolesResult.data?.userRoles.edges.map((edge) => edge.node.roleId);
    expect(assignedRoleIds).toContain(roleId);
  });
});
