#ifndef JSONTRAITS_H
#define JSONTRAITS_H

#include <QJsonValue>
#include <QJsonObject>
#include <QJsonArray>
#include <type_traits>
#include <vector>
#include <map>

// 类型特征萃取模板
template<typename T>
class JsonTraits
{
    // 序列化函数
    static QJsonValue toJson(const T& value) {
        return QJsonValue(value);
    }

    // 反序列化函数
    static T fromJson(const QJsonValue& json) {
        return json.toVariant().value<T>();
    }

    // 类型标识
    using IsSpecialized = std::false_type;
};

// 基础类型特化
template<> struct JsonTraits<int> {
    static QJsonValue toJson(int value) { return value; }
    static int fromJson(const QJsonValue& json) { return json.toInt(); }
};

template<> struct JsonTraits<double> {
    static QJsonValue toJson(double value) { return value; }
    static double fromJson(const QJsonValue& json) { return json.toDouble(); }
};

template<> struct JsonTraits<bool> {
    static QJsonValue toJson(bool value) { return value; }
    static bool fromJson(const QJsonValue& json) { return json.toBool(); }
};

template<> struct JsonTraits<QString> {
    static QJsonValue toJson(const QString& value) { return value; }
    static QString fromJson(const QJsonValue& json) { return json.toString(); }
};

// 序列容器支持 (std::vector, QList等)
template<typename T>
struct JsonTraits<std::vector<T>> {
    static QJsonValue toJson(const std::vector<T>& vec) {
        QJsonArray array;
        for (const auto& item : vec) {
            array.append(JsonTraits<T>::toJson(item));
        }
        return array;
    }

    static std::vector<T> fromJson(const QJsonValue& json) {
        std::vector<T> result;
        if (json.isArray()) {
            QJsonArray array = json.toArray();
            for (const auto& item : std::as_const(array)) {
                result.push_back(JsonTraits<T>::fromJson(item));
            }
        }
        return result;
    }
};

// 关联容器支持 (std::map, QHash等)
template<typename K, typename V>
struct JsonTraits<std::map<K, V>> {
    static QJsonValue toJson(const std::map<K, V>& map) {
        QJsonObject obj;
        for (const auto& pair : map) {
            obj[QString::fromStdString(pair.first)] = JsonTraits<V>::toJson(pair.second);
        }
        return obj;
    }

    static std::map<K, V> fromJson(const QJsonValue& json) {
        std::map<K, V> result;
        if (json.isObject()) {
            QJsonObject obj = json.toObject();
            for (auto it = obj.begin(); it != obj.end(); ++it) {
                result[it.key().toStdString()] = JsonTraits<V>::fromJson(it.value());
            }
        }
        return result;
    }
};

// 定义新的结构体注册宏
#define REGISTER_STRUCT(Type, ...) \
template<> struct JsonTraits<Type> { \
        static QJsonValue toJson(const Type& value) { \
            QJsonObject obj; \
            FOR_EACH(FIELD, __VA_ARGS__) \
            return obj; \
    } \
    \
        static Type fromJson(const QJsonValue& json) { \
            Type result{}; \
            if (json.isObject()) { \
                QJsonObject obj = json.toObject(); \
                FOR_EACH(FIELD_FROM, __VA_ARGS__) \
        } \
            return result; \
    } \
};

// 辅助宏
#define FOR_EACH(action, ...) \
PP_FOR_EACH(action, __VA_ARGS__)

#define PP_FOR_EACH(action, arg, ...) \
action(arg) \
    __VA_OPT__(PP_FOR_EACH_AGAIN(action, __VA_ARGS__))

#define PP_FOR_EACH_AGAIN(action, arg, ...) \
    action(arg) \
    __VA_OPT__(PP_FOR_EACH_AGAIN(action, __VA_ARGS__))

#define FIELD(field) obj[#field] = JsonTraits<decltype(std::declval<decltype(value)>().field)>::toJson(value.field);
#define FIELD_FROM(field) if (obj.contains(#field)) { \
    result.field = JsonTraits<decltype(result.field)>::fromJson(obj[#field]); \
}

#endif // JSONTRAITS_H
