import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/core";
import { workOrderLifecycle } from "../db/workOrder.lifecycle.generated";
import type { Transaction } from "../generated/kysely-tailordb";
import {
  WorkOrderNotFoundError,
  WorkOrderNotPausableError,
  PauseReasonRequiredError,
} from "../lib/errors.generated";

export interface PauseWorkOrderInput {
  id: string;
  pauseReason: string;
}

/**
 * Function: pauseWorkOrder
 *
 * Temporarily halts an in-progress work order and records the reason for
 * the interruption. Preserves accumulated execution history so the work
 * order can later resume.
 */
export async function run(db: Transaction, input: PauseWorkOrderInput, _ctx: CommandContext) {
  const { id, pauseReason } = input;

  // 1. Validate pause reason is provided
  if (!pauseReason || pauseReason.trim() === "") {
    return err(new PauseReasonRequiredError(id));
  }

  // 2. Fetch work order with lock
  const workOrder = await db
    .selectFrom("WorkOrder")
    .selectAll()
    .where("id", "=", id)
    .forUpdate()
    .executeTakeFirst();

  if (!workOrder) {
    return err(new WorkOrderNotFoundError(id));
  }

  // 3. Validate status is IN_PROGRESS
  const nextStatus = workOrderLifecycle.tryTransition(workOrder.status, "pause");
  if (!nextStatus) {
    return err(new WorkOrderNotPausableError(id));
  }

  // 4. Record pause event and set PAUSED
  const now = new Date();

  const updatedWorkOrder = await db
    .updateTable("WorkOrder")
    .set({
      status: nextStatus,
      pauseReason,
    })
    .where("id", "=", id)
    .returningAll()
    .executeTakeFirstOrThrow();

  // 5. Create PAUSED execution event
  await db
    .insertInto("WorkOrderExecutionEvent")
    .values({
      workOrderId: id,
      eventType: "PAUSED",
      timestamp: now,
      quantity: null,
      timeValue: null,
      scrapValue: null,
      notes: pauseReason,
    })
    .execute();

  return ok({ workOrder: updatedWorkOrder });
}
