#include "httpclient.h"
#include "config.h"
#include <QtCore>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QHttpMultiPart>
#include <QtNetwork/QHttpPart>

extern config *pconfig;

QString httpClient::sToken;

httpClient::httpClient(QObject *parent) : QThread(parent)
{

}

void httpClient::slot_post_request_data(quint64 id, QString postUrl, QByteArray data, QByteArray file, QString token)
{
    mutex.lock();
    this->id = id;
    this->postUrl = postUrl;
    this->httpData = data;
    this->httpFile = file;
    this->token = token;
    httpClient::sToken = token;
    if(false == this->httpData.isNull() && false == this->httpFile.isNull())
    {
        workStat = httpWorkStat::httpWorkFormdata;
    }
    else if(false == this->httpData.isNull())
    {
        workStat = httpWorkStat::httpWorkJson;
    }
    else if(false == this->httpFile.isNull())
    {
        workStat = httpWorkStat::httpWorkFormdata;
    }
}

void httpClient::slot_get_request_data(quint64 id, QString postUrl, QByteArray data, QString token)
{
    mutex.lock();
    this->id = id;
    this->postUrl = postUrl;
    this->httpData = data;
    this->token = token;
    httpClient::sToken = token;
    workStat = httpWorkStat::httpWorkGet;
}

void httpClient::slot_set_thread_stop(void)
{
    this->threadstatus = false;
}



bool httpClient::getRequest(const QString &url, const QString &token, const QByteArray &inData, QByteArray &outData)
{
    QNetworkAccessManager* pHttpMgr = new QNetworkAccessManager();
    // QString url = "http://" + pconfig->httpHost;
    // url = url + postUrl;
    QString strUrl = url;
    if(false == inData.isNull())
    {
        strUrl = strUrl + "?" + inData;
    }
    // 设置头信息
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(strUrl));
    requestInfo.setRawHeader("Authorization", token.toUtf8());

    // 发送 post 请求
    QNetworkReply* reply = pHttpMgr->get(requestInfo);

    // 添加超时处理，1ms 超时
    QEventLoop eventLoop;
    connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));

    // 比如设置 1ms 内完成请求，否则就认为是超时
    QTimer::singleShot(HTTP_REQUEST_TIMEOUT, &eventLoop, &QEventLoop::quit);
    eventLoop.exec();

    QByteArray array;
    if(reply->isFinished()){
        if (reply->error() == QNetworkReply::NoError) {
            // 正常结束，读取响应数据
            QByteArray result = reply->readAll();
            QString strResult = QString::fromUtf8(result);
            reply->deleteLater();
            outData = strResult.toUtf8();
            return true;
        }
        else {
            // 异常结束
            // 请求失败
            QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

            outData = QString("{\"code\":" + statusCode.toString() + ",\"result\":\"" + reply->errorString() + "\"}").toUtf8();
            reply->deleteLater();
            return false;
        }
    }
    else {
        // 请求超时
        disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
        reply->abort();

    }

    reply->deleteLater();

    outData =  "{\"code\":400,\"result\":\"failure\"}";
    return false;
}

bool httpClient::postRequest(const QString &url, const QString &token, const QByteArray &inData, QByteArray &outData)
{
    // 获取当前日期和时间
    QDateTime currentDateTime = QDateTime::currentDateTime();
    QString timetamp_str = currentDateTime.toString("yyyy-MM-ddTHH:mm:ssZ");

    QNetworkAccessManager* pHttpMgr = new QNetworkAccessManager();
    QString strUrl = url;
    // 设置头信息
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(strUrl));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
    requestInfo.setRawHeader("Module", "Android_Material");
    requestInfo.setRawHeader("Authorization", token.toUtf8());

    // 发送 post 请求
    QNetworkReply* reply = pHttpMgr->post(requestInfo, inData);

    // 添加超时处理，1ms 超时
    QEventLoop eventLoop;
    connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));

    // 比如设置 1ms 内完成请求，否则就认为是超时
    QTimer::singleShot(HTTP_REQUEST_TIMEOUT, &eventLoop, &QEventLoop::quit);
    eventLoop.exec();

    if(reply->isFinished()){
        if (reply->error() == QNetworkReply::NoError) {
            // 正常结束，读取响应数据
            QByteArray result = reply->readAll();
            outData = result;
            reply->deleteLater();
            return true;
        }
        else {
            // 异常结束
            // 请求失败
            QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

            // qDebug() << "http post failed, error code = " << statusCode.toString() << " error info: " << reply->errorString();
            outData = QString("{\"code\":" + statusCode.toString() + ",\"result\":\"" + reply->errorString() + "\"}").toUtf8();
            reply->deleteLater();
            return false;
        }
    }
    else {
        // 请求超时
        disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
        reply->abort();
    }

    reply->deleteLater();

    outData = "{\"code\":400,\"result\":\"failure\"}";
    return false;
}


