#include "InteractiveHttp.h"
#include "InteractiveData.h"
#include "InteractiveFace.h"
#include "InteractiveHand.h"


#include "../user/config.h"
extern config *pconfig;

QString InteractiveHttp::strToken;

InteractiveHttp::InteractiveHttp(QObject *parent)
    : QObject{parent}
{

}


bool InteractiveHttp::httpRequestGet(const QString &url, const QByteArray &inData, QByteArray &outData)
{
    QNetworkAccessManager* pHttpMgr = new QNetworkAccessManager();
    QString strUrl = url;
    if(false == inData.isNull())
    {
        strUrl = strUrl + "?" + inData;
    }
    // 设置头信息
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(strUrl));
    requestInfo.setRawHeader("Authorization", InteractiveHttp::strToken.toUtf8());

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

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

    // 比如设置 1ms 内完成请求，否则就认为是超时
    QTimer::singleShot(HTTP_REQUEST_TIMEOUT_TIME, &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 InteractiveHttp::httpRequestPostJson(const QString &url, 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", InteractiveHttp::strToken.toUtf8());

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

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

    // 比如设置 1ms 内完成请求，否则就认为是超时
    QTimer::singleShot(HTTP_REQUEST_TIMEOUT_TIME, &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;
}

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

    QNetworkAccessManager* pHttpMgr = new QNetworkAccessManager();
    QString strUrl = url;

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

    for (int i = 0; i < inData.size(); ++i)
    {
        multiPart->append(inData.at(i));
    }


    // 设置头信息
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(url));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + multiPart->boundary());
    requestInfo.setRawHeader("Module", "Android_Material");
    requestInfo.setRawHeader("Authorization", InteractiveHttp::strToken.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_TIME, &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;
}

// 获取异常类型字典值
QByteArray InteractiveHttp::http_get_exception_type()
{
    QString strUrl = "http://" + pconfig->httpHost + "/system/dict/data/type/material_exception";
    QByteArray inData;
    QByteArray outData;

    httpRequestGet(strUrl, inData, outData);

    return outData;
}

// 获取严重等级字典值
QByteArray InteractiveHttp::http_get_severity_level()
{
    QString strUrl = "http://" + pconfig->httpHost + "/system/dict/data/type/severity_level";
    QByteArray inData;
    QByteArray outData;

    httpRequestGet(strUrl, inData, outData);

    return outData;
}

// 获取用户信息
QByteArray InteractiveHttp::http_get_getInfo()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + pconfig->getInfo_url;
    QByteArray inData;
    QByteArray outData;

    httpRequestGet(strUrl, inData, outData);

    return outData;
}

// 获取物资柜主界面显示信息
QByteArray InteractiveHttp::http_get_getCabinetHomePage()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + "/iscs/hardware/material-api/getCabinetHomePage";
    QByteArray inData = QString("cabinetCode=%1").arg(pconfig->devUuid).toUtf8();
    QByteArray outData;

    httpRequestGet(strUrl, inData, outData);

    return outData;
}


QByteArray InteractiveHttp::http_get_getInstructionsList()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + "/iscs/hardware/material-api/getInstructionsList";
    QByteArray inData;
    QByteArray outData;

    httpRequestGet(strUrl, inData, outData);

    return outData;
}


// 获取物资信息
QByteArray InteractiveHttp::http_get_getIsMaterialsPage()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + "/iscs/materials/getIsMaterialsPage";
    QByteArray inData = QString("current=1&size=-1&cabinetCode=%1").arg(pconfig->devUuid).toUtf8();
    QByteArray outData;

    httpRequestGet(strUrl, inData, outData);

    return outData;
}

// 开始检查
// url: /iscs/hardware/material-api/startCheckPlan
QByteArray InteractiveHttp::http_post_startCheckPlan()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + "/iscs/hardware/material-api/startCheckPlan";

    QByteArray inData;
    QByteArray outData;
    {
        QJsonObject jsonRoot;
        QDateTime currentDateTime = QDateTime::currentDateTime();
        qint64 timestampSeconds = currentDateTime.toMSecsSinceEpoch();

        jsonRoot.insert("cabinetCode", pconfig->devUuid);
        jsonRoot.insert("planId", pconfig->currentPlanId);

        QJsonDocument jsonDoc(jsonRoot);
        inData = jsonDoc.toJson(QJsonDocument::Compact);
    }

    httpRequestPostJson(strUrl, inData, outData);

    return outData;
}

