/**
 * `/btw` — non-aborting mid-run steering ("by the way").
 *
 * Unlike `/steer` (which aborts the current iteration and prepends a heavy
 * STEERING preamble), `/btw` stashes a short note on the live `Context` and
 * lets the agent pick it up at the NEXT iteration boundary — between tool
 * batches — without tearing down in-flight work.
 *
 * Flow:
 *  1. The `/btw <text>` slash command calls `setBtwNote(ctx, text)` on the
 *     live run context. Multiple notes accumulate in order.
 *  2. At the top of each agent iteration (before the request is built),
 *     `Agent` drains the queue via `consumeBtwNotes(ctx)` and folds the
 *     notes into the conversation as a user-visible block.
 *
 * The notes live in `ctx.meta` so the slash command and the agent loop share
 * one source of truth, the same way `_autonomousContinue` is plumbed in
 * {@link ./continue-to-next-iteration.ts}.
 */
import type { Context } from './context.js';

/** Meta key holding the pending `/btw` notes (FIFO). */
const META_KEY = '_btwNotes';

/** Cap on queued notes so a runaway loop can't grow `ctx.meta` unbounded. */
const MAX_PENDING = 20;

function readQueue(ctx: Context): string[] {
  const raw = ctx.meta[META_KEY];
  return Array.isArray(raw) ? (raw as string[]) : [];
}

/**
 * Stash a "by the way" note on the context. The agent surfaces it at the
 * start of its next iteration. Blank notes are ignored. Returns the number
 * of notes now pending.
 */
export function setBtwNote(ctx: Context, text: string): number {
  const trimmed = text.trim();
  if (!trimmed) return readQueue(ctx).length;
  const next = [...readQueue(ctx), trimmed].slice(-MAX_PENDING);
  ctx.meta[META_KEY] = next;
  return next.length;
}

/** Number of notes currently waiting to be delivered. */
export function pendingBtwCount(ctx: Context): number {
  return readQueue(ctx).length;
}

/**
 * Read and clear all pending notes in one call. Returns them in the order
 * they were added (empty array when none).
 */
export function consumeBtwNotes(ctx: Context): string[] {
  const notes = readQueue(ctx);
  if (notes.length > 0) delete ctx.meta[META_KEY];
  return notes;
}

/**
 * Format pending notes as the text the agent reads. Kept deliberately light
 * (no "I interrupted you" framing) so the model folds the note into its
 * current work rather than restarting.
 */
export function buildBtwBlock(notes: string[]): string {
  const body = notes.map((n) => `- ${n}`).join('\n');
  return [
    '[BY THE WAY — the user added this while you were working. Fold it into',
    'your current task; do not restart from scratch unless it contradicts the',
    'goal:',
    '',
    body,
    ']',
  ].join('\n');
}
