/**
 * A simple logger class that provides consistent formatting for log messages
 * including support for logboxes with title, lines, and closing
 */
export class Logger {
  private currentBoxWidth: number | null = null;
  private static instance: Logger;

  /**
   * Creates a new Logger instance
   */
  constructor() {
    this.currentBoxWidth = null;
  }

  /**
   * Get the singleton logger instance
   * @returns The singleton logger instance
   */
  public static getInstance(): Logger {
    if (!Logger.instance) {
      Logger.instance = new Logger();
    }
    return Logger.instance;
  }

  /**
   * Log a message
   * @param message Message to log
   */
  public log(message: string): void {
    console.log(message);
  }

  /**
   * Log an error message
   * @param message Error message to log
   */
  public error(message: string): void {
    console.error(message);
  }

  /**
   * Log a warning message with a warning emoji
   * @param message Warning message to log
   */
  public warn(message: string): void {
    console.warn(`⚠️ ${message}`);
  }

  /**
   * Log a success message with a checkmark
   * @param message Success message to log
   */
  public success(message: string): void {
    console.log(`✓ ${message}`);
  }

  /**
   * Log a logbox title and set the current box width
   * @param title Title of the logbox
   * @param width Width of the logbox (including borders)
   */
  public logBoxTitle(title: string, width: number): void {
    this.currentBoxWidth = width;
    
    // Create the title line with appropriate padding
    const paddedTitle = ` ${title} `;
    const remainingSpace = width - 3 - paddedTitle.length;
    
    // Title line: ┌─ Title ───┐
    const titleLine = `┌─${paddedTitle}${'─'.repeat(remainingSpace)}┐`;
    
    console.log(titleLine);
  }

  /**
   * Log a logbox line
   * @param content Content of the line
   * @param width Optional width override. If not provided, uses the current box width.
   */
  public logBoxLine(content: string, width?: number): void {
    const boxWidth = width || this.currentBoxWidth;
    
    if (!boxWidth) {
      throw new Error('No box width specified and no previous box width to use');
    }
    
    // Calculate the available space for content
    const availableSpace = boxWidth - 2; // Account for left and right borders
    
    if (content.length <= availableSpace - 1) {
      // If content fits with at least one space for the right border stripe
      const padding = availableSpace - content.length - 1;
      console.log(`│ ${content}${' '.repeat(padding)}│`);
    } else {
      // Content is too long, let it flow out of boundaries.
      console.log(`│ ${content}`);
    }
  }

  /**
   * Log a logbox end
   * @param width Optional width override. If not provided, uses the current box width.
   */
  public logBoxEnd(width?: number): void {
    const boxWidth = width || this.currentBoxWidth;
    
    if (!boxWidth) {
      throw new Error('No box width specified and no previous box width to use');
    }
    
    // Create the bottom border: └────────┘
    console.log(`└${'─'.repeat(boxWidth - 2)}┘`);
    
    // Reset the current box width
    this.currentBoxWidth = null;
  }

  /**
   * Log a complete logbox with title, content lines, and ending
   * @param title Title of the logbox
   * @param lines Array of content lines
   * @param width Width of the logbox
   */
  public logBox(title: string, lines: string[], width: number): void {
    this.logBoxTitle(title, width);
    
    for (const line of lines) {
      this.logBoxLine(line);
    }
    
    this.logBoxEnd();
  }

  /**
   * Log a divider line
   * @param width Width of the divider
   * @param character Character to use for the divider (default: ─)
   */
  public logDivider(width: number, character: string = '─'): void {
    console.log(character.repeat(width));
  }
}

// Export a singleton instance for easy use
export const logger = Logger.getInstance();