#include "backendapimanager.h"

#include <QEventLoop>

backendAPIManager *backendAPIManager::s_instance = nullptr;

void backendAPIManager::initialize(const QString &backendUrl) {
    if (!s_instance) {
        s_instance = new backendAPIManager(backendUrl);
    }
}

void backendAPIManager::cleanup() {
    if (s_instance) {
        delete s_instance;
        s_instance = nullptr;
    }
}

void backendAPIManager::setAuthToken(const QString &token) {
    if (s_instance) {
        s_instance->authToken = token;
    }
}

backendAPIManager::backendAPIManager(const QString &backendUrl, QObject *parent)
    : QObject(parent), backendUrl(backendUrl), requestSuccess(false) {
    networkManager = new QNetworkAccessManager(this);
}

backendAPIManager::~backendAPIManager() {
    if (networkManager) {
        delete networkManager;
        networkManager = nullptr;
    }
}

void backendAPIManager::setupRequest(QNetworkRequest &request, const QString &endpoint) {
    request.setUrl(QUrl(backendUrl + endpoint));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    if (!s_instance->authToken.isEmpty()) {
        request.setRawHeader("Authorization", s_instance->authToken.toUtf8());
    }
}

QNetworkReply *backendAPIManager::sendRequest(const QString &endpoint, const QJsonObject &data,
                                              const QString &method) {
    QNetworkRequest request;
    setupRequest(request, endpoint);

    QJsonDocument doc(data);
    QByteArray jsonData = doc.toJson();

    QNetworkReply *reply = nullptr;
    if (method == "GET") {
        reply = networkManager->get(request);
    } else if (method == "POST") {
        reply = networkManager->post(request, jsonData);
    } else if (method == "PUT") {
        reply = networkManager->put(request, jsonData);
    } else if (method == "DELETE") {
        reply = networkManager->deleteResource(request);
    }

    return reply;
}

bool backendAPIManager::uploadBlastProjectFull(const QJsonObject &projectData) {
    if (!s_instance) return false;

    s_instance->requestSuccess = false;
    QNetworkReply *reply = s_instance->sendRequest("blastrecord/pc", projectData, "POST");

    // 使用事件循环等待响应
    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    if (reply->error() == QNetworkReply::NoError) {
        QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
        s_instance->handleUploadFinished(response, reply->url());
    } else {
        s_instance->handleUploadError(reply->errorString());
    }

    reply->deleteLater();
    return s_instance->requestSuccess;
}

QJsonArray backendAPIManager::getSysUsers() {
    if (!s_instance) return QJsonArray();

    QNetworkReply *reply = s_instance->sendRequest("sys-user", QJsonObject(), "GET");

    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    QJsonArray result;
    if (reply->error() == QNetworkReply::NoError) {
        QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
        result = response.object()["data"].toObject()["list"].toArray();
    }

    reply->deleteLater();
    return result;
}

QJsonArray backendAPIManager::getHAddresses() {
    if (!s_instance) return QJsonArray();

    QNetworkReply *reply = s_instance->sendRequest("h-address/pc", QJsonObject(), "GET");

    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    QJsonArray result;
    if (reply->error() == QNetworkReply::NoError) {
        QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
        result = response.object()["data"].toArray();
    }

    reply->deleteLater();
    return result;
}

bool backendAPIManager::uploadBlastProject(const QJsonObject &projectData) {
    if (!s_instance) return false;

    s_instance->requestSuccess = false;
    QNetworkReply *reply = s_instance->sendRequest("blastrecord", projectData, "POST");

    // 使用事件循环等待响应
    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    if (reply->error() == QNetworkReply::NoError) {
        QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
        s_instance->handleUploadFinished(response, reply->url());
    } else {
        s_instance->handleUploadError(reply->errorString());
    }

    reply->deleteLater();
    return s_instance->requestSuccess;
}

bool backendAPIManager::uploadBlastProjectDets(const QJsonObject &detsData) {
    if (!s_instance) return false;

    s_instance->requestSuccess = false;
    QNetworkReply *reply = s_instance->sendRequest("blastrecorddet/batch", detsData, "POST");

    // 使用事件循环等待响应
    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    if (reply->error() == QNetworkReply::NoError) {
        QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
        s_instance->handleUploadFinished(response, reply->url());
    } else {
        s_instance->handleUploadError(reply->errorString());
    }

    reply->deleteLater();
    return s_instance->requestSuccess;
}

bool backendAPIManager::uploadBlastEquipments(const QJsonObject &regDetsData) {
    if (!s_instance) return false;

    s_instance->requestSuccess = false;
    QNetworkReply *reply = s_instance->sendRequest("blastrecordequipment", regDetsData, "POST");

    // 使用事件循环等待响应
    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    if (reply->error() == QNetworkReply::NoError) {
        QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
        s_instance->handleUploadFinished(response, reply->url());
    } else {
        s_instance->handleUploadError(reply->errorString());
    }

    reply->deleteLater();
    return s_instance->requestSuccess;
}

void backendAPIManager::handleUploadFinished(const QJsonDocument &response, const QUrl &url) {
    // Check response status
    if (response.object().contains("code")) {
        int code = response.object()["code"].toInt();
        requestSuccess = (code == 200);
    } else {
        requestSuccess = false;
    }

    emit uploadFinished(response);
}

void backendAPIManager::handleUploadError(const QString &error) {
    requestSuccess = false;
    emit uploadError(error);
}
