import { createInterface, emitKeypressEvents } from 'node:readline';
import { stdin, stdout } from 'node:process';

export function ask(question, { defaultValue } = {}) {
  const rl = createInterface({ input: stdin, output: stdout });
  const suffix = defaultValue ? ` [${defaultValue}]` : '';
  return new Promise((resolve) => {
    rl.question(`${question}${suffix}: `, (answer) => {
      rl.close();
      const v = answer.trim();
      resolve(v === '' && defaultValue !== undefined ? defaultValue : v);
    });
  });
}

export function askSecret(question) {
  return new Promise((resolve, reject) => {
    if (!stdin.isTTY) {
      reject(new Error('Passwort-Eingabe erfordert ein interaktives Terminal.'));
      return;
    }
    stdout.write(`${question}: `);
    emitKeypressEvents(stdin);
    stdin.setRawMode(true);
    stdin.resume();
    let buf = '';
    const onKey = (_, key) => {
      if (!key) return;
      if (key.name === 'return' || key.name === 'enter') {
        stdin.setRawMode(false);
        stdin.pause();
        stdin.removeListener('keypress', onKey);
        stdout.write('\n');
        resolve(buf);
      } else if (key.name === 'backspace') {
        buf = buf.slice(0, -1);
      } else if (key.ctrl && key.name === 'c') {
        stdin.setRawMode(false);
        stdin.pause();
        stdin.removeListener('keypress', onKey);
        stdout.write('\n');
        reject(new Error('Abgebrochen.'));
      } else if (key.sequence && !key.ctrl && !key.meta) {
        // Akzeptiert sowohl einzelne Tipp-Zeichen als auch pasted Multi-Char-Sequences
        // (Powershell sendet Clipboard-Paste als ein einzelnes Event mit langer sequence).
        // Escape-Codes wie Arrow Keys (\x1b[A) und sonstige Steuerzeichen rausfiltern,
        // damit nur druckbarer Text im Passwort landet.
        const printable = key.sequence.replace(/[\x00-\x1f\x7f]/g, '');
        if (printable) buf += printable;
      }
    };
    stdin.on('keypress', onKey);
  });
}

export async function askConfirm(question, { defaultYes = false } = {}) {
  const hint = defaultYes ? 'J/n' : 'j/N';
  const a = (await ask(`${question} (${hint})`)).toLowerCase();
  if (a === '') return defaultYes;
  return a === 'j' || a === 'ja' || a === 'y' || a === 'yes';
}
