#include "roomapi.h"
#include "qjsonobject.h"

#include "qtjsonserializer_global.h"
#include "util/jsonmapper.h"
#include <cstddef>
#include <utility>

// std::optional<QString> id;          // 房间当前id
// std::optional<QString> name;        // 房间名
// std::optional<QString> description; // 房间的描述信息
// std::optional<int> maxUsers;        // 最大用户数
// std::optional<qint64> status;       // 1: normal 2: ban | 状态 1 正常 2 禁用
// std::optional<qint64> createdAt;    // 创建日期
// std::optional<qint64> updatedAt;    // 修改日期
// std::optional<QString> createdId;   // 创建者
// std::optional<QString> ownerId;     // 房主ID，关联用户表

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// 为 Qt 5 注册 std::optional 类型
Q_DECLARE_METATYPE(std::optional<QString>)
Q_DECLARE_METATYPE(std::optional<int>)
Q_DECLARE_METATYPE(std::optional<qint64>)

// 对于 QString 类型还需要流运算符
QDataStream &operator<<(QDataStream &out, const std::optional<QString> &opt)
{
    out << static_cast<bool>(opt.has_value());
    if (opt)
        out << *opt;
    return out;
}

QDataStream &operator>>(QDataStream &in, std::optional<QString> &opt)
{
    bool hasValue;
    in >> hasValue;
    if (hasValue) {
        QString value;
        in >> value;
        opt = value;
    } else {
        opt = std::nullopt;
    }
    return in;
}

void initRoomType()
{
    QtJsonSerializer::registerTypes();
    QtJsonSerializer::JsonSerializer::registerOptionalConverters<QString>();
    QtJsonSerializer::JsonSerializer::registerOptionalConverters<int>();
    QtJsonSerializer::JsonSerializer::registerOptionalConverters<qint64>();
    QtJsonSerializer::JsonSerializer::registerListConverters<RoomInfo>();
    qRegisterMetaType<RoomInfo>("RoomInfo");
    qRegisterMetaType<RoomListData>("RoomListData");
    qRegisterMetaType<std::optional<QString>>("std::optional<QString>");
    qRegisterMetaType<std::optional<int>>("std::optional<int>");
    qRegisterMetaType<std::optional<qint64>>("std::optional<qint64>");
}
#endif

RoomListData::RoomListData(const QJsonObject &object)
{
    // 正式开始
    QtJsonSerializer::JsonSerializer serializer;
    // serializer.setAllowDefaultNull(true);
    RoomListData roomList;
    try {
        roomList = serializer.deserialize<RoomListData>(object);
        data = roomList.data;
        total = roomList.total;
    } catch (const QtJsonSerializer::Exception &e) {
        qDebug() << "Deserialization error:" << e.what();
    }
}

QList<RoomInfo> RoomListData::getRooms() const
{
    return data;
}

QFuture<HttpResponse> getRoomListApi(const RoomInfo &roomInfo, int page, int pageSize)
{
    QJsonObject jsonData;
    QJsonValue value = JsonMapper::toJson(roomInfo);

    jsonData["page"] = page;
    jsonData["pageSize"] = pageSize;
    if (value.isObject()) {
        QJsonObject nested = value.toObject();
        for (const QString &key : nested.keys()) {
            if (!nested[key].isNull()) {
                jsonData[key] = nested[key];
            }
        }
    }

    // 活驴
    qDebug() << jsonData;
    QJsonDocument doc(jsonData);

    return TC::RequestClient::globalInstance()->postAsync("/room/list", doc);
}

QFuture<HttpResponse> getRoomApi(const QString &id)
{
    QJsonObject jsonData;
    jsonData["id"] = id;
    // 活驴
    qDebug() << jsonData;
    QJsonDocument doc(jsonData);

    return TC::RequestClient::globalInstance()->postAsync("/room", doc);
}