QString httpClient::post_json_request(void)
{
    // 获取当前日期和时间
    QDateTime currentDateTime = QDateTime::currentDateTime();
    // qint64 timestampSeconds = currentDateTime.toSecsSinceEpoch();
    QString timetamp_str = currentDateTime.toString("yyyy-MM-ddTHH:mm:ssZ");

    QNetworkAccessManager* pHttpMgr = new QNetworkAccessManager();
    QString url = "http://";
    url = url + pconfig->httpHost + postUrl;
    // qDebug() << url;
    // 设置头信息
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(url));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
    requestInfo.setRawHeader("Module", "Android_Material");
    QString auth = token;
    requestInfo.setRawHeader("Authorization", auth.toUtf8());

    // QString strInfo = requestInfo.url().toString();

    // 发送 post 请求
    QNetworkReply* reply = pHttpMgr->post(requestInfo, httpData);

    // 添加超时处理，1ms 超时
    QEventLoop eventloop;
    connect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));

    // 比如设置 1ms 内完成请求，否则就认为是超时
    QTimer::singleShot(HTTP_REQUEST_TIMEOUT, &eventloop, &QEventLoop::quit);
    eventloop.exec();

    QByteArray array;
    if(reply->isFinished()){
        if (reply->error() == QNetworkReply::NoError) {
            // 正常结束，读取响应数据
            QByteArray result = reply->readAll();
            QString strRes = QString::fromUtf8(result);

            // qDebug() << "http post success post response=" << strRes;
            reply->deleteLater();
            return strRes;
        }
        else {
            // 异常结束
            // 请求失败
            QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

            // qDebug() << "http post failed, error code = " << statusCode.toString() << " error info: " << reply->errorString();
            QString strRes = "{\"code\":" + statusCode.toString() + ",\"result\":\"" + reply->errorString() + "\"}";
            reply->deleteLater();
            return strRes;
        }
    }
    else {
        // 请求超时
        disconnect(reply, &QNetworkReply::finished, &eventloop, &QEventLoop::quit);
        reply->abort();
        // qDebug() << "http post timeout";
    }

    reply->deleteLater();

    return "{\"code\":400,\"result\":\"failure\"}";
}

