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

export interface ActivateChartOfAccountsInput {
  id: string;
  from?: string[];
}

/**
 * Function: activateChartOfAccounts
 *
 * Transitions a Chart of Accounts from DRAFT to ACTIVE status.
 * Only one CoA per company can be ACTIVE at a time.
 */
export async function run(
  db: Transaction,
  input: ActivateChartOfAccountsInput,
  _ctx: CommandContext,
) {
  const { id, from = ["DRAFT"] } = input;

  // 1. Find CoA with forUpdate
  const existing = await db
    .selectFrom("ChartOfAccounts")
    .selectAll()
    .where("id", "=", id)
    .forUpdate()
    .executeTakeFirst();

  if (!existing) {
    return err(new ChartOfAccountsNotFoundError(id));
  }

  // 2. Must be in an allowed source status
  if (!from.includes(existing.status)) {
    return err(new InvalidStateTransitionError(id));
  }

  // 3. Check no other ACTIVE CoA exists for the same company
  const activeCoA = await db
    .selectFrom("ChartOfAccounts")
    .selectAll()
    .where("companyId", "=", existing.companyId)
    .where("status", "=", "ACTIVE")
    .executeTakeFirst();

  if (activeCoA) {
    return err(new DuplicateActiveChartOfAccountsError(id));
  }

  // 4. Update status to ACTIVE
  const chartOfAccounts = await db
    .updateTable("ChartOfAccounts")
    .set({
      status: "ACTIVE",
      updatedAt: new Date(),
    })
    .where("id", "=", id)
    .returningAll()
    .executeTakeFirst();

  return ok({ chartOfAccounts: chartOfAccounts! });
}
