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 activateProductIdOnly = graphql(`
  mutation ActivateProductIdOnly($id: ID!) {
    activateProduct(id: $id) {
      id
    }
  }
`);

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

const reactivateProductFull = graphql(`
  mutation ReactivateProductFull($id: ID!) {
    reactivateProduct(id: $id) {
      id
      status
    }
  }
`);

const reactivateProductIdOnly = graphql(`
  mutation ReactivateProductIdOnly($id: ID!) {
    reactivateProduct(id: $id) {
      id
    }
  }
`);

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

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

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

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

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

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

  it("Given a DRAFT product, when reactivation 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: `REACT-DRAFT-${Date.now()}`,
        name: "Draft Reactivate Test",
        unitId: uomId,
      })
      .toPromise();
    const productId = createResult.data!.createProduct.id;

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

  it("Given an ACTIVE product, when reactivation 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: `REACT-ACTIVE-${Date.now()}`,
        name: "Active Reactivate Test",
        unitId: uomId,
      })
      .toPromise();
    const productId = createResult.data!.createProduct.id;

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

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