#include "requestprocessor.h"
#include <QDebug>
#include <QNetworkReply>

RequestProcessor::RequestProcessor(QObject *parent)
    : QObject(parent)
    , m_networkManager(new QNetworkAccessManager(this))
{
}

void RequestProcessor::execute(Request *request)
{
    if (!request) {
        qWarning() << "[RequestProcessor] Null request";
        return;
    }

    QNetworkRequest netRequest = request->toNetworkRequest();
    QNetworkReply *reply = nullptr;

    switch (request->method()) {
    case Request::Method::GET:
        reply = m_networkManager->get(netRequest);
        break;
    case Request::Method::POST:
        reply = m_networkManager->post(netRequest, request->body());
        break;
    case Request::Method::PUT:
        reply = m_networkManager->put(netRequest, request->body());
        break;
    case Request::Method::DELETE:
        reply = m_networkManager->deleteResource(netRequest);
        break;
    case Request::Method::PATCH:
        reply = m_networkManager->sendCustomRequest(netRequest, "PATCH", request->body());
        break;
    }

    if (reply) {
        m_pendingRequests.insert(reply, request);
        connect(reply, &QNetworkReply::finished, this, [this, reply]() {
            onReplyFinished(reply);
        });
    }
}

void RequestProcessor::cancelAll()
{
    for (auto it = m_pendingRequests.begin(); it != m_pendingRequests.end(); ++it) {
        it.key()->abort();
        it.key()->deleteLater();
    }
    m_pendingRequests.clear();
}

void RequestProcessor::onReplyFinished(QNetworkReply *reply)
{
    if (!reply) return;

    Request *request = m_pendingRequests.value(reply, nullptr);
    if (!request) {
        reply->deleteLater();
        return;
    }

    QString accountId = request->accountId();
    int httpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    if (reply->error() == QNetworkReply::NoError) {
        QByteArray data = reply->readAll();
        QJsonDocument doc = QJsonDocument::fromJson(data);
        emit requestFinished(accountId, doc);
    } else {
        QString errorMsg = reply->errorString();
        qWarning() << "[RequestProcessor] Error:" << httpCode << errorMsg;
        emit requestFailed(accountId, httpCode, errorMsg);
    }

    m_pendingRequests.remove(reply);
    reply->deleteLater();
    request->deleteLater();
}
