export interface BatchString {
  id: string;
  content: string;
}

export interface BatchPlannerOptions {
  maxChars: number;
  maxCount: number;
  maxPayloadBytes?: number;
}

/**
 * Pack strings greedily in input order while respecting the configured limits.
 * An item that exceeds a limit by itself is retained as a singleton batch.
 */
export function planBatches(
  strings: Array<BatchString>,
  opts: BatchPlannerOptions
): Array<Array<BatchString>> {
  if (strings.length === 0) {
    return [];
  }

  const batches: Array<Array<BatchString>> = [];
  let currentBatch: Array<BatchString> = [];
  let currentChars = 0;

  for (const string of strings) {
    const stringChars = string.content.length;
    const candidateBatch = [...currentBatch, string];
    const candidatePayloadBytes = Buffer.byteLength(JSON.stringify(candidateBatch));
    const exceedsCurrentBatch = currentBatch.length > 0 && (
      currentBatch.length >= opts.maxCount
      || currentChars + stringChars > opts.maxChars
      || (
        opts.maxPayloadBytes !== undefined
        && candidatePayloadBytes > opts.maxPayloadBytes
      )
    );

    if (exceedsCurrentBatch) {
      batches.push(currentBatch);
      currentBatch = [];
      currentChars = 0;
    }

    currentBatch.push(string);
    currentChars += stringChars;
  }

  if (currentBatch.length > 0) {
    batches.push(currentBatch);
  }

  return batches;
}
