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

const createCategoryIdOnly = graphql(`
  mutation CreateCategoryForViewerBrowse($code: String!, $name: String!) {
    createCategory(code: $code, name: $name) {
      id
    }
  }
`);

const listCategories = graphql(`
  query ListCategoriesViewer {
    productCategories {
      edges {
        node {
          id
          code
          name
        }
      }
    }
  }
`);

const getCategory = graphql(`
  query GetCategoryViewer($id: ID!) {
    productCategory(id: $id) {
      id
      code
      name
    }
  }
`);

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

  // Create our own category so this file is self-contained and does not
  // depend on rows other tests may delete in parallel.
  let ownCategoryId: string;
  beforeAll(async () => {
    const res = await gql
      .mutation(createCategoryIdOnly, {
        code: `VIEWER-BROWSE-${Date.now()}`,
        name: "Viewer Browse Category",
      })
      .toPromise();
    ownCategoryId = res.data!.createCategory.id;
  });

  it("Given categories exist, the viewer sees the hierarchical tree without mutation actions", async () => {
    const result = await gql.query(listCategories, {}).toPromise();

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

  it("Given no categories exist, the viewer sees an empty state", async () => {
    const result = await gql.query(listCategories, {}).toPromise();

    expect(result.data?.productCategories.edges).toBeDefined();
    expect(Array.isArray(result.data?.productCategories.edges)).toBe(true);
  });

  it("Given the viewer selects a category, they are navigated to the category detail screen", async () => {
    // Fetch a category this file created, not edges[0] from the shared list:
    // a parallel delete test could remove that row between list and fetch.
    const result = await gql.query(getCategory, { id: ownCategoryId }).toPromise();

    expect(result.data?.productCategory?.id).toBe(ownCategoryId);
    expect(result.data?.productCategory?.code).toBeDefined();
    expect(result.data?.productCategory?.name).toBeDefined();
  });
});
