#ifndef JSON_SERIALIZER_H
#define JSON_SERIALIZER_H

#include <json/json.h>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <memory>
#include <unordered_map>
#include <algorithm>
#include <cctype>
#include <type_traits>
#include "SerializationException.h"

class Serializable;

// 枚举类型支持，序列化接口
template <typename T>
struct EnumTraits;

static bool isConvertibleToInt(const std::string &str, int &value)
{
    try
    {
        value = std::stoi(str);
        return true;
    }
    catch (const std::invalid_argument &)
    {
        // 字符串不是有效的整数
        return false;
    }
    catch (const std::out_of_range &)
    {
        // 转换结果超出 int 类型的范围
        return false;
    }
}

// 序列化实现
template <typename T, typename Enable = void>
struct Serializer;

// 基本类型处理
template <typename T>
struct Serializer<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
{

    static Json::Value serialize(const T &value)
    {
        return Json::Value(value);
    }

    static void deserialize(const Json::Value &json, T &value)
    {
        if (json.empty() || json.isNull())
        {
            return;
        }

        if (!json.isConvertibleTo(Json::ValueType::intValue) &&
            !json.isConvertibleTo(Json::ValueType::uintValue) &&
            !json.isConvertibleTo(Json::ValueType::realValue) &&
            !json.isConvertibleTo(Json::ValueType::booleanValue))
        {
            THROW_SERIALIZABLE_EXCEPTION(rtx::exception::ErrorCode::SERIALIZE_MISMATCH_ARITHMETIC_VALUE, "Type mismatch for arithmetic value");
        }
        value = json.as<T>();
    }
};

// 字符串类型
template <>
struct Serializer<std::string>
{
    static Json::Value serialize(const std::string &value)
    {
        return Json::Value(value);
    }

    static void deserialize(const Json::Value &json, std::string &value)
    {
        if (json.empty() || json.isNull())
        {
            value = "";
            return;
        }
        if (!json.isString())
        {
            THROW_SERIALIZABLE_EXCEPTION(rtx::exception::ErrorCode::SERIALIZE_MISMATCH_STRING_VALUE, "Type mismatch for string");
        }
        value = json.asString();
    }
};

// 枚举字符串类型
template <typename T>
struct Serializer<T, typename std::enable_if<!std::is_arithmetic<T>::value &&
                                             !std::is_same<T, std::string>::value &&
                                             EnumTraits<T>::is_enum &&
                                             EnumTraits<T>::is_string>::type>
{
    static Json::Value serialize(const T &value)
    {
        return EnumTraits<T>::toString(value);
    }

    static void deserialize(const Json::Value &json, T &value)
    {
        if (json.empty() || json.isNull())
        {
            return;
        }
        if (!json.isString())
        {
            THROW_SERIALIZABLE_EXCEPTION(rtx::exception::ErrorCode::SERIALIZE_MISMATCH_ENUM_VALUE, "Enum should be string type");
        }
        value = EnumTraits<T>::fromString(json.asString());
    }
};

// 枚举数字类型
template <typename T>
struct Serializer<T, typename std::enable_if<!std::is_arithmetic<T>::value &&
                                             !std::is_same<T, std::string>::value &&
                                             EnumTraits<T>::is_enum &&
                                             EnumTraits<T>::is_int>::type>
{
    static Json::Value serialize(const T &value)
    {
        return std::to_string(static_cast<int>(value));
    }

    static void deserialize(const Json::Value &json, T &value)
    {
        if (json.empty() || json.isNull())
        {
            return;
        }

        
        if (!json.isConvertibleTo(Json::ValueType::intValue))
        {
            THROW_SERIALIZABLE_EXCEPTION(rtx::exception::ErrorCode::SERIALIZE_MISMATCH_ENUM_VALUE, "Enum should be int type");
        }
        int enumValue = json.asInt();
        if (!EnumTraits<T>::isValid(enumValue))
        {
            THROW_SERIALIZABLE_EXCEPTION(rtx::exception::ErrorCode::SERIALIZE_INVALID_ENUM_VALUE, "Invalid enum value: " + std::to_string(enumValue));
        }
        value = static_cast<T>(enumValue);
    }
};

