#include "tchttpservice.h"
QScopedPointer<TCHttpService> TCHttpService::m_instance;

TCHttpService *TCHttpService::getInstance()
{
    if (m_instance.isNull()) {
        m_instance.reset(new TCHttpService);
    }

    return m_instance.data();
}

void TCHttpService::apiLogin()
{
    QByteArray pwdMd5 = QCryptographicHash::hash(m_firstPwd.toUtf8(), QCryptographicHash::Md5);
    QString md5Hex = pwdMd5.toHex();

    QString urlStr;
//    if (m_enableSsl)
        urlStr = "https://" + m_domain + "/api/login";
//    else
//        urlStr = "http://" + m_domain + "/api/login";

    QUrl url(urlStr);
    QJsonObject jsonObj;
    jsonObj["user"]="test1";
    jsonObj["pwd"]=md5Hex;
    QJsonDocument jsonDoc(jsonObj);
    QByteArray jsonData = jsonDoc.toJson();
    QMap<QString, QString> headers;
    headers.insert("Content-Type", "application/json");

    QNetworkReply* reply = nullptr;
//    qDebug() <<url;
//    QNetworkRequest request(url);
//    reply = m_manager.post(request, jsonData);

//        QObject::connect(reply, &QNetworkReply::finished, [this, reply]() {

//        emit requestFinished(reply);
//    });
    Post(url, headers, {}, jsonData, 1);
}

void TCHttpService::apiMyfileCount()
{
    QString urlStr;
    if (m_enableSsl)
        urlStr = "https://" + m_domain + "/api/myfiles";
    else
        urlStr = "http://" + m_domain + "/api/myfiles";

    QMap<QString, QString> headers;
    headers.insert("Content-Type", "application/json");
    QString bodyStr = QString("\"%1\":\"%2\",\"%3\":\"%4\"").arg("token").arg(m_token).arg("user").arg(m_userName);
    QMap<QString, QString> params;
    params.insert("cmd", "count");
//    QNetworkReply* reply = Post(urlStr, headers, params, bodyStr.toUtf8());

//    QObject::connect(reply, &QNetworkReply::finished, [this, reply]{

//        QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
//        QJsonObject jsonObj = jsonDoc.object();

//        int code = jsonObj["code"].toInt();

//        if (code == 0) {
//            int total = jsonObj["total"].toInt();
//            this->m_total = total;
//        }

//        reply->deleteLater();
//    });

}

void TCHttpService::apiMyfileNormal()
{
    QString urlStr;
    if (m_enableSsl)
        urlStr = "https://" + m_domain + "/api/myfiles";
    else
        urlStr = "http://" + m_domain + "/api/myfiles";

    QMap<QString, QString> headers;
    headers.insert("Content-Type", "application/json");

    QMap<QString, QString> params;
    params.insert("cmd", "normal");
    QString bodyStr = QString("\"%1\":\"%2\",\"%3\":\"%4\",\"%5\":\"%6\",\"%7\":\"%8\"").arg("token").arg(m_token).
            arg("user").arg(m_userName).arg("count").arg(m_total).arg("start").arg(0);
//    QNetworkReply* reply = Post(QUrl(urlStr), headers, params, bodyStr.toUtf8());

//    QObject::connect(reply, &QNetworkReply::finished, [this, reply]{
//       QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
//       QJsonObject jsonObj = jsonDoc.object();

//       int code = jsonObj["code"].toInt();
//       if (code == 0) {
//           int count = jsonObj["count"].toInt();
//           if (count != 0) {
//               QJsonArray array = jsonObj["files"].toArray();
//               for (const QJsonValue& value : array) {
//                   QJsonObject item = value.toObject();
//                   updateFileMap(item);
//               }
//           }
//       }

//       reply->deleteLater();
//    });
}

void TCHttpService::apiMd5(const QString& filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        return;
    }

    QByteArray fileMd5;
    QCryptographicHash hash(QCryptographicHash::Md5);
    if (hash.addData(&file)) {
         fileMd5 = hash.result().toHex();
    }
    else
        return;

    QString urlStr;
    if (m_enableSsl)
        urlStr = "https://" + m_domain + "/api/md5";
    else
        urlStr = "http://" + m_domain + "/api/md5";
    QMap<QString, QString> headers;
    headers.insert("Content-Type", "application/json");
    QString md5Str = QString::fromUtf8(fileMd5);
    QString bodyStr = QString("\"%1\":\"%2\",\"%3\":\"%4\",\"%5\":\"%6\",\"%7\":\"%8\"").arg("token").arg(m_token).
            arg("md5").arg(md5Str).arg("filename").arg(QFileInfo(file).fileName()).arg("user").arg(m_userName);
    file.close();
//    QNetworkReply* reply = Post(urlStr, headers, {}, bodyStr.toUtf8());

//    QObject::connect(reply, &QNetworkReply::finished, [this, reply, filePath, md5Str]{
//        QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
//        QJsonObject jsonObj = jsonDoc.object();
//        int code = jsonObj["code"].toInt();
//        switch (code) {
//        case 0:
//            break;
//        case 1:
//            apiUpload(filePath, md5Str);
//            break;
//        }
//    });
}

