import { ok, err } from "@tailor-platform/erp-kit/core";
import { Transaction } from "../generated/kysely-tailordb";
import {
  AssignmentNotFoundError,
  ProductNotFoundError,
  ProductArchivedError,
  AxisStructureLockedError,
} from "../lib/errors.generated";

export interface RemoveAttributeValueFromProductInput {
  productId: string;
  attributeId: string;
  valueId: string;
}

/**
 * Function: removeAttributeValueFromProduct
 *
 * Removes an attribute value assignment from a product.
 * Identified by the composite key (productId, attributeId, valueId).
 *
 * Status-based rules:
 * - DRAFT: freely removable
 * - ACTIVE: removal is blocked (axis structure locked)
 * - ARCHIVED: all changes blocked
 */
export async function run(db: Transaction, input: RemoveAttributeValueFromProductInput) {
  const { productId, attributeId, valueId } = input;

  // Check product exists
  const product = await db
    .selectFrom("Product")
    .selectAll()
    .where("id", "=", productId)
    .executeTakeFirst();
  if (!product) {
    return err(new ProductNotFoundError(productId));
  }

  // Status-based rules
  if (product.status === "ARCHIVED") {
    return err(new ProductArchivedError(productId));
  }

  if (product.status === "ACTIVE") {
    return err(new AxisStructureLockedError(productId));
  }

  // Find the assignment
  const assignment = await db
    .selectFrom("ProductAttributeAssignment")
    .selectAll()
    .where("productId", "=", productId)
    .where("attributeId", "=", attributeId)
    .where("valueId", "=", valueId)
    .forUpdate()
    .executeTakeFirst();
  if (!assignment) {
    return err(new AssignmentNotFoundError(`${productId}:${attributeId}:${valueId}`));
  }

  await db.deleteFrom("ProductAttributeAssignment").where("id", "=", assignment.id).execute();

  return ok({ id: assignment.id });
}
