#ifndef ROBOT_CONSOLE_H
#define ROBOT_CONSOLE_H

#include <cstdio>
#include <cstdarg>

namespace robot
{

  /**
   * @namespace color
   * @brief ANSI color code constants for terminal output formatting.
   *
   * This namespace provides ANSI escape sequences for colored terminal output.
   * All color codes are compatible with terminals that support ANSI escape codes.
   * Colors are automatically disabled if the terminal doesn't support them or if
   * the NO_COLOR environment variable is set.
   */
  namespace color
  {
    /**
     * @brief ANSI escape code to reset all formatting.
     *
     * Resets text color, background color, and all text styles to default.
     */
    static const char *RESET = "\033[0m";

    // Text colors
    /**
     * @brief ANSI escape code for black text color.
     */
    static const char *BLACK = "\033[30m";

    /**
     * @brief ANSI escape code for red text color.
     */
    static const char *RED = "\033[31m";

    /**
     * @brief ANSI escape code for green text color.
     */
    static const char *GREEN = "\033[32m";

    /**
     * @brief ANSI escape code for yellow text color.
     */
    static const char *YELLOW = "\033[33m";

    /**
     * @brief ANSI escape code for blue text color.
     */
    static const char *BLUE = "\033[34m";

    /**
     * @brief ANSI escape code for magenta text color.
     */
    static const char *MAGENTA = "\033[35m";

    /**
     * @brief ANSI escape code for cyan text color.
     */
    static const char *CYAN = "\033[36m";

    /**
     * @brief ANSI escape code for white text color.
     */
    static const char *WHITE = "\033[37m";

    // Bright text colors
    /**
     * @brief ANSI escape code for bright black text color.
     */
    static const char *BRIGHT_BLACK = "\033[90m";

    /**
     * @brief ANSI escape code for bright red text color.
     */
    static const char *BRIGHT_RED = "\033[91m";

    /**
     * @brief ANSI escape code for bright green text color.
     */
    static const char *BRIGHT_GREEN = "\033[92m";

    /**
     * @brief ANSI escape code for bright yellow text color.
     */
    static const char *BRIGHT_YELLOW = "\033[93m";

    /**
     * @brief ANSI escape code for bright blue text color.
     */
    static const char *BRIGHT_BLUE = "\033[94m";

    /**
     * @brief ANSI escape code for bright magenta text color.
     */
    static const char *BRIGHT_MAGENTA = "\033[95m";

    /**
     * @brief ANSI escape code for bright cyan text color.
     */
    static const char *BRIGHT_CYAN = "\033[96m";

    /**
     * @brief ANSI escape code for bright white text color.
     */
    static const char *BRIGHT_WHITE = "\033[97m";

    // Background colors
    /**
     * @brief ANSI escape code for black background color.
     */
    static const char *BG_BLACK = "\033[40m";

    /**
     * @brief ANSI escape code for red background color.
     */
    static const char *BG_RED = "\033[41m";

    /**
     * @brief ANSI escape code for green background color.
     */
    static const char *BG_GREEN = "\033[42m";

    /**
     * @brief ANSI escape code for yellow background color.
     */
    static const char *BG_YELLOW = "\033[43m";

    /**
     * @brief ANSI escape code for blue background color.
     */
    static const char *BG_BLUE = "\033[44m";

    /**
     * @brief ANSI escape code for magenta background color.
     */
    static const char *BG_MAGENTA = "\033[45m";

    /**
     * @brief ANSI escape code for cyan background color.
     */
    static const char *BG_CYAN = "\033[46m";

    /**
     * @brief ANSI escape code for white background color.
     */
    static const char *BG_WHITE = "\033[47m";

    // Text styles
    /**
     * @brief ANSI escape code for bold text style.
     */
    static const char *BOLD = "\033[1m";

    /**
     * @brief ANSI escape code for dim text style.
     */
    static const char *DIM = "\033[2m";

    /**
     * @brief ANSI escape code for italic text style.
     */
    static const char *ITALIC = "\033[3m";

    /**
     * @brief ANSI escape code for underlined text style.
     */
    static const char *UNDERLINE = "\033[4m";

