import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core";
import { pipelineLifecycle } from "../db/pipeline.lifecycle.generated";
import type { Transaction } from "../generated/kysely-tailordb";
import { PipelineNotFoundError, InvalidStatusTransitionError } from "../lib/errors.generated";

export interface DeactivatePipelineInput {
  pipelineId: string;
}

export async function run(db: Transaction, input: DeactivatePipelineInput, ctx: CommandContext) {
  void ctx;

  const pipeline = await db
    .selectFrom("Pipeline")
    .selectAll()
    .where("id", "=", input.pipelineId)
    .forUpdate()
    .executeTakeFirst();

  if (!pipeline) {
    return err(new PipelineNotFoundError(input.pipelineId));
  }

  // Idempotent: ARCHIVED → ARCHIVED returns the existing row as-is.
  if (pipeline.status === pipelineLifecycle.transitions.deactivate.to) {
    return ok({ pipeline });
  }

  const nextStatus = pipelineLifecycle.tryTransition(pipeline.status, "deactivate");
  if (!nextStatus) {
    return err(new InvalidStatusTransitionError(input.pipelineId));
  }

  const archivedPipeline = await db
    .updateTable("Pipeline")
    .set({
      status: nextStatus,
      updatedAt: new Date(),
    })
    .where("id", "=", input.pipelineId)
    .returningAll()
    .executeTakeFirst();

  return ok({
    pipeline: archivedPipeline ?? { ...pipeline, status: nextStatus, updatedAt: new Date() },
  });
}
