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

const getProduct = graphql(`
  query GetProduct($id: ID!) {
    product(id: $id) {
      id
    }
  }
`);

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

  it("Given a DRAFT product, when deletion is confirmed, then the product is permanently removed from the system.", async () => {
    const unitsResult = await gql.query(listUnits, {}).toPromise();
    const uomId = unitsResult.data!.units.edges[0].node.id;

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

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

    expect(res.data?.deleteProduct.id).toBe(productId);

    // Verify the product no longer exists
    const check = await gql.query(getProduct, { id: productId }).toPromise();
    expect(check.data?.product).toBeNull();
  });

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

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

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

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

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

    const createResult = await gql
      .mutation(createProductIdOnly, {
        code: `DEL-ARCH-${Date.now()}`,
        name: "Archived Delete 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(deleteProduct, { id: productId }).toPromise()).rejects.toThrow();
  });
});
