/**
 * Interactive setup utilities — new-user detection, prompts, browser open, handoff.
 * Uses only Node.js built-ins; no new runtime dependencies.
 */
import readline from 'readline';
import { execSync } from 'child_process';
import { readSetupMarker } from './install-wizard.js';
const ANSI = {
    cyan: '\x1b[36m',
    green: '\x1b[32m',
    yellow: '\x1b[33m',
    magenta: '\x1b[35m',
    dim: '\x1b[2m',
    bold: '\x1b[1m',
    reset: '\x1b[0m',
};
const tty = () => process.stdout.isTTY === true && !process.env.NO_COLOR;
const c = (s, k) => tty() ? `${ANSI[k]}${s}${ANSI.reset}` : s;
const log = (s) => process.stdout.write(s + '\n');
/** Single-line readline prompt. Returns empty string in non-TTY environments. */
export async function promptLine(question) {
    if (!tty())
        return '';
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
        terminal: true,
    });
    return new Promise(resolve => {
        rl.question(question, ans => {
            rl.close();
            resolve(ans.trim());
        });
    });
}
/**
 * Keystroke-level prompt — shows question and waits for one of `validKeys`.
 * Falls back to validKeys[0] in non-TTY or CI environments.
 */
export async function promptKey(question, validKeys) {
    if (!tty() || process.env.CI)
        return validKeys[0];
    process.stdout.write(question);
    return new Promise(resolve => {
        const stdin = process.stdin;
        const wasRaw = stdin.isRaw;
        if (stdin.setRawMode)
            stdin.setRawMode(true);
        stdin.resume();
        stdin.setEncoding('utf8');
        const handler = (key) => {
            const k = key.toLowerCase();
            const normalized = (k === '\r' || k === '\n') ? '\r' : k;
            if (validKeys.includes(normalized) || validKeys.includes(k)) {
                if (stdin.setRawMode)
                    stdin.setRawMode(wasRaw ?? false);
                stdin.pause();
                stdin.removeListener('data', handler);
                process.stdout.write('\n');
                resolve(validKeys.includes(k) ? k : validKeys[0]);
            }
            else if (key === '\u0003') {
                process.stdout.write('\n');
                process.exit(0);
            }
        };
        stdin.on('data', handler);
    });
}
/** Open browser cross-platform. Non-fatal on error. */
export function openBrowser(url) {
    try {
        const cmd = process.platform === 'darwin' ? `open "${url}"`
            : process.platform === 'win32' ? `start "" "${url}"`
                : `xdg-open "${url}"`;
        execSync(cmd, { stdio: 'ignore', timeout: 3000 });
    }
    catch { /* non-fatal */ }
}
/** True when no setup marker exists → first install. */
export function isNewUser() {
    return readSetupMarker() === null;
}
/**
 * Interactive license key prompt shown to new users on the free tier.
 * Returns the entered key or null if user chose to skip.
 */
export async function promptLicenseKey(currentTier = 'free') {
    if (!tty() || currentTier !== 'free')
        return null;
    log('');
    log(c('  ┌─ LICENSE ──────────────────────────────────────────────────┐', 'magenta'));
    log(c('  │', 'magenta') + '  You\'re on the ' + c('Free', 'yellow') + ' plan.                                    ' + c('│', 'magenta'));
    log(c('  │', 'magenta') + '  Get a license at ' + c('nexus-prime.cfd/license', 'cyan') + '              ' + c('│', 'magenta'));
    log(c('  └────────────────────────────────────────────────────────────┘', 'magenta'));
    log('');
    const choice = await promptKey(`  ${c('[L]', 'yellow')} Enter license key   ${c('[S]', 'dim')} Skip for now   › `, ['l', 's']);
    if (choice === 'l') {
        const key = await promptLine(`\n  ${c('License key', 'cyan')}: `);
        if (key.length > 4)
            return key;
        log(`  ${c('(skipped — key too short)', 'dim')}`);
    }
    return null;
}
/** Print post-install handoff banner with dashboard URL and quick-start commands. */
export function printHandoffBanner(dashUrl, opts = {}) {
    const bdr = '═'.repeat(62);
    const row = (label, val) => {
        const content = `  ${label.padEnd(12)} → ${val}`;
        return c('║', 'cyan') + content.padEnd(64) + c('║', 'cyan');
    };
    const div = c('╠' + '─'.repeat(62) + '╣', 'dim');
    log('');
    log(c(`╔${bdr}╗`, 'cyan'));
    log(c('║', 'cyan') + c('  ⚡ NEXUS PRIME · CONTROL PLANE ONLINE', 'bold').padEnd(75) + c('║', 'cyan'));
    log(div);
    log(row(c('Dashboard', 'yellow'), c(dashUrl, 'cyan')));
    if (opts.isNew) {
        log(row(c('Onboarding', 'yellow'), c(dashUrl + '/welcome', 'cyan')));
    }
    log(div);
    log(row(c('Orchestrate', 'dim'), 'nexus-prime orchestrate "<goal>"'));
    log(row(c('Status', 'dim'), 'nexus-prime status'));
    log(row(c('Hire', 'dim'), 'nexus-prime setup auto (re-run anytime)'));
    log(c(`╚${bdr}╝`, 'cyan'));
    log('');
}
/** Print a compact banner for returning users showing last-setup info. */
export function printReturningUserBanner(marker) {
    const ago = Math.round((Date.now() - marker.setupCompletedAt) / 86_400_000);
    const agoStr = ago < 1 ? 'today' : ago === 1 ? 'yesterday' : `${ago}d ago`;
    log('');
    log(c('  ┌─ EXISTING INSTALLATION ─────────────────────────────────────┐', 'dim'));
    log(c('  │', 'dim') + `  Last setup : ${c(agoStr.padEnd(48, ' '), 'cyan')}` + c('│', 'dim'));
    log(c('  │', 'dim') + `  IDEs       : ${c(marker.configuredIDEs.join(', ').substring(0, 48).padEnd(48, ' '), 'cyan')}` + c('│', 'dim'));
    log(c('  └─────────────────────────────────────────────────────────────┘', 'dim'));
    log('');
}
/**
 * Animated "syncing" spinner that resolves when the provided promise resolves.
 * Falls back to simple await in non-TTY environments.
 */
export async function withSpinner(label, work) {
    if (!tty())
        return work;
    const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
    let i = 0;
    const interval = setInterval(() => {
        process.stdout.write(`\r  ${c(frames[i++ % frames.length], 'cyan')} ${label}  `);
    }, 80);
    try {
        const result = await work;
        clearInterval(interval);
        process.stdout.write(`\r  ${c('✓', 'green')} ${label}          \n`);
        return result;
    }
    catch (err) {
        clearInterval(interval);
        process.stdout.write(`\r  ${c('✗', 'yellow')} ${label}          \n`);
        throw err;
    }
}
