/**
 * Upfyn-Code CLI — Terminal UI & Animations
 *
 * Beautiful blue-themed terminal experience inspired by Claude Code.
 * Uses terminal-safe characters that render correctly on Windows CMD,
 * PowerShell, Windows Terminal, Git Bash, macOS Terminal, and Linux.
 */

// --- ANSI escape codes ---
const ESC = '\x1b';
const CSI = `${ESC}[`;

// Blue theme palette (24-bit RGB — works in all modern terminals)
const theme = {
  // Core blues
  blue:       `${CSI}38;2;59;130;246m`,   // #3B82F6
  brightBlue: `${CSI}38;2;96;165;250m`,   // #60A5FA
  skyBlue:    `${CSI}38;2;125;211;252m`,   // #7DD3FC
  deepBlue:   `${CSI}38;2;30;58;138m`,    // #1E3A8A
  indigo:     `${CSI}38;2;99;102;241m`,   // #6366F1
  violet:     `${CSI}38;2;139;92;246m`,   // #8B5CF6

  // Accent
  cyan:       `${CSI}38;2;34;211;238m`,   // #22D3EE
  teal:       `${CSI}38;2;45;212;191m`,   // #2DD4BF
  white:      `${CSI}38;2;248;250;252m`,  // #F8FAFC
  gray:       `${CSI}38;2;148;163;184m`,  // #94A3B8
  dimGray:    `${CSI}38;2;71;85;105m`,    // #475569
  darkGray:   `${CSI}38;2;51;65;85m`,     // #334155
  yellow:     `${CSI}38;2;250;204;21m`,   // #FACC15
  green:      `${CSI}38;2;74;222;128m`,   // #4ADE80
  red:        `${CSI}38;2;248;113;113m`,  // #F87171
  orange:     `${CSI}38;2;251;146;60m`,   // #FB923C

  // Background
  bgDeep:     `${CSI}48;2;15;23;42m`,     // #0F172A
  bgBlue:     `${CSI}48;2;30;58;138m`,    // #1E3A8A
  bgBright:   `${CSI}48;2;59;130;246m`,   // #3B82F6

  // Formatting
  bold:       `${CSI}1m`,
  dim:        `${CSI}2m`,
  italic:     `${CSI}3m`,
  underline:  `${CSI}4m`,
  reset:      `${CSI}0m`,
};

const t = theme;
const r = t.reset;

// --- Terminal capability detection ---
function detectTerminalSupport() {
  // Windows Terminal, VS Code, modern terminals support full Unicode
  if (process.env.WT_SESSION) return 'unicode';
  if (process.env.TERM_PROGRAM === 'vscode') return 'unicode';
  if (process.env.TERM_PROGRAM === 'iTerm.app') return 'unicode';
  if (process.env.TERM_PROGRAM === 'Hyper') return 'unicode';
  if (process.env.TERM === 'xterm-256color') return 'unicode';
  if (process.env.TERM === 'xterm-kitty') return 'unicode';
  if (process.env.COLORTERM === 'truecolor') return 'unicode';

  // Windows without WT_SESSION — use ASCII
  if (process.platform === 'win32') return 'ascii';

  // Most modern Linux/Mac terminals support basic box-drawing
  return 'unicode';
}

// Box-drawing character sets
const CHARS_UNICODE = {
  h: '\u2500',   // ─
  v: '\u2502',   // │
  tl: '\u250C',  // ┌
  tr: '\u2510',  // ┐
  bl: '\u2514',  // └
  br: '\u2518',  // ┘
  cross: '\u253C', // ┼
  ltee: '\u251C',  // ├
  rtee: '\u2524',  // ┤
  ttee: '\u252C',  // ┬
  btee: '\u2534',  // ┴
  dot: '\u00B7',   // ·
  bullet: '\u2022', // •
  star: '*',
};

const CHARS_ASCII = {
  h: '-',
  v: '|',
  tl: '+',
  tr: '+',
  bl: '+',
  br: '+',
  cross: '+',
  ltee: '+',
  rtee: '+',
  ttee: '+',
  btee: '+',
  dot: '.',
  bullet: '*',
  star: '*',
};

const termLevel = detectTerminalSupport();
const ch = termLevel === 'unicode' ? CHARS_UNICODE : CHARS_ASCII;

