import { createInterface } from 'node:readline/promises'
import process from 'node:process'

/**
 * Ask a yes/no question on the terminal. Returns `defaultYes` on empty input
 * or when not attached to a TTY (so non-interactive runs never block).
 */
export async function confirmYesNo(
  question: string,
  defaultYes = true,
): Promise<boolean> {
  if (!process.stdin.isTTY) return defaultYes
  const rl = createInterface({ input: process.stdin, output: process.stdout })
  try {
    const hint = defaultYes ? '[Y/n]' : '[y/N]'
    const answer = (await rl.question(`${question} ${hint} `)).trim().toLowerCase()
    if (answer === '') return defaultYes
    return answer === 'y' || answer === 'yes'
  } finally {
    rl.close()
  }
}

/**
 * Read a secret from the terminal without echoing keystrokes. Falls back to a
 * plain line read when stdin is not a TTY, so a piped value still works.
 */
export async function promptSecret(question: string): Promise<string> {
  const stdin = process.stdin
  if (!stdin.isTTY) {
    const rl = createInterface({ input: stdin })
    try {
      for await (const line of rl) return line
      return ''
    } finally {
      rl.close()
    }
  }
  process.stdout.write(question)
  return new Promise<string>((resolve) => {
    let value = ''
    stdin.setRawMode(true)
    stdin.resume()
    stdin.setEncoding('utf8')
    const onData = (chunk: string) => {
      for (const ch of chunk) {
        if (ch === '\n' || ch === '\r' || ch === '') {
          stdin.setRawMode(false)
          stdin.pause()
          stdin.removeListener('data', onData)
          process.stdout.write('\n')
          resolve(value)
          return
        }
        if (ch === '') {
          stdin.setRawMode(false)
          process.stdout.write('\n')
          process.exit(130)
        }
        if (ch === '' || ch === '\b') value = value.slice(0, -1)
        else value += ch
      }
    }
    stdin.on('data', onData)
  })
}
