import sql from 'mssql';
import { xmlTag, xmlElement } from './xml.js';

// ReserviereBestellpositionenOptionen: ChargenVorbelegen (0x0002) | Stücklistenkorrektur (0x0100).
// Matches jtlCore's AuslieferungContext ctor + the StoredProcedures.cs wrapper for
// Auslieferung_spReserviereBestellpositionen (see delivery.md §3.1).
const RESERVIERE_OPTIONS = 0x102;

/**
 * Reserves every order position against the outgoing warehouse, creating
 * dbo.tPickliste/tPicklistePos rows (status 0 -> 5) for this session.
 * Mirrors PosBookPositionService.BookPosition -> AuslieferungContext.NeuReservieren
 * -> Auslieferung.spReserviereBestellpositionen.
 *
 * XML parameters are passed as NVarChar and CONVERT()ed to xml in the SQL
 * batch itself (rather than using sql.Xml directly), because tedious does
 * not reliably round-trip the `xml` SQL type for these procedures.
 */
export async function reservePositions(transaction, kBenutzer, kSessionId, kWarenLager, positions) {
  if (!positions.length) {
    return;
  }

  const bestellpositionen = positions
    .map(({ kAuftragPosition, quantity }) =>
      xmlElement('Bestellposition', [xmlTag('kBestellPos', kAuftragPosition), xmlTag('fAnzahl', quantity)])
    )
    .join('');

  const laeger = xmlElement('Lager', [
    xmlTag('kWarenlager', kWarenLager),
    xmlTag('nPrio', 0),
    xmlTag('kLieferant', 0),
    xmlTag('kAnsprechpartner', 0),
  ]);

  await new sql.Request(transaction)
    .input('Bestellpositionen', sql.NVarChar(sql.MAX), bestellpositionen)
    .input('Laeger', sql.NVarChar(sql.MAX), laeger)
    .input('nOptions', sql.Int, RESERVIERE_OPTIONS)
    .input('kBenutzer', sql.Int, kBenutzer)
    .input('kSessionId', sql.Int, kSessionId)
    .query(`
      DECLARE @xBestellpositionen XML = CONVERT(XML, @Bestellpositionen);
      DECLARE @xLaeger XML = CONVERT(XML, @Laeger);
      EXEC Auslieferung.spReserviereBestellpositionen
        @Bestellpositionen  = @xBestellpositionen,
        @Laeger              = @xLaeger,
        @Warenlagereingaenge = NULL,
        @nOptions             = @nOptions,
        @kBenutzer            = @kBenutzer,
        @kSessionId           = @kSessionId;
    `);
}
