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

const listUserIds = graphql(`
  query ListUserIds {
    users {
      edges {
        node {
          id
        }
      }
    }
  }
`);

const getUser = graphql(`
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      name
      email
      status
    }
  }
`);

const getUserStatus = graphql(`
  query GetUserStatus($id: ID!) {
    user(id: $id) {
      id
      status
    }
  }
`);

const createActiveRole = graphql(`
  mutation CreateActiveRoleForViewDetail($name: String!, $permissions: [String!]!) {
    createRole(name: $name, permissions: $permissions) {
      id
    }
  }
`);

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

const deactivateUserIdOnly = graphql(`
  mutation DeactivateUserIdOnly($userId: ID!) {
    deactivateUser(userId: $userId) {
      id
    }
  }
`);

describe("user--view-user-detail", () => {
  const gql = createGraphQLClient(inject("url"), inject("token"));

  // Create our own active role so this file does not depend on seeded roles.
  // Other tests deactivate roles in parallel, so reusing one from the list is unsafe.
  let activeRoleId: string;
  beforeAll(async () => {
    const res = await gql
      .mutation(createActiveRole, { name: `view-detail-active-${Date.now()}`, permissions: [] })
      .toPromise();
    activeRoleId = res.data!.createRole.id;
  });

  it("Click on a user in the list; verify name, email, status, and assigned roles are displayed", async () => {
    const listResult = await gql.query(listUserIds, {}).toPromise();
    const userId = listResult.data!.users.edges[0].node.id;

    const res = await gql.query(getUser, { id: userId }).toPromise();

    expect(res.data?.user?.id).toBe(userId);
    expect(res.data?.user?.name).toBeDefined();
    expect(res.data?.user?.email).toBeDefined();
    expect(res.data?.user?.status).toBeDefined();
  });

  it("Click on an INACTIVE user; verify the profile is displayed with INACTIVE status clearly indicated", async () => {
    const createResult = await gql
      .mutation(createUserIdOnly, {
        name: "Inactive Detail User",
        email: `inactive-detail-${Date.now()}@example.com`,
        roleIds: [activeRoleId],
      })
      .toPromise();
    const userId = createResult.data!.createUser.id;

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

    const res = await gql.query(getUserStatus, { id: userId }).toPromise();

    expect(res.data?.user?.status).toBe("INACTIVE");
  });
});
