/**
 * CLI Output Utilities
 * Provides colorized, formatted output for the CLI
 */

import chalk from 'chalk';
import ora, { Ora } from 'ora';

/**
 * Success message (green checkmark)
 */
export function success(message: string): void {
  console.log(chalk.green('✓') + ' ' + message);
}

/**
 * Error message (red X)
 */
export function error(message: string): void {
  console.log(chalk.red('✗') + ' ' + chalk.red(message));
}

/**
 * Warning message (yellow warning sign)
 */
export function warning(message: string): void {
  console.log(chalk.yellow('⚠') + ' ' + chalk.yellow(message));
}

/**
 * Info message (blue info icon)
 */
export function info(message: string): void {
  console.log(chalk.blue('ℹ') + ' ' + message);
}

/**
 * Section header
 */
export function header(message: string): void {
  console.log('\n' + chalk.bold.cyan(message));
}

/**
 * Subheader
 */
export function subheader(message: string): void {
  console.log(chalk.cyan(message));
}

/**
 * Command/code snippet
 */
export function code(text: string): string {
  return chalk.gray('`') + chalk.cyan(text) + chalk.gray('`');
}

/**
 * File path
 */
export function path(filePath: string): string {
  return chalk.gray(filePath);
}

/**
 * Emphasized text
 */
export function bold(text: string): string {
  return chalk.bold(text);
}

/**
 * Dimmed/muted text
 */
export function dim(text: string): string {
  return chalk.gray(text);
}

/**
 * Create a spinner for long-running operations
 */
export function spinner(text: string): Ora {
  return ora({
    text,
    color: 'cyan',
    spinner: 'dots',
  });
}

/**
 * Print a blank line
 */
export function blank(): void {
  console.log('');
}

/**
 * Print a horizontal rule
 */
export function rule(): void {
  console.log(chalk.gray('─'.repeat(60)));
}

/**
 * Format an error with suggestions
 */
export function errorWithSuggestions(
  errorMessage: string,
  suggestions: string[]
): void {
  error(errorMessage);
  blank();
  console.log(chalk.bold('Suggestions:'));
  for (const suggestion of suggestions) {
    console.log('  ' + chalk.yellow('→') + ' ' + suggestion);
  }
  blank();
}

/**
 * Print a list of items
 */
export function list(items: string[], color: 'green' | 'yellow' | 'blue' | 'gray' = 'blue'): void {
  const colorFn = {
    green: chalk.green,
    yellow: chalk.yellow,
    blue: chalk.blue,
    gray: chalk.gray,
  }[color];

  for (const item of items) {
    console.log('  ' + colorFn('•') + ' ' + item);
  }
}

/**
 * Print a table
 */
export function table(rows: Array<[string, string]>): void {
  const maxKeyLength = Math.max(...rows.map(([key]) => key.length));

  for (const [key, value] of rows) {
    const paddedKey = key.padEnd(maxKeyLength);
    console.log('  ' + chalk.cyan(paddedKey) + '  ' + value);
  }
}

/**
 * Banner with box
 */
export function banner(title: string, subtitle?: string): void {
  const width = Math.max(title.length, subtitle?.length || 0) + 4;
  const topLine = '┌' + '─'.repeat(width) + '┐';
  const bottomLine = '└' + '─'.repeat(width) + '┘';
  const titleLine = '│ ' + title.padEnd(width - 1) + '│';
  const subtitleLine = subtitle ? '│ ' + subtitle.padEnd(width - 1) + '│' : null;

  console.log(chalk.cyan(topLine));
  console.log(chalk.cyan(titleLine));
  if (subtitleLine) {
    console.log(chalk.gray(subtitleLine));
  }
  console.log(chalk.cyan(bottomLine));
  blank();
}

/**
 * Progress indicator
 */
export function progress(current: number, total: number, label: string): void {
  const percentage = Math.round((current / total) * 100);
  const barWidth = 30;
  const filled = Math.round((current / total) * barWidth);
  const empty = barWidth - filled;

  const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
  const stats = chalk.gray(`${current}/${total}`) + ' ' + chalk.cyan(`${percentage}%`);

  process.stdout.write(`\r  ${bar} ${stats} ${label}`);

  if (current === total) {
    process.stdout.write('\n');
  }
}
