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

const listUnits = graphql(`
  query ListUnits {
    units {
      edges {
        node {
          id
        }
      }
    }
  }
`);

const createProductIdOnly = graphql(`
  mutation CreateProductIdOnly($code: String!, $name: String!, $unitId: ID!) {
    createProduct(code: $code, name: $name, unitId: $unitId) {
      id
    }
  }
`);

const activateProductFull = graphql(`
  mutation ActivateProductFull($id: ID!) {
    activateProduct(id: $id) {
      id
      status
    }
  }
`);

const activateProductIdOnly = graphql(`
  mutation ActivateProductIdOnly($id: ID!) {
    activateProduct(id: $id) {
      id
    }
  }
`);

const deactivateProductIdOnly = graphql(`
  mutation DeactivateProductIdOnly($id: ID!) {
    deactivateProduct(id: $id) {
      id
    }
  }
`);

describe("product-manager--activate-product", () => {
  const gql = createGraphQLClient(inject("url"), inject("token"));

  it("Given a DRAFT product, when activation is confirmed, then the product status becomes ACTIVE and UoM is locked.", async () => {
    const unitsResult = await gql.query(listUnits, {}).toPromise();
    const uomId = unitsResult.data!.units.edges[0].node.id;

    const createResult = await gql
      .mutation(createProductIdOnly, {
        code: `ACT-${Date.now()}`,
        name: "Activate Test",
        unitId: uomId,
      })
      .toPromise();
    const productId = createResult.data!.createProduct.id;

    const res = await gql.mutation(activateProductFull, { id: productId }).toPromise();

    expect(res.data?.activateProduct.status).toBe("ACTIVE");
  });

  it("Given an ACTIVE product, when activation is attempted, then an error is shown and status remains unchanged.", async () => {
    const unitsResult = await gql.query(listUnits, {}).toPromise();
    const uomId = unitsResult.data!.units.edges[0].node.id;

    const createResult = await gql
      .mutation(createProductIdOnly, {
        code: `ACT-DUP-${Date.now()}`,
        name: "Already Active Test",
        unitId: uomId,
      })
      .toPromise();
    const productId = createResult.data!.createProduct.id;

    await gql.mutation(activateProductIdOnly, { id: productId }).toPromise();

    await expect(
      gql.mutation(activateProductIdOnly, { id: productId }).toPromise(),
    ).rejects.toThrow();
  });

  it("Given an ARCHIVED product, when activation is attempted, then an error is shown and status remains unchanged.", async () => {
    const unitsResult = await gql.query(listUnits, {}).toPromise();
    const uomId = unitsResult.data!.units.edges[0].node.id;

    const createResult = await gql
      .mutation(createProductIdOnly, {
        code: `ACT-ARCH-${Date.now()}`,
        name: "Archived Activate Test",
        unitId: uomId,
      })
      .toPromise();
    const productId = createResult.data!.createProduct.id;

    await gql.mutation(activateProductIdOnly, { id: productId }).toPromise();
    await gql.mutation(deactivateProductIdOnly, { id: productId }).toPromise();

    await expect(
      gql.mutation(activateProductIdOnly, { id: productId }).toPromise(),
    ).rejects.toThrow();
  });
});
