import type { Transaction } from "../generated/kysely-tailordb";
import { InvalidCostingMethodError, StandardCostRateRequiredError } from "../lib/errors.generated";
import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/module";

const VALID_COSTING_METHODS = ["FIFO", "AVCO", "STANDARD_COST"] as const;
type CostingMethod = (typeof VALID_COSTING_METHODS)[number];

export interface CreateValuationPolicyInput {
  name: string;
  costingMethod: string;
  standardCostRate?: number | null;
}

/**
 * Function: createValuationPolicy
 *
 * Creates a new valuation policy that defines the costing method used to
 * calculate inventory value. Supported costing methods are FIFO, AVCO,
 * and STANDARD_COST.
 */
export async function run(
  db: Transaction,
  input: CreateValuationPolicyInput,
  _ctx: CommandContext,
) {
  const { name, costingMethod, standardCostRate } = input;

  // 1. Validate costingMethod
  if (!VALID_COSTING_METHODS.includes(costingMethod as CostingMethod)) {
    return err(new InvalidCostingMethodError(costingMethod));
  }

  // 2. Require standardCostRate for STANDARD_COST
  if (costingMethod === "STANDARD_COST" && standardCostRate == null) {
    return err(new StandardCostRateRequiredError(costingMethod));
  }

  // 3. Create valuation policy
  const policy = await db
    .insertInto("ValuationPolicy")
    .values({
      name,
      costingMethod: costingMethod as CostingMethod,
      standardCostRate: standardCostRate ?? null,
      createdAt: new Date(),
      updatedAt: null,
    })
    .returningAll()
    .executeTakeFirst();

  return ok({ valuationPolicy: policy! });
}
