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

const createAttribute = graphql(`
  mutation CreateAttributeForViewerBrowse($code: String!, $name: String!, $valueLabels: [String!]) {
    createAttribute(code: $code, name: $name, valueLabels: $valueLabels) {
      id
    }
  }
`);

const listAttributes = graphql(`
  query ViewerListProductAttributes {
    productAttributes {
      edges {
        node {
          id
          code
          name
        }
      }
    }
  }
`);

const getAttribute = graphql(`
  query ViewerGetProductAttribute($id: ID!) {
    productAttribute(id: $id) {
      id
      code
      name
    }
  }
`);

describe("viewer--browse-attribute-list", () => {
  const gql = createGraphQLClient(inject("url"), inject("token"));

  // Create our own attributes so this file is self-contained.
  // With parallel workers it may run before any attribute is created.
  let ownAttributeId: string;
  beforeAll(async () => {
    const suffix = Date.now();
    const results = await Promise.all(
      [0, 1].map((i) =>
        gql
          .mutation(createAttribute, {
            code: `BROWSE-VIEWER-ATTR-${suffix}-${i}`,
            name: `Browse Viewer Attribute ${i}`,
            valueLabels: ["A", "B"],
          })
          .toPromise(),
      ),
    );
    ownAttributeId = results[0].data!.createAttribute.id;
  });

  it("Given attributes exist, when the attribute list is opened, then each attribute is shown with its code, name, and value count.", async () => {
    const res = await gql.query(listAttributes, {}).toPromise();

    expect(res.data?.productAttributes.edges.length).toBeGreaterThan(0);
    const node = res.data?.productAttributes.edges[0].node;
    expect(node?.id).toBeDefined();
    expect(node?.code).toBeDefined();
    expect(node?.name).toBeDefined();
  });

  it("Given the attribute list is displayed, when an attribute is selected, then the attribute detail screen is shown in read-only mode.", async () => {
    // Fetch an attribute this file created, not edges[0] from the shared list:
    // a parallel delete test could remove that row between list and fetch.
    const res = await gql.query(getAttribute, { id: ownAttributeId }).toPromise();

    const viewerAttr = res.data!.productAttribute!;
    expect(viewerAttr.id).toBe(ownAttributeId);
    expect(viewerAttr.code).toBeDefined();
    expect(viewerAttr.name).toBeDefined();
  });
});