// 数组类型
template <typename T>
struct Serializer<std::vector<T>>
{
    static Json::Value serialize(const std::vector<T> &arr)
    {
        Json::Value jsonArr(Json::arrayValue);
        for (const auto &item : arr)
        {
            jsonArr.append(Serializer<T>::serialize(item));
        }
        return jsonArr;
    }

    static void deserialize(const Json::Value &json, std::vector<T> &vec)
    {
        if (json.empty() || json.isNull())
        {
            vec.clear();
            return;
        }
        if (!json.isArray())
        {
            THROW_SERIALIZABLE_EXCEPTION(rtx::exception::ErrorCode::SERIALIZE_EXPECTED_ARRARY_VALUE, "Expected array type");
        }

        vec.clear();
        for (const auto &elem : json)
        {
            T item;
            Serializer<T>::deserialize(elem, item);
            vec.push_back(item);
        }
    }
};

// map类型（key必须是string）
template <typename V>
struct Serializer<std::map<std::string, V>>
{
    static Json::Value serialize(const std::map<std::string, V> &m)
    {
        Json::Value jsonObj;
        for (const auto &pair : m)
        {
            jsonObj[pair.first] = Serializer<V>::serialize(pair.second);
        }
        return jsonObj;
    }

    static void deserialize(const Json::Value &json, std::map<std::string, V> &map)
    {
        if (json.empty() || json.isNull())
        {
            map.clear();
            return;
        }

        if (!json.isObject())
        {
            THROW_SERIALIZABLE_EXCEPTION(rtx::exception::ErrorCode::SERIALIZE_EXPECTED_OBJECT_VALUE, "Expected object type");
        }

        map.clear();
        for (auto it = json.begin(); it != json.end(); ++it)
        {
            V item;
            Serializer<V>::deserialize(*it, item);
            map[it.key().asString()] = item;
        }
    }
};

// 去除字符串末尾的所有空白字符（包括空格、制表符、换行符等）
static void trimTrailingWhitespace(std::string &str)
{
    if (str.empty())
        return;

    // 找到最后一个不是空白字符的位置
    auto it = std::find_if(str.rbegin(), str.rend(), [](unsigned char ch)
                           { return !std::isspace(ch); });

    // 截取字符串到该位置
    str.erase(it.base(), str.end());
}

// 序列化接口
class Serializable
{
public:
    virtual Json::Value toJson() const = 0;

    virtual std::string toJsonString() const
    {
        Json::FastWriter writer;
        Json::Value root = toJson();
        std::string data = writer.write(root);
        trimTrailingWhitespace(data);
        return data;
    }

    virtual void fromJson(const Json::Value &json) = 0;
};

class VoidSerializable : public Serializable
{
private:
    Json::Value null;

public:
    Json::Value toJson() const override
    {
        return null;
    }

    std::string toJsonString() const override
    {
        return null.toStyledString();
    }

    void fromJson(const Json::Value &json)
    {
    }
};

#define SERIALIZE_JSON_FIELD(val, field) (val[#field] = Serializer<decltype(field)>::serialize(field))
// #define SERIALIZE_JSON_OBJECT_FIELD(val, field) (val[#field] = field.toJson())
#define SERIALIZE_JSON_PTR_FIELD(val, field) (val[#field] = field->toJson())
#define SERIALIZE_JSON_ENUM_FIELD(val, field) (val[#field] = ::enumToJson(field))

#define DESERIALIZE_JSON_FIELD(val, field) (Serializer<decltype(field)>::deserialize(val[#field], field))
// #define DESERIALIZE_JSON_OBJECT_FIELD(val, field) (field.fromJson(val[#field]))
#define DESERIALIZE_JSON_PTR_FIELD(val, field) (field->fromJson(val[#field]))
#define DESERIALIZE_JSON_ENUM_STR_FIELD(val, field) (::enumFromJson(val[#field], field))

