import { createContext } from "@tailor-platform/erp-kit/app";
import { createResolver, t } from "@tailor-platform/sdk";
import { getDB } from "@/generated/kysely-tailordb";
import { pmModules } from "@/modules";

export default createResolver({
  name: "updateProduct",
  operation: "mutation",
  input: {
    id: t.uuid().description("Product ID"),
    name: t.string({ optional: true }).description("New product name"),
    description: t.string({ optional: true }).description("New product description"),
    unitId: t.uuid({ optional: true }).description("New unit of measure ID"),
  },
  body: async (context) => {
    const db = getDB("main-db");
    const result = await db.transaction().execute(async (trx) => {
      const updateInput: {
        id: string;
        name?: string;
        description?: string | null;
        unitId?: string;
      } = {
        id: context.input.id,
      };
      if (context.input.name != null) updateInput.name = context.input.name;
      if (context.input.description !== undefined)
        updateInput.description = context.input.description;
      if (context.input.unitId != null) updateInput.unitId = context.input.unitId;

      const cmdResult = await pmModules.commands.updateProduct(
        trx,
        updateInput,
        createContext(context),
      );
      if (!cmdResult.ok) {
        switch (cmdResult.error.code) {
          case "PRODUCT_MANAGEMENT_PRODUCT_NOT_FOUND":
            throw new Error(`Product ${context.input.id} does not exist`);
          case "PRODUCT_MANAGEMENT_NO_FIELDS_TO_UPDATE":
            throw new Error("No fields to update were provided");
          case "PRODUCT_MANAGEMENT_UOM_LOCKED":
            throw new Error("Unit of measure cannot be changed after product is activated");
          case "PRODUCT_MANAGEMENT_INVALID_UOM":
            throw new Error(`Invalid unit of measure: ${context.input.unitId}`);
          case "PRODUCT_MANAGEMENT_MISSING_REQUIRED_FIELD":
            throw new Error(`Missing required field: ${cmdResult.error.message}`);
          case "INSUFFICIENT_PERMISSION":
            throw cmdResult.error;
          default:
            throw cmdResult.error satisfies never;
        }
      }
      return {
        id: cmdResult.value.product.id,
        name: cmdResult.value.product.name,
        status: cmdResult.value.product.status,
      };
    });

    return result;
  },
  output: t
    .object({
      id: t.uuid().description("Product ID"),
      name: t.string().description("Product name"),
      status: t.string().description("Product status"),
    })
    .description("Updated product"),
});