// Helper — colorize
const c = {
  blue:    (s) => `${t.blue}${s}${r}`,
  bright:  (s) => `${t.brightBlue}${s}${r}`,
  sky:     (s) => `${t.skyBlue}${s}${r}`,
  cyan:    (s) => `${t.cyan}${s}${r}`,
  teal:    (s) => `${t.teal}${s}${r}`,
  white:   (s) => `${t.bold}${t.white}${s}${r}`,
  gray:    (s) => `${t.gray}${s}${r}`,
  dim:     (s) => `${t.dimGray}${s}${r}`,
  dark:    (s) => `${t.darkGray}${s}${r}`,
  green:   (s) => `${t.green}${s}${r}`,
  yellow:  (s) => `${t.yellow}${s}${r}`,
  red:     (s) => `${t.red}${s}${r}`,
  orange:  (s) => `${t.orange}${s}${r}`,
  violet:  (s) => `${t.violet}${s}${r}`,
  indigo:  (s) => `${t.indigo}${s}${r}`,
  bold:    (s) => `${t.bold}${s}${r}`,
  bBlue:   (s) => `${t.bold}${t.blue}${s}${r}`,
  bBright: (s) => `${t.bold}${t.brightBlue}${s}${r}`,
  bWhite:  (s) => `${t.bold}${t.white}${s}${r}`,
  bCyan:   (s) => `${t.bold}${t.cyan}${s}${r}`,
};

// --- ASCII Art Logo ---
const LOGO = [
  `${t.brightBlue}    __  __      ____                 ${t.skyBlue} ______          __     ${r}`,
  `${t.brightBlue}   / / / /___  / __/_  ______        ${t.skyBlue}/ ____/___  ____/ /__   ${r}`,
  `${t.brightBlue}  / / / / __ \\/ /_/ / / / __ \\  ${t.blue}____${t.skyBlue}/ /   / __ \\/ __  / _ \\  ${r}`,
  `${t.brightBlue} / /_/ / /_/ / __/ /_/ / / / / ${t.blue}/___ ${t.skyBlue}/ /___/ /_/ / /_/ /  __/  ${r}`,
  `${t.brightBlue} \\____/ .___/_/  \\__, /_/ /_/       ${t.skyBlue}\\____/\\____/\\__,_/\\___/   ${r}`,
  `${t.brightBlue}     /_/       /____/                                          ${r}`,
];

