/**
 * Token coalescer. Buffers stream tokens within a small time window before
 * dispatching a single aggregated chunk. Prevents 60+ re-renders per second
 * on fast streams.
 */

import { LIMITS } from '../config';

export interface TokenBuffer {
  /** Append a delta. Returns immediately. */
  push(delta: string): void;
  /** Force flush and resolve any pending timer. */
  flush(): void;
  /** Stop accepting tokens; flush whatever is buffered. */
  close(): void;
}

export function createTokenBuffer(
  onFlush: (delta: string) => void,
  windowMs = LIMITS.streamCoalesceMs,
): TokenBuffer {
  let pending = '';
  let timer: ReturnType<typeof setTimeout> | null = null;
  let closed = false;

  const flush = () => {
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }
    if (pending) {
      const out = pending;
      pending = '';
      onFlush(out);
    }
  };

  return {
    push(delta: string) {
      if (closed || !delta) return;
      pending += delta;
      if (windowMs <= 0) {
        flush();
        return;
      }
      if (timer === null) {
        timer = setTimeout(flush, windowMs);
      }
    },
    flush,
    close() {
      closed = true;
      flush();
    },
  };
}