QByteArray InteractiveHttp::http_post_insertCheckRecord(const QByteArray &json)
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + "/iscs/hardware/material-api/insertCheckRecord";

    QByteArray inData = json;
    QByteArray outData;
    httpRequestPostJson(strUrl, inData, outData);

    return outData;
}

QByteArray InteractiveHttp::http_post_selectMaterialsByRfidList(const QStringList &rfids)
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + pconfig->getMaterial_url;

    QByteArray inData;
    QByteArray outData;
    {
        QJsonObject jsonRoot;
        QDateTime currentDateTime = QDateTime::currentDateTime();
        qint64 timestampSeconds = currentDateTime.toMSecsSinceEpoch();

        QJsonArray jsonarray;
        for (const QString& str : rfids)
        {
            jsonarray.append(str);
        }
        jsonRoot.insert("list", jsonarray);
        QJsonDocument jsonDoc(jsonRoot);
        inData = jsonDoc.toJson(QJsonDocument::Compact);
    }

    httpRequestPostJson(strUrl, inData, outData);

    return outData;
}

// 获取物资柜物资错放异常
QByteArray InteractiveHttp::http_get_getIsMaterialsLoanExceptionPage()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + pconfig->getIsMaterialsLoanExceptionPage_url;
    QByteArray inData = QString("loanFromCode=" + pconfig->devUuid).toUtf8();
    inData += "&current=1&size=-1&exceptionType=0&status=0";
    QByteArray outData;

    httpRequestGet(strUrl, inData, outData);

    // TempWriteData("C:/Users/HP/Desktop/Temp/0.txt", outData);

    return outData;
}

QByteArray InteractiveHttp::http_get_getSysUserCharacteristicPage()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + pconfig->getSysUserCharacteristicPage_url;
    QByteArray inData = QString("userId=" + pconfig->userId).toUtf8();
    QByteArray outData;

    httpRequestGet(strUrl, inData, outData);

    return outData;
}

QByteArray InteractiveHttp::http_get_getLastCheckPlanByCabinetCode()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + pconfig->getMaterialCheckPlan_url;
    QByteArray inData = QString("cabinetCode=" + pconfig->devUuid).toUtf8();
    QByteArray outData;

    httpRequestGet(strUrl, inData, outData);

    return outData;
}

QByteArray InteractiveHttp::http_get_selectExMaterialTypeById()
{

    return QByteArray();
}

QByteArray InteractiveHttp::http_get_selectIsMaterialsCabinetByCode()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + "/iscs/cabinet/selectIsMaterialsCabinetByCode";
    QByteArray inData = QString("cabinetCode=" + pconfig->devUuid).toUtf8();
    QByteArray outData;

    httpRequestGet(strUrl, inData, outData);

    return outData;
}

QByteArray InteractiveHttp::http_post_insertSubmitPlan()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + pconfig->postSubmit_url;
    QByteArray inData;
    QByteArray outData;
    {
        QJsonObject jsonObjRoot;
        QString url = pconfig->postSubmit_url;
        jsonObjRoot.insert("cabinetCode", pconfig->devUuid);
        jsonObjRoot.insert("planId", pconfig->currentPlanId);

        QJsonDocument jsonDoc(jsonObjRoot);
        inData = jsonDoc.toJson(QJsonDocument::Compact);
    }

    httpRequestPostJson(strUrl, inData, outData);

    return outData;
}

// 上报异常
QByteArray InteractiveHttp::http_post_insertIsException(const QString &json)
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + "/iscs/exception/insertIsException";
    QByteArray inData = json.toUtf8();
    QByteArray outData;

    httpRequestPostJson(strUrl, inData, outData);

    return outData;
}

QByteArray InteractiveHttp::http_post_deleteSysUserCharacteristicByRecordIds(const QString &recordIds)
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + "/system/user/characteristic/deleteSysUserCharacteristicByRecordIds";
    // if (!recordIds.isEmpty())
    // {
    //     strUrl += "?recordIds=";
    //     for (int i = 0; i < recordIds.size(); ++i)
    //     {
    //         strUrl += recordIds.at(i);
    //         if (i != recordIds.size() - 1)
    //         {
    //             strUrl += ",";
    //         }
    //     }
    // }
    strUrl += recordIds;

    QByteArray inData;
    QByteArray outData;

    httpRequestPostJson(strUrl, inData, outData);

    return outData;
}

