import type { Interface as ReadlineInterface } from 'readline/promises';

export interface ChoiceOption<T = string> {
  label: string;
  value: T;
}

export interface Prompter {
  ask(question: string, defaultValue?: string): Promise<string>;
  confirm(question: string, defaultYes?: boolean): Promise<boolean>;
  choose<T = string>(question: string, options: ChoiceOption<T>[]): Promise<T>;
  password(question: string): Promise<string>;
  println(msg?: string): void;
}

export function createPrompter(rl: ReadlineInterface): Prompter {
  return {
    async ask(question: string, defaultValue?: string): Promise<string> {
      const suffix = defaultValue !== undefined ? ` [${defaultValue}]` : '';
      const answer = await rl.question(`${question}${suffix}: `);
      return answer.trim() || defaultValue || '';
    },

    async confirm(question: string, defaultYes = true): Promise<boolean> {
      const hint = defaultYes ? '[Y/n]' : '[y/N]';
      const answer = await rl.question(`${question} ${hint} `);
      const trimmed = answer.trim().toLowerCase();
      if (trimmed === '') {return defaultYes;}
      return trimmed === 'y' || trimmed === 'yes';
    },

    async choose<T = string>(question: string, options: ChoiceOption<T>[]): Promise<T> {
      this.println(question);
      for (let i = 0; i < options.length; i++) {
        this.println(`  ${i + 1}. ${options[i].label}`);
      }
      const answer = await rl.question('> ');
      const idx = parseInt(answer.trim(), 10) - 1;
      if (idx >= 0 && idx < options.length) {return options[idx].value;}
      return options[0].value;
    },

    async password(question: string): Promise<string> {
      const answer = await rl.question(`${question}: `);
      return answer.trim();
    },

    println(msg = ''): void {
      process.stdout.write(msg + '\n');
    },
  };
}
