const COLORS = {
  reset: "\x1b[0m",
  bright: "\x1b[1m",
  dim: "\x1b[2m",
  red: "\x1b[31m",
  green: "\x1b[32m",
  yellow: "\x1b[33m",
  blue: "\x1b[34m",
  magenta: "\x1b[35m",
  cyan: "\x1b[36m",
  white: "\x1b[37m",
  gray: "\x1b[90m",
};

export function color(text: string, colorName: keyof typeof COLORS): string {
  return `${COLORS[colorName]}${text}${COLORS.reset}`;
}

export function success(text: string): void {
  console.log(color(`✅ ${text}`, "green"));
}

export function error(text: string): void {
  console.error(color(`❌ ${text}`, "red"));
}

export function warning(text: string): void {
  console.warn(color(`⚠️  ${text}`, "yellow"));
}

export function info(text: string): void {
  console.log(color(`ℹ️  ${text}`, "blue"));
}

export function dim(text: string): string {
  return color(text, "gray");
}

export function bold(text: string): string {
  return `${COLORS.bright}${text}${COLORS.reset}`;
}

export function formatCommitMessage(type: string, scope: string | undefined, subject: string): string {
  let message = color(type, "cyan");
  if (scope) {
    message += color(`(${scope})`, "gray");
  }
  message += color(": ", "gray");
  message += subject;
  return message;
}

export function formatDiff(diff: string): string {
  return diff
    .split("\n")
    .map(line => {
      if (line.startsWith("+") && !line.startsWith("+++")) {
        return color(line, "green");
      } else if (line.startsWith("-") && !line.startsWith("---")) {
        return color(line, "red");
      } else if (line.startsWith("@@")) {
        return color(line, "cyan");
      } else if (line.startsWith("diff") || line.startsWith("index")) {
        return color(line, "magenta");
      }
      return line;
    })
    .join("\n");
}

export class Spinner {
  private frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
  private current = 0;
  private interval: Timer | null = null;
  private text: string;

  constructor(text: string) {
    this.text = text;
  }

  start(): void {
    this.interval = setInterval(() => {
      process.stdout.write(`\r${color(this.frames[this.current]!, "cyan")} ${this.text}`);
      this.current = (this.current + 1) % this.frames.length;
    }, 80);
  }

  stop(finalText?: string): void {
    if (this.interval) {
      clearInterval(this.interval);
      this.interval = null;
    }
    process.stdout.write("\r" + " ".repeat(this.text.length + 4) + "\r");
    if (finalText) {
      console.log(finalText);
    }
  }
}