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

export interface DeleteJournalEntryInput {
  journalEntryId: string;
}

/**
 * Function: deleteJournalEntry
 *
 * Removes a journal entry and all its associated journal lines from the system.
 * Only DRAFT entries can be deleted. Posted entries must be reversed rather than
 * deleted to preserve the audit trail.
 */
export async function run(db: Transaction, input: DeleteJournalEntryInput, _ctx: CommandContext) {
  const { journalEntryId } = input;

  // 1. Find journal entry with forUpdate
  const existing = await db
    .selectFrom("JournalEntry")
    .selectAll()
    .where("id", "=", journalEntryId)
    .forUpdate()
    .executeTakeFirst();

  if (!existing) {
    return err(new JournalEntryNotFoundError(journalEntryId));
  }

  // 2. Must be DRAFT
  if (existing.status !== "DRAFT") {
    return err(new InvalidStatusForDeleteError(journalEntryId));
  }

  // 3. Delete all associated journal lines first
  await db.deleteFrom("JournalLine").where("journalEntryId", "=", journalEntryId).execute();

  // 4. Delete the journal entry
  await db.deleteFrom("JournalEntry").where("id", "=", journalEntryId).execute();

  return ok({ journalEntryId });
}
