import { createInterface } from 'node:readline';
import { signIn, saveSession } from '../../auth.js';
import { readMeta } from './daemon.js';

/**
 * Prompt for a single line of input (with echo).
 */
export function promptLine(question: string): Promise<string> {
  const rl = createInterface({ input: process.stdin, output: process.stdout });
  return new Promise((resolve) => {
    rl.question(question, (answer) => {
      rl.close();
      resolve(answer.trim());
    });
  });
}

/**
 * Prompt for a secret value without echoing the typed characters to the terminal.
 * Uses TTY raw mode when available so that passwords do not appear in terminal
 * recordings, scrollback, or shared screen sessions.
 */
export function promptSecret(question: string): Promise<string> {
  return new Promise((resolve) => {
    process.stdout.write(question);
    if (process.stdin.isTTY) {
      process.stdin.setRawMode(true);
    }
    process.stdin.resume();
    process.stdin.setEncoding('utf-8');

    let secret = '';
    const onData = (char: string): void => {
      if (char === '\n' || char === '\r' || char === '\u0004') {
        process.stdout.write('\n');
        if (process.stdin.isTTY) {
          process.stdin.setRawMode(false);
        }
        process.stdin.pause();
        process.stdin.removeListener('data', onData);
        resolve(secret);
      } else if (char === '\u0003') {
        // ^C
        process.stdout.write('\n');
        if (process.stdin.isTTY) {
          process.stdin.setRawMode(false);
        }
        process.stdin.pause();
        process.stdin.removeListener('data', onData);
        process.exit(130);
      } else if (char === '\u007f' || char === '\b') {
        secret = secret.slice(0, -1);
      } else {
        secret += char;
      }
    };
    process.stdin.on('data', onData);
  });
}

/**
 * Shared login helper used by both `mosaic login` and `mosaic gateway login`.
 * Prompts for email/password if not supplied, signs in, and persists the session.
 */
export async function runLogin(opts: {
  gatewayUrl: string;
  email?: string;
  password?: string;
}): Promise<void> {
  const email = opts.email ?? (await promptLine('Email: '));
  // Do not trim password — it may intentionally contain leading/trailing whitespace
  const password = opts.password ?? (await promptSecret('Password: '));

  const auth = await signIn(opts.gatewayUrl, email, password);
  saveSession(opts.gatewayUrl, auth);
  console.log(`Signed in as ${auth.email} (${opts.gatewayUrl})`);
}

/**
 * Derive the gateway base URL from meta.json with a fallback.
 */
export function getGatewayUrl(overrideUrl?: string): string {
  if (overrideUrl) return overrideUrl;
  const meta = readMeta();
  if (meta) return `http://${meta.host}:${meta.port.toString()}`;
  return 'http://localhost:14242';
}