    /**
     * @brief ANSI escape code for blinking text style.
     */
    static const char *BLINK = "\033[5m";

    /**
     * @brief ANSI escape code for reverse video (swap foreground/background).
     */
    static const char *REVERSE = "\033[7m";
  }

  /**
   * @brief Check if the terminal supports color output.
   *
   * Checks various conditions to determine if the terminal supports ANSI color codes:
   * - Checks if NO_COLOR environment variable is set (disables colors)
   * - Checks TERM environment variable for common color-capable terminals
   * - Defaults to true for most modern terminals
   *
   * @return true if colors are supported, false otherwise.
   */
  bool is_color_supported();

  /**
   * @brief Enable or disable color output.
   *
   * Sets whether color output should be used. This is useful for redirecting output
   * to files or non-terminal outputs where color codes would be unwanted.
   *
   * @param enabled true to enable colors (if supported), false to disable.
   *
   * @note Colors are only enabled if both this flag is true AND the terminal supports colors.
   */
  void set_color_enabled(bool enabled);

  /**
   * @brief Check if color output is currently enabled.
   *
   * Returns true only if both color_enabled flag is true AND the terminal supports colors.
   *
   * @return true if colors are enabled and supported, false otherwise.
   */
  bool is_color_enabled();

  /**
   * @brief Print formatted text in red color.
   *
   * Prints formatted text using printf-style formatting with red text color.
   * Automatically resets color after printing.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   *
   * @code
   * printf_red("Error: %s\n", error_message);
   * @endcode
   */
  void printf_red(const char *format, ...);

  /**
   * @brief Print formatted text in green color.
   *
   * Prints formatted text using printf-style formatting with green text color.
   * Automatically resets color after printing.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void printf_green(const char *format, ...);

  /**
   * @brief Print formatted text in yellow color.
   *
   * Prints formatted text using printf-style formatting with yellow text color.
   * Automatically resets color after printing.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void printf_yellow(const char *format, ...);

  /**
   * @brief Print formatted text in blue color.
   *
   * Prints formatted text using printf-style formatting with blue text color.
   * Automatically resets color after printing.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void printf_blue(const char *format, ...);

  /**
   * @brief Print formatted text in cyan color.
   *
   * Prints formatted text using printf-style formatting with cyan text color.
   * Automatically resets color after printing.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void printf_cyan(const char *format, ...);

  /**
   * @brief Print formatted text in magenta color.
   *
   * Prints formatted text using printf-style formatting with magenta text color.
   * Automatically resets color after printing.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void printf_magenta(const char *format, ...);

  /**
   * @brief Print formatted text in white color.
   *
   * Prints formatted text using printf-style formatting with white text color.
   * Automatically resets color after printing.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void printf_white(const char *format, ...);

  /**
   * @brief Print formatted text with a custom color code.
   *
   * Prints formatted text using printf-style formatting with a custom ANSI color code.
   * Useful when you want to use a color from the color namespace or combine styles.
   * Automatically resets color after printing.
   *
   * @param color_code ANSI escape code for the desired color/style (e.g., color::RED, color::BOLD).
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   *
   * @code
   * printf_color(color::BRIGHT_RED, "Critical: %s\n", message);
   * printf_color(color::BOLD, "Important message\n");
   * @endcode
   */
  void printf_color(const char *color_code, const char *format, ...);

  /**
   * @brief Log an informational message (blue color).
   *
   * Logs an informational message with blue text color. Use for general information
   * that doesn't indicate success, warning, or error.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   *
   * @code
   * log_info("Processing %d items\n", count);
   * @endcode
   */
  void log_info(const char *format, ...);

  /**
   * @brief Log a success message (green color).
   *
   * Logs a success message with green text color. Use for successful operations
   * or positive status updates.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   *
   * @code
   * log_success("Operation completed successfully\n");
   * @endcode
   */
  void log_success(const char *format, ...);

  /**
   * @brief Log a warning message (yellow color).
   *
   * Logs a warning message with yellow text color. Use for warnings that don't
   * prevent operation but should be noted.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   *
   * @code
   * log_warning("Low battery: %d%%\n", battery_level);
   * @endcode
   */
  void log_warning(const char *format, ...);