// --- Rocket ASCII Art (safe characters only) ---
const ROCKET_FRAMES = [
  // Frame 0: Pre-launch
  [
    `         ${t.dimGray}|${r}`,
    `        ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
    `       ${t.white}|${t.blue}||${t.white}|${r}`,
    `       ${t.white}|${t.blue}||${t.white}|${r}`,
    `       ${t.white}|${t.brightBlue}||${t.white}|${r}`,
    `      ${t.white}/${t.blue}|||${t.white}\\${r}`,
    `     ${t.white}/${t.blue}=====${t.white}\\${r}`,
    `    ${t.dimGray}==========${r}`,
  ],
  // Frame 1: Ignition
  [
    `         ${t.dimGray}|${r}`,
    `        ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
    `       ${t.white}|${t.blue}||${t.white}|${r}`,
    `       ${t.white}|${t.blue}||${t.white}|${r}`,
    `       ${t.white}|${t.brightBlue}||${t.white}|${r}`,
    `      ${t.white}/${t.blue}|||${t.white}\\${r}`,
    `     ${t.white}/${t.blue}=====${t.white}\\${r}`,
    `      ${t.orange}#${t.yellow}*${t.orange}#${t.yellow}*${t.orange}#${r}`,
  ],
  // Frame 2: Lift-off
  [
    `        ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
    `       ${t.white}|${t.blue}||${t.white}|${r}`,
    `       ${t.white}|${t.blue}||${t.white}|${r}`,
    `       ${t.white}|${t.brightBlue}||${t.white}|${r}`,
    `      ${t.white}/${t.blue}|||${t.white}\\${r}`,
    `     ${t.white}/${t.blue}=====${t.white}\\${r}`,
    `      ${t.yellow}#${t.orange}@${t.yellow}#${t.orange}@${t.yellow}#${r}`,
    `       ${t.orange}*${t.yellow}o${t.orange}*${r}`,
  ],
  // Frame 3: Ascending
  [
    `        ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
    `       ${t.white}|${t.blue}||${t.white}|${r}`,
    `       ${t.white}|${t.brightBlue}||${t.white}|${r}`,
    `      ${t.white}/${t.blue}|||${t.white}\\${r}`,
    `     ${t.white}/${t.blue}=====${t.white}\\${r}`,
    `      ${t.yellow}@${t.orange}#${t.yellow}@${t.orange}#${t.yellow}@${r}`,
    `       ${t.orange}#${t.yellow}@${t.orange}#${r}`,
    `        ${t.yellow}*${t.orange}*${r}`,
  ],
  // Frame 4: Full thrust
  [
    `        ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
    `       ${t.white}|${t.blue}||${t.white}|${r}`,
    `       ${t.white}|${t.brightBlue}||${t.white}|${r}`,
    `      ${t.white}/${t.blue}|||${t.white}\\${r}`,
    `     ${t.white}/${t.blue}=====${t.white}\\${r}`,
    `     ${t.yellow}@${t.orange}#${t.yellow}@${t.orange}#${t.yellow}@${t.orange}#${r}`,
    `      ${t.orange}#${t.yellow}@${t.orange}#${t.yellow}@${r}`,
    `       ${t.yellow}o${t.orange}*${t.yellow}o${r}`,
    `        ${t.orange}*${t.yellow}*${r}`,
  ],
  // Frame 5: Going up
  [
    ``,
    `        ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
    `       ${t.white}|${t.blue}||${t.white}|${r}`,
    `      ${t.white}/${t.blue}|||${t.white}\\${r}`,
    `     ${t.white}/${t.blue}=====${t.white}\\${r}`,
    `     ${t.yellow}@${t.orange}#${t.yellow}@${t.orange}#${t.yellow}@${t.orange}#${r}`,
    `      ${t.orange}@${t.yellow}#${t.orange}@${t.yellow}#${r}`,
    `       ${t.yellow}o${t.orange}o${t.yellow}o${r}`,
    `        ${t.orange}*${r}  ${t.dimGray}.${r}`,
  ],
  // Frame 6: Higher
  [
    ``,
    ``,
    `        ${t.skyBlue}/${t.brightBlue}^${t.skyBlue}\\${r}`,
    `       ${t.skyBlue}|${t.blue}||${t.skyBlue}|${r}`,
    `      ${t.skyBlue}/${t.blue}==${t.skyBlue}\\${r}`,
    `      ${t.yellow}#${t.orange}@${t.yellow}#${t.orange}#${r}`,
    `       ${t.orange}o${t.yellow}o${r}`,
    `        ${t.yellow}*${r}`,
    `        ${t.dimGray}.${r}   ${t.dimGray}.${r}`,
  ],
  // Frame 7: Almost gone
  [
    ``,
    ``,
    ``,
    `        ${t.skyBlue}/${t.brightBlue}^${t.skyBlue}\\${r}`,
    `       ${t.blue}==${r}`,
    `       ${t.orange}o${t.yellow}o${r}`,
    `        ${t.yellow}*${r}`,
    ``,
    `     ${t.dimGray}.${r}      ${t.dimGray}.${r}  ${t.dimGray}.${r}`,
  ],
  // Frame 8: Gone — just stars
  [
    ``,
    ``,
    ``,
    `        ${t.brightBlue}*${r}`,
    ``,
    `       ${t.dimGray}.${r}`,
    ``,
    `  ${t.dimGray}.${r}          ${t.dimGray}.${r}`,
    `     ${t.dimGray}.${r}    ${t.dimGray}.${r}      ${t.dimGray}.${r}`,
  ],
];

// --- Sleep utility ---
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

// --- Clear screen ---
const clearScreen = () => process.stdout.write(`${CSI}2J${CSI}H`);

// --- Move cursor ---
const moveTo = (row, col) => process.stdout.write(`${CSI}${row};${col}H`);

// --- Hide/show cursor ---
const hideCursor = () => process.stdout.write(`${CSI}?25l`);
const showCursor = () => process.stdout.write(`${CSI}?25h`);

/**
 * Strip ANSI codes for length calculation
 */
