import { openSession, discardSession, closeSession } from './session.js';
import { getOutgoingWarehouse } from './warehouse.js';
import { reservePositions } from './reserve.js';
import { commitPicklists } from './commit.js';
import { deliverPicklists } from './deliver.js';

/**
 * Delivers the full ordered quantity of every position of an order, exactly
 * reproducing JTL-Wawi's own fulfillment engine (jtlCore's
 * PosOrderCreationService -> DeliveryStep.Run -> AuslieferungAusliefernContext.Commit())
 * instead of the old shortcut of calling Versand.spLieferscheinErstellen /
 * spLieferscheinPosErstellen directly. See ../../../delivery.md for the full
 * investigation (§0 has the literal SQL sequence this function implements).
 *
 * Creates real dbo.tPickliste/tPicklistePos rows, decrements real warehouse
 * stock, produces a properly numbered Lieferschein ("<AuftragsNr>-NNN"), and
 * a dbo.tVersand row carrying the order's Versandart (e.g. "Selbstabholer"),
 * matching what the Wawi GUI / native POS sync produce.
 */
export async function deliverOrder(transaction, kBenutzer, kAuftrag, kVersandArt, deliveredItems) {
  if (!deliveredItems.length) {
    return;
  }

  const kWarenLager = await getOutgoingWarehouse(transaction);
  const kSessionId = await openSession(transaction, kBenutzer);

  try {
    await reservePositions(transaction, kBenutzer, kSessionId, kWarenLager, deliveredItems);
    await commitPicklists(transaction, kBenutzer, kSessionId, kAuftrag);
    await deliverPicklists(transaction, kBenutzer, kSessionId, kAuftrag, kVersandArt);
  } finally {
    // Safe to run unconditionally (success or error): spPicklistenVerwerfen only
    // ever removes not-yet-delivered (nStatus < 10) Picklisten for this session.
    // Swallow cleanup errors so they never mask an earlier, more relevant error
    // (the outer transaction rollback in create-order.js is what actually matters
    // on failure).
    try {
      await discardSession(transaction, kBenutzer, kSessionId);
      await closeSession(transaction, kSessionId);
    } catch {
      // best-effort cleanup only
    }
  }
}