  /**
   * @brief Log an error message (red color).
   *
   * Logs an error message with red text color. Use for errors that indicate
   * problems or failures.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   *
   * @code
   * log_error("Failed to open file: %s\n", filename);
   * @endcode
   */
  void log_error(const char *format, ...);

  /**
   * @brief Log a debug message (cyan color).
   *
   * Logs a debug message with cyan text color. Use for debugging information
   * that is typically only needed during development.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   *
   * @code
   * log_debug("Variable value: %d\n", value);
   * @endcode
   */
  void log_debug(const char *format, ...);

  /**
   * @brief Log an informational message with file and line information.
   *
   * Logs an informational message with blue color, including the source file
   * and line number where the log was called. Useful for debugging and tracing.
   *
   * @param file Source file name (typically use __FILE__ macro).
   * @param line Line number (typically use __LINE__ macro).
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   *
   * @code
   * log_info_at(__FILE__, __LINE__, "Processing started\n");
   * @endcode
   */
  void log_info_at(const char *file, int line, const char *format, ...);

  /**
   * @brief Log a success message with file and line information.
   *
   * Logs a success message with green color, including the source file and line number.
   *
   * @param file Source file name (typically use __FILE__ macro).
   * @param line Line number (typically use __LINE__ macro).
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void log_success_at(const char *file, int line, const char *format, ...);

  /**
   * @brief Log a warning message with file and line information.
   *
   * Logs a warning message with yellow color, including the source file and line number.
   *
   * @param file Source file name (typically use __FILE__ macro).
   * @param line Line number (typically use __LINE__ macro).
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void log_warning_at(const char *file, int line, const char *format, ...);

  /**
   * @brief Log an error message with file and line information.
   *
   * Logs an error message with red color, including the source file and line number.
   *
   * @param file Source file name (typically use __FILE__ macro).
   * @param line Line number (typically use __LINE__ macro).
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void log_error_at(const char *file, int line, const char *format, ...);

  /**
   * @brief Log a debug message with file and line information.
   *
   * Logs a debug message with cyan color, including the source file and line number.
   *
   * @param file Source file name (typically use __FILE__ macro).
   * @param line Line number (typically use __LINE__ macro).
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void log_debug_at(const char *file, int line, const char *format, ...);


  /**
   * @brief Log an error message with throttle.
   *
   * Logs an error message with red text color. Use for errors that indicate
   * problems or failures.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */ 
  void log_error_throttle(double throttle, const char *format, ...);

  /**
   * @brief Log a debug message with throttle.
   *
   * Logs a debug message with cyan text color. Use for debugging information
   * that is typically only needed during development.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void log_info_throttle(double throttle, const char *format, ...);

  /**
   * @brief Log a success message with throttle.
   *
   * Logs a success message with green text color. Use for successful operations
   * or positive status updates.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void log_success_throttle(double throttle, const char *format, ...);

  /**
   * @brief Log a warning message with throttle.
   *
   * Logs a warning message with yellow text color. Use for warnings that don't
   * prevent operation but should be noted.
   *
   * @param format printf-style format string.
   * @param ... Variable arguments for format string.
   */
  void log_warning_throttle(double throttle, const char *format, ...);

  /**
   * @brief Assert a condition and log error if it fails.
   *
   * Checks if a condition is true. If the condition is false, logs an error
   * message with red text color and terminates the program by calling abort().
   * This is useful for debugging and catching logic errors during development.
   *
   * @param condition The condition to check (must evaluate to true).
   * @param format Optional printf-style format string for error message.
   * @param ... Variable arguments for format string.
   *
   * @note In release builds, assertions may be disabled. Use this for conditions
   *       that should never be false (logic errors), not for runtime error handling.
   *
   * @code
   * log_assert(ptr != nullptr, "Pointer is null!");
   * log_assert(index < size, "Index %d out of bounds (size: %d)", index, size);
   * log_assert(velocity > 0, "Velocity must be positive, got: %f", velocity);
   * @endcode
   */
  void log_assert(bool condition, const char *format = nullptr, ...);

   
} // namespace robot

#endif // ROBOT_CONSOLE_H
