// Reconstruction d'écran via @xterm/headless : terminal headless PERSISTANT par session, alimenté
// incrémentalement par le flux PTY. Remplace le strip ANSI naïf (qui « mange les espaces » et casse
// la détection des dialogues — verdict S1/S3). Aucune dépendance DOM (usage Node).
import { createRequire } from 'node:module';
import type { Terminal as XtermTerminal } from '@xterm/headless';

// @xterm/headless est publié en CommonJS : sous Node ESM natif l'import nommé échoue
// (cjs-module-lexer ne détecte pas l'export). On charge via require, typé par l'import type.
const require = createRequire(import.meta.url);
const { Terminal } = require('@xterm/headless') as { Terminal: typeof XtermTerminal };

export class ScreenReader {
  private readonly term: XtermTerminal;

  constructor(cols = 120, rows = 40) {
    this.term = new Terminal({ cols, rows, scrollback: 0, allowProposedApi: true });
  }

  /**
   * Alimente le terminal avec un chunk PTY brut (la frontière UTF-8 et les séquences ANSI coupées
   * sont gérées par xterm). La promesse se résout quand le chunk a été parsé (snapshot fiable ensuite).
   */
  feed(chunk: Uint8Array | string): Promise<void> {
    return new Promise((resolve) => this.term.write(chunk as Uint8Array, resolve));
  }

  resize(cols: number, rows: number): void {
    this.term.resize(cols, rows);
  }

  /** Lignes visibles du viewport courant, espaces préservés (trim à droite uniquement). */
  snapshotLines(): string[] {
    const buf = this.term.buffer.active;
    const lines: string[] = [];
    for (let y = 0; y < this.term.rows; y++) {
      const line = buf.getLine(buf.baseY + y);
      lines.push(line ? line.translateToString(true) : '');
    }
    return lines;
  }

  dispose(): void {
    this.term.dispose();
  }
}