function stripAnsi(str) {
  return str.replace(/\x1b\[[0-9;]*m/g, '');
}

/**
 * Pad a string (with ANSI codes) to a visual width
 */
function padAnsi(str, width) {
  const visible = stripAnsi(str).length;
  const pad = Math.max(0, width - visible);
  return str + ' '.repeat(pad);
}

/**
 * Draw a horizontal line
 */
function hLine(width = 60) {
  return c.dark(ch.h.repeat(width));
}

/**
 * Play the rocket launch animation
 */
async function playRocketAnimation() {
  hideCursor();
  clearScreen();

  const cols = process.stdout.columns || 80;
  const centerX = Math.floor(cols / 2) - 12;

  // Show pre-launch text
  moveTo(2, centerX - 5);
  process.stdout.write(c.dim('Initializing Upfyn-Code...'));

  await sleep(400);

  // Play each frame
  const delays = [500, 300, 200, 150, 120, 120, 150, 200, 400];

  for (let f = 0; f < ROCKET_FRAMES.length; f++) {
    // Clear the animation area (rows 4-14)
    for (let row = 4; row <= 14; row++) {
      moveTo(row, 1);
      process.stdout.write(' '.repeat(cols));
    }

    const frame = ROCKET_FRAMES[f];
    for (let i = 0; i < frame.length; i++) {
      moveTo(4 + i, centerX);
      process.stdout.write(frame[i]);
    }

    // Status text under animation
    moveTo(14, centerX - 2);
    if (f === 0) process.stdout.write(c.dim('Systems check...'));
    else if (f === 1) process.stdout.write(c.orange('Ignition sequence started'));
    else if (f === 2) process.stdout.write(c.yellow('Lift-off!'));
    else if (f <= 4) process.stdout.write(c.bright('Ascending...'));
    else if (f <= 6) process.stdout.write(c.sky('Reaching orbit...'));
    else if (f === 7) process.stdout.write(c.cyan('Entering space...'));
    else process.stdout.write(c.bBright('Ready to code! *'));

    await sleep(delays[f] || 200);
  }

  await sleep(300);
  showCursor();
}

/**
 * Draw a box with title (terminal-safe characters)
 */
function box(title, content, width = 58) {
  const lines = [];
  const inner = width - 4;

  lines.push(`  ${t.dimGray}${ch.tl}${ch.h}${r} ${c.bBright(title)} ${t.dimGray}${ch.h.repeat(Math.max(0, inner - title.length - 1))}${ch.tr}${r}`);

  for (const line of content) {
    lines.push(`  ${t.dimGray}${ch.v}${r} ${line}`);
  }

  lines.push(`  ${t.dimGray}${ch.bl}${ch.h.repeat(width - 2)}${ch.br}${r}`);
  return lines;
}

/**
 * Show the main welcome screen (Claude Code-style layout)
 */
function showWelcomeScreen(version, options = {}) {
  const cols = process.stdout.columns || 80;
  const { serverUrl, username, cwd, isConnected } = options;
  const W = Math.min(cols - 4, 72); // content width
  const leftW = 32;
  const rightW = W - leftW - 3; // 3 for separator + padding

  clearScreen();

  const lines = [];

  // --- Top border with version ---
  const verStr = `Upfyn-Code v${version}`;
  const topPad = Math.max(0, W - verStr.length - 4);
  lines.push('');
  lines.push(`  ${t.dimGray}${ch.h}${ch.h} ${r}${c.bBright(verStr)}${t.dimGray} ${ch.h.repeat(topPad)}${r}`);
  lines.push('');

  // --- Build left and right panels ---
  const leftPanel = [];
  const rightPanel = [];

  // Left: Welcome + Rocket mascot
  leftPanel.push(c.bWhite('  Welcome back!'));
  leftPanel.push('');
  leftPanel.push(`      ${t.dimGray}|${r}`);
  leftPanel.push(`     ${t.white}/${t.brightBlue}^${t.white}\\${r}`);
  leftPanel.push(`    ${t.white}|${t.blue}|${t.brightBlue}o${t.blue}|${t.white}|${r}`);
  leftPanel.push(`    ${t.white}|${t.blue}||${t.white}|${r}`);
  leftPanel.push(`   ${t.white}/${t.blue}===${t.white}\\${r}`);
  leftPanel.push(`   ${t.cyan}~~~~~${r}`);
  leftPanel.push('');
  if (username) {
    leftPanel.push(`  ${c.gray('User:')} ${c.bright(username)}`);
  }
  leftPanel.push(`  ${c.gray('Path:')} ${c.dim(cwd || process.cwd())}`);

  // Right: Tips + Recent Activity
  rightPanel.push(`  ${c.bCyan('Tips for getting started')}`);
  rightPanel.push(`  ${c.gray('Run')} ${c.bright('uc connect')} ${c.gray('to bridge to web UI')}`);
  rightPanel.push(`  ${c.gray('Run')} ${c.bright('uc start')} ${c.gray('to launch local server')}`);
  rightPanel.push(`  ${c.gray('Run')} ${c.bright('uc status')} ${c.gray('to see configuration')}`);
  rightPanel.push(`  ${c.gray('Run')} ${c.bright('uc help')} ${c.gray('for all commands')}`);
  rightPanel.push('');
  rightPanel.push(`  ${c.bCyan('Recent activity')}`);
  if (isConnected) {
    rightPanel.push(`  ${c.green('*')} Connected to ${c.bright(serverUrl || 'server')}`);
  } else {
    rightPanel.push(`  ${c.dim('No active connection')}`);
  }
  rightPanel.push('');
  if (serverUrl) {
    rightPanel.push(`  ${c.gray('Server:')} ${c.cyan(serverUrl)}`);
  }

  // Merge panels side by side
  const maxRows = Math.max(leftPanel.length, rightPanel.length);

  for (let i = 0; i < maxRows; i++) {
    const left = padAnsi(leftPanel[i] || '', leftW);
    const right = rightPanel[i] || '';
    lines.push(`${left}${t.dimGray}${ch.v}${r} ${right}`);
  }

  lines.push('');

  // --- Bottom border ---
  lines.push(`  ${t.dimGray}${ch.h.repeat(W)}${r}`);
  lines.push('');

  // --- Status bar ---
  const statusItems = [];
  if (isConnected) {
    statusItems.push(`${t.green}* Connected${r}`);
  } else {
    statusItems.push(`${t.dimGray}o Not connected${r}`);
  }
  statusItems.push(`${t.gray}v${version}${r}`);

  lines.push(`  ${statusItems.join(`  ${t.dimGray}${ch.dot}${r}  `)}`);
  lines.push('');

  // --- Input prompt area (between two lines like Claude Code) ---
  lines.push(`  ${t.dimGray}${ch.h.repeat(W)}${r}`);
  lines.push(`  ${t.brightBlue}>${r} ${c.dim('Type a command or use /upfynai-connect ...')}`);
  lines.push(`  ${t.dimGray}${ch.h.repeat(W)}${r}`);
  lines.push('');

  process.stdout.write(lines.join('\n') + '\n');
}

/**
 * Show connection success banner
 */
function showConnectionBanner(username, serverUrl) {
  const W = 50;
  const lines = [];
  const bLine = (content) => `  ${t.green}${ch.v}${r}${padAnsi(content, W)}${t.green}${ch.v}${r}`;
  lines.push('');
  lines.push(`  ${t.green}${ch.tl}${ch.h.repeat(W)}${ch.tr}${r}`);
  lines.push(bLine(`  ${c.green('OK')} ${c.bWhite('Connected successfully!')}`));
  lines.push(bLine(''));
  lines.push(bLine(`  ${c.gray('User:')}    ${c.bright(username || 'Unknown')}`));
  lines.push(bLine(`  ${c.gray('Server:')}  ${c.cyan(serverUrl || 'Unknown')}`));
  lines.push(bLine(''));
  lines.push(bLine(`  ${c.dim('Your machine is bridged to the web UI.')}`));
  lines.push(bLine(`  ${c.dim('Press Ctrl+C to disconnect.')}`));
  lines.push(`  ${t.green}${ch.bl}${ch.h.repeat(W)}${ch.br}${r}`);
  lines.push('');

  process.stdout.write(lines.join('\n') + '\n');
}

/**
 * Show a spinner with message
 */
function createSpinner(message) {
  const frames = ['/', '-', '\\', '|'];
  let i = 0;
  let interval;

  return {
    start() {
      hideCursor();
      interval = setInterval(() => {
        const frame = frames[i % frames.length];
        process.stdout.write(`\r  ${t.brightBlue}${frame}${r} ${c.gray(message)}`);
        i++;
      }, 100);
    },
    stop(finalMessage) {
      clearInterval(interval);
      process.stdout.write(`\r  ${c.green('OK')} ${c.white(finalMessage || message)}${''.padEnd(20)}\n`);
      showCursor();
    },
    fail(finalMessage) {
      clearInterval(interval);
      process.stdout.write(`\r  ${c.red('FAIL')} ${c.red(finalMessage || message)}${''.padEnd(20)}\n`);
      showCursor();
    }
  };
}

/**
 * Show styled help
 */
function showStyledHelp(version) {
  const W = 60;
  const lines = [];

  lines.push('');
  // Header box — build each line to exactly W visible chars inside the borders
  const hdrLine1 = `    ${c.bBright('Upfyn-Code')} ${c.dim('--')} ${c.gray('by Thinqmesh Technologies')}`;
  const hdrLine2 = `    ${c.dim('Visual AI Coding Interface with Upfyn-Canvas')}`;
  lines.push(`  ${t.brightBlue}${ch.tl}${ch.h.repeat(W)}${ch.tr}${r}`);
  lines.push(`  ${t.brightBlue}${ch.v}${r}${padAnsi(hdrLine1, W)}${t.brightBlue}${ch.v}${r}`);
  lines.push(`  ${t.brightBlue}${ch.v}${r}${padAnsi(hdrLine2, W)}${t.brightBlue}${ch.v}${r}`);
  lines.push(`  ${t.brightBlue}${ch.bl}${ch.h.repeat(W)}${ch.br}${r}`);
  lines.push('');

  // Usage
  lines.push(`  ${c.bBright('Usage:')}`);
  lines.push(`    ${c.bright('uc')} ${c.cyan('[command]')} ${c.dim('[options]')}`);
  lines.push('');

  // Commands
  lines.push(`  ${c.bBright('Commands:')}`);
  const cmds = [
    ['(default)',            'Launch Claude Code with Upfyn branding'],
    ['start',              'Start the local server (web UI)'],
    ['stop',               'Stop a running server'],
    ['connect',            'Connect local machine to hosted server'],
    ['config',             'View/set configuration (API key, etc.)'],
    ['status',             'Show configuration and data locations'],
    ['install-commands',   'Install /upfynai-* slash commands'],
    ['uninstall-commands', 'Remove /upfynai-* slash commands'],
    ['update',             'Update to the latest version'],
    ['reset',              'Clear local database (fresh start)'],
    ['uninstall',          'Remove all data, config, and slash commands'],
    ['help',               'Show this help information'],
    ['version',            'Show version information'],
  ];
  for (const [cmd, desc] of cmds) {
    lines.push(`    ${c.cyan(cmd.padEnd(22))} ${c.gray(desc)}`);
  }
  lines.push('');

  // Slash Commands
  lines.push(`  ${c.bBright('Slash Commands')} ${c.dim('(inside Claude Code CLI):')}`);
  const slashCmds = [
    ['/upfynai',            'Start the web UI server'],
    ['/upfynai-connect',    'Connect CLI session to web UI'],
    ['/upfynai-disconnect', 'Disconnect from web UI'],
    ['/upfynai-status',     'Show connection status'],
    ['/upfynai-doctor',     'Run diagnostics'],
  ];
  for (const [cmd, desc] of slashCmds) {
    lines.push(`    ${c.violet(cmd.padEnd(22))} ${c.gray(desc)}`);
  }
  lines.push('');

  // Options
  lines.push(`  ${c.bBright('Options:')}`);
  const opts = [
    ['-p, --port <port>',         'Set server port (default: 3001)'],
    ['--server <url>',            'Server URL for connect'],
    ['--key <token>',             'Relay token for connect'],
    ['--api-key <key>',           'Set Anthropic API key'],
    ['--database-path <path>',    'Custom database location'],
    ['-h, --help',                'Show help'],
    ['-v, --version',             'Show version'],
  ];
  for (const [opt, desc] of opts) {
    lines.push(`    ${c.yellow(opt.padEnd(28))} ${c.gray(desc)}`);
  }
  lines.push('');

  // Examples
  lines.push(`  ${c.bBright('Examples:')}`);
  lines.push(`    ${c.dim('$')} ${c.bright('uc')}                              ${c.dim('# Launch Claude Code')}`);
  lines.push(`    ${c.dim('$')} ${c.bright('uc connect --key upfyn_xxx')}      ${c.dim('# Bridge to hosted server')}`);
  lines.push(`    ${c.dim('$')} ${c.bright('uc config --api-key sk-ant-xxx')}  ${c.dim('# Save Anthropic API key')}`);
  lines.push(`    ${c.dim('$')} ${c.bright('uc start --port 8080')}            ${c.dim('# Start on port 8080')}`);
  lines.push(`    ${c.dim('$')} ${c.bright('uc status')}                       ${c.dim('# Show configuration')}`);
  lines.push('');

  // Footer
  lines.push(`  ${c.dim('Documentation:')} ${c.cyan('https://cli.upfyn.com/docs')}`);
  lines.push(`  ${c.dim('Report Issues:')} ${c.cyan('https://github.com/thinqmesh/upfynai-code/issues')}`);
  lines.push('');

  process.stdout.write(lines.join('\n') + '\n');
}

/**
 * Show styled status
 */
function showStyledStatus(info) {
  const lines = [];

  lines.push('');
  lines.push(`  ${c.bBright('Upfyn-Code')} ${c.dim('-- Status')}`);
  lines.push(`  ${c.dark('='.repeat(50))}`);
  lines.push('');

  // Version
  lines.push(`  ${c.bright('Version')}     ${c.white(info.version)}`);
  lines.push('');

  // Installation
  lines.push(`  ${c.bright('Install')}     ${c.dim(info.installDir)}`);
  lines.push(`  ${c.bright('Database')}    ${c.dim(info.dbPath)}`);
  if (info.dbExists) {
    lines.push(`              ${c.green('OK')} ${c.gray(`Exists (${info.dbSize})`)}`);
  } else {
    lines.push(`              ${c.yellow('--')} ${c.gray('Not created yet')}`);
  }
  lines.push('');

  // Server status
  if (info.serverRunning) {
    lines.push(`  ${c.bright('Server')}      ${c.green('Running')} ${c.dim(`(PID ${info.serverRunning}, port ${info.port})`)}`);
  } else {
    lines.push(`  ${c.bright('Server')}      ${c.dim('Stopped')}`);
  }
  lines.push('');

  // Configuration
  lines.push(`  ${c.bright('Config')}`);
  lines.push(`    ${c.gray('PORT')}          ${c.cyan(info.port)} ${info.portDefault ? c.dim('(default)') : ''}`);
  lines.push(`    ${c.gray('DATABASE')}      ${c.dim(info.dbPath)}`);
  lines.push(`    ${c.gray('CLI')}           ${c.dim(info.claudeCli || 'claude (default)')}`);
  if (info.apiKey) {
    lines.push(`    ${c.gray('API KEY')}       ${c.green('Set')} ${c.dim('(sk-ant-...' + info.apiKey.slice(-4) + ')')}`);
  }
  lines.push('');

  // Bottom
  lines.push(`  ${c.dark('='.repeat(50))}`);
  lines.push('');
  lines.push(`  ${c.bCyan('Tips:')}`);
  lines.push(`    ${c.dim('>')} Use ${c.bright('uc start')} to start the local web UI`);
  lines.push(`    ${c.dim('>')} Use ${c.bright('uc stop')} to stop the server`);
  lines.push(`    ${c.dim('>')} Use ${c.bright('uc connect --key upfyn_xxx')} to bridge to web UI`);
  lines.push(`    ${c.dim('>')} Use ${c.bright('uc config --api-key sk-ant-xxx')} to save your API key`);
  lines.push(`    ${c.dim('>')} Use ${c.bright('uc help')} for all commands`);
  lines.push('');

  process.stdout.write(lines.join('\n') + '\n');
}

/**
 * Show server startup banner
 */
function showServerBanner(port, version) {
  const lines = [];

  lines.push('');
  for (const line of LOGO) lines.push(`  ${line}`);
  lines.push('');
  lines.push(`  ${c.dim('v' + version)}  ${c.dim('--')}  ${c.gray('by Thinqmesh Technologies')}`);
  lines.push('');
  lines.push(`  ${c.dark(ch.h.repeat(52))}`);
  lines.push('');
  lines.push(`  ${c.green('*')} ${c.bWhite('Server running')} ${c.gray('on')} ${c.bCyan(`http://localhost:${port}`)}`);
  lines.push('');
  lines.push(`  ${c.dim('Press Ctrl+C to stop.')}`);
  lines.push('');

  process.stdout.write(lines.join('\n') + '\n');
}

/**
 * Show connect startup with animation
 */
async function showConnectStartup(serverUrl, machine, user, version) {
  await playRocketAnimation();

  clearScreen();

  const lines = [];

  lines.push('');
  for (const line of LOGO) lines.push(`  ${line}`);
  lines.push('');
  lines.push(`  ${c.dim('v' + version)}  ${c.dim('--')}  ${c.gray('Relay Client')}`);
  lines.push('');
  lines.push(`  ${c.dark(ch.h.repeat(52))}`);
  lines.push('');
  lines.push(`  ${c.gray('Server:')}   ${c.cyan(serverUrl)}`);
  lines.push(`  ${c.gray('Machine:')}  ${c.dim(machine)}`);
  lines.push(`  ${c.gray('User:')}     ${c.dim(user)}`);
  lines.push('');

  process.stdout.write(lines.join('\n') + '\n');
}

/**
 * Show interactive launch screen (before spawning Claude Code)
 */
function showLaunchScreen(version, claudeBin, options = {}) {
  const cols = process.stdout.columns || 80;
  const W = Math.min(cols - 4, 72);

  const lines = [];

  lines.push('');
  for (const line of LOGO) lines.push(`  ${line}`);
  lines.push('');
  lines.push(`  ${c.dim('v' + version)}  ${c.dim('--')}  ${c.gray('by Thinqmesh Technologies')}`);
  lines.push('');
  lines.push(`  ${c.dark(ch.h.repeat(W))}`);
  lines.push('');

  if (claudeBin) {
    lines.push(`  ${c.green('*')} ${c.bWhite('Claude Code detected:')} ${c.dim(claudeBin)}`);
  }
  if (options.relayStatus) {
    lines.push(`  ${c.green('*')} ${c.bWhite('Relay:')} ${c.dim(options.relayStatus)}`);
  }
  if (options.apiKey) {
    lines.push(`  ${c.green('*')} ${c.bWhite('API Key:')} ${c.dim('Configured')}`);
  }
  lines.push('');

  if (claudeBin) {
    lines.push(`  ${c.dim('Launching Claude Code...')}`);
    lines.push(`  ${c.dim('Slash commands available: /upfynai-connect, /upfynai-status')}`);
  } else {
    lines.push(`  ${c.yellow('!')} ${c.white('Claude Code CLI not found on PATH')}`);
    lines.push('');
    lines.push(`  ${c.gray('Install Claude Code:')}`);
    lines.push(`    ${c.bright('npm install -g @anthropic-ai/claude-code')}`);
    lines.push('');
    lines.push(`  ${c.gray('Or start the server instead:')}`);
    lines.push(`    ${c.bright('uc start')}`);
  }
  lines.push('');
  lines.push(`  ${c.dark(ch.h.repeat(W))}`);
  lines.push('');

  process.stdout.write(lines.join('\n') + '\n');
}

/**
 * Show config display
 */
function showConfig(config) {
  const lines = [];
  lines.push('');
  lines.push(`  ${c.bBright('Upfyn-Code')} ${c.dim('-- Configuration')}`);
  lines.push(`  ${c.dark('='.repeat(50))}`);
  lines.push('');

  lines.push(`  ${c.gray('Server')}        ${config.server ? c.cyan(config.server) : c.dim('(not set)')}`);
  lines.push(`  ${c.gray('Relay Key')}     ${config.relayKey ? c.green('Set') + ' ' + c.dim('(' + config.relayKey.slice(0, 10) + '...)') : c.dim('(not set)')}`);
  lines.push(`  ${c.gray('API Key')}       ${config.anthropicApiKey ? c.green('Set') + ' ' + c.dim('(sk-ant-...' + config.anthropicApiKey.slice(-4) + ')') : c.dim('(not set)')}`);
  lines.push('');
  lines.push(`  ${c.gray('Config file:')}  ${c.dim(config._path || '~/.upfynai/config.json')}`);
  lines.push('');

  lines.push(`  ${c.bCyan('Set values:')}`);
  lines.push(`    ${c.dim('$')} ${c.bright('uc config --api-key sk-ant-xxx')}    ${c.dim('# Save Anthropic API key')}`);
  lines.push(`    ${c.dim('$')} ${c.bright('uc config --clear-api-key')}         ${c.dim('# Remove API key')}`);
  lines.push(`    ${c.dim('$')} ${c.bright('uc connect --server <url> --key <token>')}`);
  lines.push('');

  process.stdout.write(lines.join('\n') + '\n');
}

/**
 * Log a relay event with icon
 */
function logRelayEvent(icon, message, color = 'gray') {
  const colorFn = c[color] || c.gray;
  const timestamp = new Date().toLocaleTimeString('en-US', { hour12: false });
  console.log(`  ${c.dim(timestamp)}  ${icon}  ${colorFn(message)}`);
}

export {
  theme,
  c,
  ch,
  LOGO,
  detectTerminalSupport,
  playRocketAnimation,
  showWelcomeScreen,
  showConnectionBanner,
  showStyledHelp,
  showStyledStatus,
  showServerBanner,
  showConnectStartup,
  showLaunchScreen,
  showConfig,
  logRelayEvent,
  createSpinner,
  hideCursor,
  showCursor,
  clearScreen,
  sleep,
  hLine,
  box,
  stripAnsi,
  padAnsi,
};