// 注册枚举映射：先退出当前两层命名空间，在全局特化 EnumTraits，再重新进入
// NS 为第二层命名空间名（如 account / pcsdk）
#define REGISTER_SERIALIZE_ENUM_STRING(ENUM_TYPE, NS, ...)                                                                                              \
    }                                                                                                                                                   \
    }                                                                                                                                                   \
    template <>                                                                                                                                         \
    struct EnumTraits<ENUM_TYPE>                                                                                                                        \
    {                                                                                                                                                   \
        using EnumType = ENUM_TYPE;                                                                                                                     \
        static constexpr bool is_enum = true;                                                                                                           \
        static constexpr bool is_string = true;                                                                                                         \
        static constexpr bool is_int = false;                                                                                                           \
        static const std::unordered_map<EnumType, std::string> &get_mapping()                                                                           \
        {                                                                                                                                               \
            static const std::unordered_map<EnumType, std::string> mapping = {__VA_ARGS__};                                                             \
            return mapping;                                                                                                                             \
        }                                                                                                                                               \
        static std::string toString(EnumType value)                                                                                                     \
        {                                                                                                                                               \
            auto it = get_mapping().find(value);                                                                                                        \
            if (it != get_mapping().end())                                                                                                              \
                return it->second;                                                                                                                      \
            THROW_SERIALIZABLE_EXCEPTION(rtx::exception::ErrorCode::SERIALIZE_INVALID_ENUM_VALUE, "Invalid enum value: " #ENUM_TYPE);                   \
        }                                                                                                                                               \
        static EnumType fromString(const std::string &str)                                                                                              \
        {                                                                                                                                               \
            for (auto &&pair : get_mapping())                                                                                                           \
            {                                                                                                                                           \
                if (pair.second == str)                                                                                                                 \
                {                                                                                                                                       \
                    return pair.first;                                                                                                                  \
                }                                                                                                                                       \
            }                                                                                                                                           \
            THROW_SERIALIZABLE_EXCEPTION(rtx::exception::ErrorCode::SERIALIZE_INVALID_ENUM_VALUE, "Invalid enum type: " #ENUM_TYPE ", string: " + str); \
        }                                                                                                                                               \
        static bool isValid(int num)                                                                                                                    \
        {                                                                                                                                               \
            for (const auto &pair : get_mapping())                                                                                                      \
            {                                                                                                                                           \
                if (static_cast<int>(pair.first) == num)                                                                                                \
                    return true;                                                                                                                        \
            }                                                                                                                                           \
            return false;                                                                                                                               \
        }                                                                                                                                               \
    };                                                                                                                                                  \
    namespace rtx                                                                                                                                       \
    {                                                                                                                                                   \
        namespace NS                                                                                                                                    \
        {

#define REGISTER_SERIALIZE_ENUM_INT(ENUM_TYPE, NS, ...)                 \
    }                                                                  \
    }                                                                  \
    template <>                                                        \
    struct EnumTraits<ENUM_TYPE>                                       \
    {                                                                  \
        using EnumType = ENUM_TYPE;                                    \
        static constexpr bool is_enum = true;                          \
        static constexpr bool is_int = true;                           \
        static constexpr bool is_string = false;                       \
        static const std::vector<EnumType> &get_values()               \
        {                                                              \
            static const std::vector<EnumType> values = {__VA_ARGS__}; \
            return values;                                             \
        }                                                              \
                                                                       \
        static bool isValid(int num)                                   \
        {                                                              \
            for (const auto &value : get_values())                     \
            {                                                          \
                if (static_cast<int>(value) == num)                    \
                    return true;                                       \
            }                                                          \
            return false;                                              \
        }                                                              \
    };                                                                 \
    namespace rtx                                                      \
    {                                                                  \
        namespace NS                                                   \
        {

// 基于 Serializable 的通用序列化（跨平台，避免在嵌套命名空间内做模板特化）
template <typename T>
struct Serializer<T, typename std::enable_if<std::is_base_of<Serializable, T>::value>::type>
{
    static Json::Value serialize(const T &obj)
    {
        return obj.toJson();
    }

    static void deserialize(const Json::Value &json, T &obj)
    {
        obj.fromJson(json);
    }
};

// 保留宏以兼容现有调用点（实现已由上面的 SFINAE 特化覆盖）
#define REGISTER_SERIALIZE_OBJECT(Type) \
    static_assert(std::is_base_of<Serializable, Type>::value, #Type " must derive from Serializable")

#endif // JSON_SERIALIZER_H