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

export interface OpenForAdvanceEntryInput {
  id: string;
}

const from = ["NEVER_OPENED"];

export async function run(db: Transaction, input: OpenForAdvanceEntryInput, ctx: CommandContext) {
  const period = await db
    .selectFrom("AccountingPeriod")
    .selectAll()
    .where("id", "=", input.id)
    .forUpdate()
    .executeTakeFirst();

  if (!period) {
    return err(new AccountingPeriodNotFoundError(input.id));
  }

  if (!from.includes(period.status as string)) {
    return err(new InvalidStatusTransitionError(input.id));
  }

  const updated = await db
    .updateTable("AccountingPeriod")
    .set({
      status: "FUTURE_ENTERABLE",
      updatedAt: new Date(),
    })
    .where("id", "=", input.id)
    .returningAll()
    .executeTakeFirstOrThrow();

  // Emit audit event recording status transition from NEVER_OPENED to FUTURE_ENTERABLE and acting user
  void ctx;

  return ok({ accountingPeriod: updated });
}
