#pragma once
#include <string>
#include <map>
#include <vector>
#include <variant>
#include <memory>

namespace includecpp {
namespace inbuilds {

// Simple JSON value type
using JsonValue = std::variant<
    std::nullptr_t,
    bool,
    int,
    double,
    std::string,
    std::vector<std::shared_ptr<std::variant<std::nullptr_t, bool, int, double, std::string>>>,
    std::map<std::string, std::shared_ptr<std::variant<std::nullptr_t, bool, int, double, std::string>>>
>;

class JSON {
public:
    // Parsing
    static std::string parse(const std::string& json_str);
    static std::string stringify(const std::string& data);

    // Object Operations
    static std::string create_object();
    static std::string set_field(const std::string& obj, const std::string& key, const std::string& value);
    static std::string get_field(const std::string& obj, const std::string& key);
    static bool has_field(const std::string& obj, const std::string& key);
    static std::vector<std::string> get_keys(const std::string& obj);

    // Array Operations
    static std::string create_array();
    static std::string array_push(const std::string& arr, const std::string& value);
    static std::string array_get(const std::string& arr, int index);
    static int array_length(const std::string& arr);

    // Type Checking
    static bool is_object(const std::string& json);
    static bool is_array(const std::string& json);
    static bool is_string(const std::string& json);
    static bool is_number(const std::string& json);
    static bool is_boolean(const std::string& json);
    static bool is_null(const std::string& json);

    // Conversion
    static std::string to_pretty_string(const std::string& json);
    static std::string from_string(const std::string& str);
    static std::string from_number(double num);
    static std::string from_boolean(bool val);
    static std::string from_null();
};

// Free functions
std::string load_json(const std::string& filepath);
bool save_json(const std::string& filepath, const std::string& json);

} // namespace inbuilds
} // namespace includecpp
