#ifndef JSONMAPPER_H
#define JSONMAPPER_H

#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QMap>
#include <QMetaProperty>
#include <QVariant>

#include "QtJsonSerializer"
#include "qjsonobject.h"

class JsonMapper
{
public:
    // 从JSON对象映射到任意Q_GADGET结构体/类
    template<typename T>
    static T fromJson(const QJsonValue &json)
    {
        T obj;
        if (!json.isObject()) {
            return obj;
        }

        QJsonObject jsonObj = json.toObject();
        const QMetaObject *metaObj = &T::staticMetaObject;

        for (int i = metaObj->propertyOffset(); i < metaObj->propertyCount(); ++i) {
            QMetaProperty prop = metaObj->property(i);
            QString propName = prop.name();

            if (jsonObj.contains(propName)) {
                QVariant value = jsonObj[propName].toVariant();
                if (value.canConvert(prop.type())) {
                    prop.writeOnGadget(&obj, value);
                }
            }
        }

        return obj;
    }

    // 从JSON数组映射到QList<T>
    template<typename T>
    static QList<T> fromJsonArray(const QJsonValue &json)
    {
        QList<T> list;
        if (!json.isArray()) {
            return list;
        }

        QJsonArray array = json.toArray();
        for (const QJsonValue &item : array) {
            list.append(fromJson<T>(item));
        }

        return list;
    }
    template<typename T>
    static QJsonValue toJson(const T &obj)
    {
        try {
            QtJsonSerializer::JsonSerializer serializer;
            return serializer.serialize(obj);
        } catch (QtJsonSerializer::Exception &e) {
            qDebug() << e.what();
        }
        return QJsonValue();
    }
    template<typename T>
    static T formJsonEx(const QJsonObject &obj)
    {
        try {
            QtJsonSerializer::JsonSerializer serializer;
            return serializer.deserialize<T>(obj);
        } catch (QtJsonSerializer::Exception &e) {
            qDebug() << e.what();
        }
        return T();
    }

private:
};

#endif // JSONMAPPER_H