void TCHttpService::apiUpload(const QString &filePath, const QString &md5Str)
{
    QString urlStr;
    if (m_enableSsl)
        urlStr = "https://" + m_domain + "/api/upload";
    else
        urlStr = "http://" + m_domain + "/api/upload";

    QFile file(filePath);
    QFileInfo info(file);

    QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    QHttpPart filePart;
    QString contentTypeStrFile = QString("form-data; name=\"file\"; filename=\"%1\"").arg(info.fileName());
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
                       QVariant(contentTypeStrFile));
    filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
    if (!file.open(QIODevice::ReadOnly)) {
        return;
    }

    filePart.setBodyDevice(&file);
    file.setParent(multiPart);
    multiPart->append(filePart);


    QHttpPart userPart;
    QString contentTypeStrUser = QString("form-data; name=\"user\"");
    userPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(contentTypeStrUser));
    userPart.setBody(m_userName.toUtf8());
    multiPart->append(userPart);

    QHttpPart md5Part;
    QString contentTypeStrMd5 = QString("form-data; name=\"md5\"");
    md5Part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentTypeStrMd5));
    md5Part.setBody(md5Str.toUtf8());
    multiPart->append(md5Part);

    QHttpPart sizePart;
    QString contentTypeStrSize = QString("form-data; name=\"size\"");
    sizePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentTypeStrSize));
    sizePart.setBody(QString::number(info.size()).toUtf8());
    multiPart->append(sizePart);

    QUrl url(urlStr);
    QNetworkRequest request(url);

    QNetworkReply* reply = m_manager.post(request, multiPart);
    multiPart->setParent(reply);

    QObject::connect(reply, &QNetworkReply::finished, [this, reply]{
        QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
        QJsonObject jsonObj = jsonDoc.object();

        int code = jsonObj["code"].toInt();
        if (code == 0) {
            emit signal_uploadSuc();
        }
        reply->deleteLater();
    });

}

void TCHttpService::apiSharePicShare(const QString &fileName, const QString &md5)
{

    QString urlStr;
    if (m_enableSsl)
        urlStr = "https://" + m_domain + "/api/sharepic";
    else
        urlStr = "http://" + m_domain + "/api/sharepic";

    QMap<QString, QString> headers;
    QMap<QString, QString> body;
    QMap<QString, QString> params;

    headers.insert("Content-Type", "application/json");

    QString bodyStr = QString("\"%1\":\"%2\",\"%3\":\"%4\",\"%5\":\"%6\",\"%7\":\"%8\"").arg("token").arg(m_token).
            arg("user").arg(m_userName).arg("md5").arg(md5).arg("filename").arg(fileName);

    params.insert("cmd", "share");

//    QNetworkReply* reply = Post(QUrl(urlStr), headers, params, bodyStr.toUtf8());

//    QObject::connect(reply, &QNetworkReply::finished, [this, reply]{
//        QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
//        QJsonObject jsonObj = jsonDoc.object();

//        int code = jsonObj["code"].toInt();
//        if (code == 0) {
//            emit signal_shareSuc();
//        }
//        reply->deleteLater();
//    });
}

void TCHttpService::setConfiguration(QString userName, QString firstPwd, QString domain)
{
    qDebug() << "setConfiguration";
    this->m_domain = domain;
    this->m_userName = userName;
    this->m_firstPwd = firstPwd;
    connect(this, &TCHttpService::requestFinished, [](QNetworkReply* reply){
        qDebug() << "readall";
        qDebug() <<reply->readAll();
        reply->deleteLater();
    });
    apiLogin();
}

void TCHttpService::setSsl(bool enable)
{
    qDebug() << "setSsl:" <<enable;
    this->m_enableSsl = enable;
}

QNetworkReply *TCHttpService::Get(const QUrl &url, const QMap<QString, QString> headers, const QMap<QString, QString> params)
{
    QUrlQuery query;
    for (auto ite = params.constBegin(); ite != params.constEnd(); ite++) {
        query.addQueryItem(ite.key(), ite.value());
    }

    QUrl requestUrl = url;
    requestUrl.setQuery(query);

    QNetworkRequest request(requestUrl);

    for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++) {
        request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8());
    }

    QNetworkReply* reply = m_manager.get(request);

    return reply;
}

QNetworkReply *TCHttpService::Post(const QUrl &url, const QMap<QString, QString> headers, const QMap<QString, QString> params, const QByteArray body)
{

}

QByteArray TCHttpService::Post(QUrl url, QMap<QString, QString> headers, QMap<QString, QString> params, QByteArray body, int i)
{
    QUrlQuery query;
    for (auto ite = params.constBegin(); ite != params.constEnd(); ite++) {
        query.addQueryItem(ite.key(), ite.value());
    }

    QUrl requestUrl = url;
    requestUrl.setQuery(query);
    qDebug() << requestUrl;
    QNetworkRequest request(url);

//    for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++) {
//        request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8());
//    }
    qDebug() << 1;
    QJsonObject jsonObj;
    jsonObj["user"]="test1";
    jsonObj["pwd"]="e10adc3949ba59abbe56e057f20f883e";
    QJsonDocument jsonDoc(jsonObj);
    QByteArray jsonData = jsonDoc.toJson();
    qDebug() << 2;
    QNetworkReply* reply = nullptr;
    qDebug() << 3;
    reply = m_manager.post(request, jsonData);
    qDebug() << 4;
    QObject::connect(reply, &QNetworkReply::finished, [this, reply](){
//        QByteArray respData = reply->readAll();
//        qDebug() <<respData;
//        return respData;
//        reply->deleteLater();
        qDebug() << "emit requestFinished";
//        emit requestFinished(reply);
    });

}

void TCHttpService::updateFileMap(QJsonObject jsonObj)
{
    QString fileMD5 = jsonObj["md5"].toString();
    QString fileUrl = jsonObj["http"].toString();

    QMap<QString, QString>::iterator ite = m_fileMap.begin();
    if (ite != m_fileMap.end())
        return;

    m_fileMap.insert(fileMD5, fileUrl);
}

TCHttpService::TCHttpService(QObject *parent) : QObject(parent)
{

}
