#pragma once
#include <string>
#include <vector>
#include <map>
#include <regex>

namespace includecpp {
namespace inbuilds {

class StringUtils {
public:
    // Basic Operations
    static std::string to_upper(const std::string& str);
    static std::string to_lower(const std::string& str);
    static std::string trim(const std::string& str);
    static std::string trim_left(const std::string& str);
    static std::string trim_right(const std::string& str);
    static std::string reverse(const std::string& str);
    static std::string repeat(const std::string& str, int count);
    static std::string pad_left(const std::string& str, int width, char fill = ' ');
    static std::string pad_right(const std::string& str, int width, char fill = ' ');
    static std::string pad_center(const std::string& str, int width, char fill = ' ');

    // Search & Replace
    static bool contains(const std::string& str, const std::string& substr);
    static bool starts_with(const std::string& str, const std::string& prefix);
    static bool ends_with(const std::string& str, const std::string& suffix);
    static int index_of(const std::string& str, const std::string& substr, int start = 0);
    static int last_index_of(const std::string& str, const std::string& substr);
    static int count_occurrences(const std::string& str, const std::string& substr);
    static std::string replace(const std::string& str, const std::string& old_str, const std::string& new_str);
    static std::string replace_all(const std::string& str, const std::string& old_str, const std::string& new_str);
    static std::string replace_first(const std::string& str, const std::string& old_str, const std::string& new_str);
    static std::string replace_last(const std::string& str, const std::string& old_str, const std::string& new_str);

    // Splitting & Joining
    static std::vector<std::string> split(const std::string& str, const std::string& delimiter);
    static std::vector<std::string> split_lines(const std::string& str);
    static std::vector<std::string> split_whitespace(const std::string& str);
    static std::string join(const std::vector<std::string>& strings, const std::string& delimiter);
    static std::vector<std::string> chunk(const std::string& str, int size);

    // Character Classification
    static bool is_alpha(const std::string& str);
    static bool is_numeric(const std::string& str);
    static bool is_alphanumeric(const std::string& str);
    static bool is_lowercase(const std::string& str);
    static bool is_uppercase(const std::string& str);
    static bool is_whitespace(const std::string& str);
    static bool is_empty(const std::string& str);
    static bool is_blank(const std::string& str);

    // Regex Operations
    static bool regex_match(const std::string& str, const std::string& pattern);
    static std::vector<std::string> regex_find_all(const std::string& str, const std::string& pattern);
    static std::string regex_replace(const std::string& str, const std::string& pattern, const std::string& replacement);
    static std::vector<std::string> regex_split(const std::string& str, const std::string& pattern);

    // Substring Operations
    static std::string substring(const std::string& str, int start, int length = -1);
    static std::string left(const std::string& str, int length);
    static std::string right(const std::string& str, int length);
    static std::string remove(const std::string& str, int start, int length);
    static std::string insert(const std::string& str, int pos, const std::string& substr);

    // Encoding/Decoding
    static std::string url_encode(const std::string& str);
    static std::string url_decode(const std::string& str);
    static std::string html_escape(const std::string& str);
    static std::string html_unescape(const std::string& str);

    // Case Conversion
    static std::string to_title_case(const std::string& str);
    static std::string to_camel_case(const std::string& str);
    static std::string to_snake_case(const std::string& str);
    static std::string to_kebab_case(const std::string& str);
    static std::string to_pascal_case(const std::string& str);

    // Comparison
    static bool equals_ignore_case(const std::string& a, const std::string& b);
    static int compare_natural(const std::string& a, const std::string& b);
    static double similarity(const std::string& a, const std::string& b);
    static int levenshtein_distance(const std::string& a, const std::string& b);

    // Formatting
    static std::string format(const std::string& fmt, const std::vector<std::string>& args);
    static std::string truncate(const std::string& str, int max_length, const std::string& suffix = "...");
    static std::string wrap(const std::string& str, int width);
    static std::string remove_accents(const std::string& str);

    // Validation
    static bool is_email(const std::string& str);
    static bool is_url(const std::string& str);
    static bool is_ip_address(const std::string& str);
    static bool is_hex(const std::string& str);
    static bool is_base64(const std::string& str);

    // Utilities
    static std::string random_string(int length, const std::string& charset = "");
    static std::string hash_string(const std::string& str);
    static std::vector<std::string> extract_numbers(const std::string& str);
    static std::vector<std::string> extract_words(const std::string& str);
    static std::map<std::string, int> word_frequency(const std::string& str);
};

} // namespace inbuilds
} // namespace includecpp