QString httpClient::post_formdata_request(void)
{
    // 获取当前日期和时间
    QDateTime currentDateTime = QDateTime::currentDateTime();
    // qint64 timestampSeconds = currentDateTime.toSecsSinceEpoch();
    QString timetamp_str = currentDateTime.toString("yyyy-MM-ddTHH:mm:ssZ");

    QNetworkAccessManager* pHttpMgr = new QNetworkAccessManager();
    QString url = "http://";
    url = url + pconfig->httpHost + postUrl;
    // qDebug() << url;

    // 创建multipart表单
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    if(false == httpData.isNull())
    {
        // qDebug() << "httpData=" << QString::fromUtf8(httpData);
        // 添加JSON数据部分
        QHttpPart jsonPart;
        jsonPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"userName\""));
        jsonPart.setBody(httpData);
        multiPart->append(jsonPart);
    }

    // 添加文件部分
    QHttpPart filePart;
    filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/bmp"));
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
                       QVariant(QString("form-data; name=\"file\"; filename=\"finger.bmp\"")));


    // qDebug() << "Hex string:" << httpFile.toHex().constData();
    QBuffer *buffer = new QBuffer(&httpFile);
    if (!buffer->open(QIODevice::ReadOnly)) {
        qDebug() << "无法打开缓冲区";
        delete buffer;
        delete multiPart;
        return "{\"code\":400,\"result\":\"无法打开缓冲区\"}";
    }
    filePart.setBodyDevice(buffer);
    buffer->setParent(multiPart); // 设置父对象以便自动清理

    // QFile *file = new QFile("C:\\Users\\porkling\\Downloads\\finger\\1\\image_0.bmp");
    // if (!file->open(QIODevice::ReadOnly)) {
    //     qDebug() << "无法打开BMP文件:" << file->errorString();
    //     delete file;
    //     delete multiPart;
    //     return "{\"code\":400,\"result\":\"无法打开缓冲区\"}";
    // }
    // filePart.setBodyDevice(file);
    // file->setParent(multiPart); // 设置父对象以便自动清理

    multiPart->append(filePart);


    // 设置头信息
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(url));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + multiPart->boundary());
    requestInfo.setRawHeader("Module", "Android_Material");
    QString auth = token;
    requestInfo.setRawHeader("Authorization", auth.toUtf8());


    // 发送 post 请求
    QNetworkReply* reply = pHttpMgr->post(requestInfo, multiPart);
    multiPart->setParent(reply); // reply删除时会自动删除multiPart

    // 添加超时处理，1ms 超时
    QEventLoop eventloop;
    connect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));

    // 比如设置 1ms 内完成请求，否则就认为是超时
    QTimer::singleShot(HTTP_REQUEST_TIMEOUT, &eventloop, &QEventLoop::quit);
    eventloop.exec();

    QByteArray array;
    if(reply->isFinished()){
        if (reply->error() == QNetworkReply::NoError) {
            // 正常结束，读取响应数据
            QByteArray result = reply->readAll();
            QString strRes = QString::fromUtf8(result);

            // qDebug() << "http post success post response=" << strRes;
            reply->deleteLater();
            return strRes;
        }
        else {
            // 异常结束
            // 请求失败
            QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

            // qDebug() << "http post failed, error code = " << statusCode.toString() << " error info: " << reply->errorString();
            QString strRes = "{\"code\":" + statusCode.toString() + ",\"result\":\"" + reply->errorString() + "\"}";
            reply->deleteLater();
            return strRes;
        }
    }
    else {
        // 请求超时
        disconnect(reply, &QNetworkReply::finished, &eventloop, &QEventLoop::quit);
        reply->abort();
        // qDebug() << "http post timeout";
    }

    reply->deleteLater();

    return "{\"code\":400,\"result\":\"failure\"}";
}

QString httpClient::get_request(void)
{
    QNetworkAccessManager* pHttpMgr = new QNetworkAccessManager();
    QString url = "http://" + pconfig->httpHost;
    url = url + postUrl;
    if(false == httpData.isNull())
    {
        url = url + "?" + httpData;
    }
    qDebug() << url;
    // 设置头信息
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(url));
    QString auth = token;
    requestInfo.setRawHeader("Authorization", auth.toUtf8());

    // 发送 post 请求
    QNetworkReply* reply = pHttpMgr->get(requestInfo);

    // 添加超时处理，1ms 超时
    QEventLoop eventloop;
    connect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));

    // 比如设置 1ms 内完成请求，否则就认为是超时
    QTimer::singleShot(HTTP_REQUEST_TIMEOUT, &eventloop, &QEventLoop::quit);
    eventloop.exec();

    QByteArray array;
    if(reply->isFinished()){
        if (reply->error() == QNetworkReply::NoError) {
            // 正常结束，读取响应数据
            QByteArray result = reply->readAll();
            QString strRes = QString::fromUtf8(result);

            // qDebug() << "http post success post response=" << strRes;
            reply->deleteLater();
            return strRes;
        }
        else {
            // 异常结束
            // 请求失败
            QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

            // qDebug() << "http post failed, error code = " << statusCode.toString() << " error info: " << reply->errorString();
            QString strRes = "{\"code\":" + statusCode.toString() + ",\"result\":\"" + reply->errorString() + "\"}";
            reply->deleteLater();
            return strRes;
        }
    }
    else {
        // 请求超时
        disconnect(reply, &QNetworkReply::finished, &eventloop, &QEventLoop::quit);
        reply->abort();
        // qDebug() << "http post timeout";
    }

    reply->deleteLater();

    return "{\"code\":400,\"result\":\"failure\"}";
}

void httpClient::run()
{
    while(this->threadstatus)
    {
        if(workStat != httpWorkStat::httpWorkSleep)
        {
            QString res = "";
            switch(workStat)
            {
            case httpWorkStat::httpWorkJson:res = post_json_request();break;
            case httpWorkStat::httpWorkFormdata:res = post_formdata_request();break;
            case httpWorkStat::httpWorkGet:res = get_request();break;
            }

            QByteArray bb = res.toUtf8();
            mutex.unlock();
            workStat = httpWorkStat::httpWorkSleep;
            emit signal_response_data(id, postUrl, bb);
        }

        msleep(10);
    }
    qDebug() << "httpclient thread exit!";
}