QByteArray InteractiveHttp::http_post_insertUserFace()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + pconfig->insertUserFace_url;
    QList<QHttpPart> inData;
    QByteArray outData;

    // 添加用户名
    QHttpPart httpPartUserName;
    httpPartUserName.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"userName\""));
    httpPartUserName.setBody(SINGLETON_CREATE(InteractiveData)()->m_userName.toUtf8());
    inData.append(httpPartUserName);

    // 添加用户图片
    QImage image = SINGLETON_CREATE(InteractiveFace)()->getImage();
    QByteArray imageData;
    QBuffer buffer(&imageData);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "PNG");

    QHttpPart httpPartImage;
    httpPartImage.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
    httpPartImage.setHeader(QNetworkRequest::ContentDispositionHeader,
                            QVariant(QString("form-data; name=\"file\"; filename=\"face.png\"")));

    httpPartImage.setBody(imageData);
    inData.append(httpPartImage);

    httpRequestPostFormdata(strUrl, inData, outData);

    // TempWriteData("C:/Users/HP/Desktop/Temp/1.txt", outData);

    return outData;
}

QByteArray InteractiveHttp::http_post_insertUserFingerprintDat(const QString &group)
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + pconfig->addfinger_url;
    QList<QHttpPart> inData;
    QByteArray outData;

    // 添加用户名
    QHttpPart httpPartUserName;
    httpPartUserName.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"userName\""));
    httpPartUserName.setBody(SINGLETON_CREATE(InteractiveData)()->m_userName.toUtf8());
    inData.append(httpPartUserName);

    // 添加用户组
    QHttpPart httpPartUserGroup;
    httpPartUserGroup.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"group\""));
    httpPartUserGroup.setBody(group.toUtf8());
    inData.append(httpPartUserGroup);

    // 添加用户图片
    QImage image = SINGLETON_CREATE(InteractiveHand)()->getImage();
    QByteArray imageData;
    QBuffer buffer(&imageData);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "BMP");

    QHttpPart httpPartImage;
    httpPartImage.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/bmp"));
    httpPartImage.setHeader(QNetworkRequest::ContentDispositionHeader,
                            QVariant(QString("form-data; name=\"file\"; filename=\"face.bmp\"")));

    httpPartImage.setBody(imageData);
    inData.append(httpPartImage);

    httpRequestPostFormdata(strUrl, inData, outData);

    return outData;
}

QByteArray InteractiveHttp::http_post_loginByFace()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + pconfig->loginByFace_url;
    QList<QHttpPart> inData;
    QByteArray outData;

    // 添加用户图片
    QImage image = SINGLETON_CREATE(InteractiveFace)()->getImage();
    QByteArray imageData;
    QBuffer buffer(&imageData);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "PNG");

    QHttpPart httpPartImage;
    httpPartImage.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
    httpPartImage.setHeader(QNetworkRequest::ContentDispositionHeader,
                            QVariant(QString("form-data; name=\"file\"; filename=\"face.png\"")));

    httpPartImage.setBody(imageData);
    inData.append(httpPartImage);

    httpRequestPostFormdata(strUrl, inData, outData);

    return outData;
}

QByteArray InteractiveHttp::http_post_loginByFingerprintDat()
{
    // 访问http服务
    QString strUrl = "http://" + pconfig->httpHost + pconfig->fingerLogin_url;
    QList<QHttpPart> inData;
    QByteArray outData;

    // 添加用户图片
    QImage image = SINGLETON_CREATE(InteractiveHand)()->getImage();
    QByteArray imageData;
    QBuffer buffer(&imageData);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "BMP");


    QHttpPart httpPartImage;
    httpPartImage.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/bmp"));
    httpPartImage.setHeader(QNetworkRequest::ContentDispositionHeader,
                            QVariant(QString("form-data; name=\"file\"; filename=\"face.bmp\"")));

    httpPartImage.setBody(imageData);
    inData.append(httpPartImage);

    httpRequestPostFormdata(strUrl, inData, outData);

    return outData;
}

// 用于临时存储服务器请求响应的函数
// TempWriteData("C:/Users/HP/Desktop/Temp/0.txt", outData);
void InteractiveHttp::TempWriteData(const QString &path, const QByteArray &data)
{
    QFile file(path);
    if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
        file.write(data);
        file.close();
    }
}
