#include "ordergetwork.h"

#include "preDefine.h"

#include "event/fmapplication.h"
#include "event/posevent.h"

#include "model/posorderpool.h"

#include <QTimer>
#include <QEventLoop>
#include <QVariantMap>
#include <QSettings>

#include "QsLog.h"

OrderGetWork::OrderGetWork(QObject *parent) : QObject(parent)
{
    _timeout = VALUE_PULLSYNCTIME;
    _stopflag = false;
    _islogin = false;
    _timestamp = "0";

    //订阅需要拉单的事件
    FMApplication::subscibeEvent(this, PosEvent::s_need_get_order);
    //订阅操作订单的事件
    FMApplication::subscibeEvent(this, PosEvent::s_opt_order);
    //
    FMApplication::subscibeEvent(this, PosEvent::s_login_storeinfo);
}

void OrderGetWork::workStart()
{
    QLOG_INFO() << "OrderGetWork::workStart : " << QThread::currentThreadId();

    while(!_stopflag)
    {
        unsigned int tmptime = _timeout;
        unsigned int nexttime = _timeout;
        QString error;

        do
        {
            if(_islogin && !PullOrder(nexttime, error))
            {
                QLOG_ERROR()  << QThread::currentThreadId() << "PullOrder failed";
                tmptime = _timeout;
                QVariantMap map;
                map.insert(EVENT_KEY_STATUS, false);
                map.insert(EVENT_KEY_MSG, error);

                POSTEVENTTYPE(PosEvent::s_get_order_status,map,QVariantMap);
                break;
            }

            tmptime = nexttime;
            QLOG_INFO() << QThread::currentThreadId() << "next workStart timeout : " << tmptime;

        }while(0);

        QEventLoop loop;

        QTimer::singleShot(tmptime, this, &OrderGetWork::quit);

        connect(this, &OrderGetWork::quit, &loop, &QEventLoop::quit);

        loop.exec();
    }
}

#ifdef FM_TEST
#include <QFile>
#include <QJsonDocument>

bool OrderGetWork::PullOrder(unsigned int timeout, QString &error)
{
    error.clear();

    QJsonObject json, recvjson;
    QString realurl;

    QFile file(FMApplication::applicationDirPath() + "/" + "ordertest.txt");

    if(!file.open(QFile::ReadOnly))
    {
        QLOG_ERROR() << "open ordertest.txt failed";
        timeout = 10000;
        error = QString::fromLocal8Bit("打开本地测试订单文件失败");
        return false;
    }

    QByteArray tmparray = file.readAll();

    QLOG_INFO() << tmparray.data();

    QJsonParseError errors;
    QJsonDocument jsonDocument = QJsonDocument::fromJson(tmparray, &errors);

    file.close();

    if(jsonDocument.isNull())
    {
        QLOG_ERROR() << "read ordertest.txt data not json" << errors.errorString();
        timeout = 10000;
        error = QString::fromLocal8Bit("本地测试订单文件内容不合法");
        return false;
    }

    recvjson = jsonDocument.object();

    if(!OrderGetDataProcess::getOrderRequest(_storeinfo, json, _timestamp,_token))
    {
        error = QString::fromLocal8Bit("拉单失败,门店信息配置错误");
        QLOG_ERROR() << "getLogingRequest failed";
        return false;
    }

    QLOG_INFO() << "pullorder request json : " << json;

    if(!OrderGetDataProcess::getRealUrl(FMH_GETORDER, json, _url, realurl))
    {
        error = QString::fromLocal8Bit("拉单失败,请求地址配置错误");
        QLOG_ERROR() << "getRealUrl failed";
        return false;
    }

    QLOG_INFO() << "pullorder request url :" << realurl;

//    if(!_loginSocket->Request(json, recvjson, realurl, error))
//    {
//        error = QString::fromLocal8Bit("拉单失败,网络错误:").append(error);
//        QLOG_ERROR() << "pullorder failed";
//        return false;
//    }

    QLOG_INFO() << "pullorder return json : " << recvjson;

    if(!OrderGetDataProcess::checkStatusCode(recvjson, error))
    {
        error = QString::fromLocal8Bit("拉单失败:");
        QLOG_ERROR() << "checkStatusCode failed";
        return false;
    }

    QJsonArray array;

    if(!OrderGetDataProcess::getOrders(recvjson, array))
        QLOG_WARN() << "getOrders failed";

    optOrder(array);

    OrderGetDataProcess::getRSTTimeout(recvjson, timeout, _timeout);

    return true;

}

void OrderGetWork::setStoreinfo(const QVariantMap &storeinfo)
{
    _storeinfo.insert(JSON_STOREID, "ldd666");
    _storeinfo.insert(JSON_STATIONID, "001");
    _storeinfo.insert(JSON_KEY_USERID, "ldd123");
    _storeinfo.insert(JSON_KEY_PWD, "123456");
    _storeinfo.insert(JSON_KEY_PARTNERID, "8888");

    QLOG_INFO() << _storeinfo;
}

void OrderGetWork::setUrl(const QString &url)
{
    _url = QString("http:////118.89.167.51:9101//gateway?action=%1&access_token=%2&ver=%3&sign=%4");
}

void OrderGetWork::setTimeout(unsigned int timeout)
{
    _timeout = 1*60*1000;
}

bool OrderGetWork::loginToServer(QString &error)
{
    if(_islogin)
        return true;

    error.clear();

    QJsonObject json, recvjson;
    QString realurl;

    if(!OrderGetDataProcess::getLogingRequest(_storeinfo, json))
    {
        error = QString::fromLocal8Bit("登录失败,门店信息配置错误");
        QLOG_ERROR() << "getLogingRequest failed";
        return false;
    }

    QLOG_INFO() << "login request json : " << json;

    if(!OrderGetDataProcess::getRealUrl(FMH_LOGIN, json, _url, realurl))
    {
        error = QString::fromLocal8Bit("登录失败,请求地址配置错误");
        QLOG_ERROR() << "getRealUrl failed";
        return false;
    }

    QLOG_INFO() << "login request url :" << realurl;

    recvjson.insert(JSON_KEY_CODE, "ok");
    recvjson.insert(JSON_KEY_MESSAGE, QString::fromLocal8Bit("成功的不行"));

    QLOG_INFO() << "login return json : " << recvjson;

    if(!OrderGetDataProcess::checkStatusCode(recvjson, error))
    {
        error = QString::fromLocal8Bit("登录失败:");
        QLOG_ERROR() << "checkStatusCode failed";
        return false;
    }

    _islogin = true;

    return true;
}

void OrderGetWork::optOrderWithType(const QVariantMap &map)
{
    if(!map.contains(EVENT_KEY_STATUS) || !map.contains(EVENT_KEY_ORDERID))
        return ;

    QString status = map[EVENT_KEY_STATUS].toString();
    QString orderid = map[EVENT_KEY_ORDERID].toString();
    int type = -1;

    QString realurl;
    QString error;
    QJsonObject recvjson;

    if(status.isEmpty() || orderid.isEmpty())
        return ;

    QJsonObject json;

    OrderGetDataProcess::getOptRequest(map, json);

    QLOG_INFO() << "optOrderWithType order : " << json;

    OrderGetDataProcess::getRequestType(status, type);

    QLOG_INFO() << "optOrderWithType status and reqtype : " << status << type;

    if(!OrderGetDataProcess::getRealUrl(type, json, _url, realurl))
    {
        QVariantMap tmpmap;

        tmpmap.insert(EVENT_KEY_STATUS, false);
        tmpmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("获取请求链接失败"));

        POSTEVENTTYPE(PosEvent::s_opt_status,tmpmap,QVariantMap);
        return ;
    }

    QLOG_INFO() << "optOrderWithType request url :" << realurl;

//    if(!BillSocket::S_Request(json, recvjson, realurl, error))
//    {
//        QVariantMap tmpmap;

//        tmpmap.insert(EVENT_KEY_STATUS, false);
//        tmpmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("网络错误").append(error));

//        POSTEVENTTYPE(PosEvent::s_opt_status,tmpmap,QVariantMap);

//        return ;
//    }

    recvjson.insert(JSON_KEY_CODE, "ok");
    recvjson.insert(JSON_KEY_MESSAGE, QString::fromLocal8Bit("饿的不行了"));

    QJsonObject tmpjson;

    tmpjson.insert(JSON_KEY_ORDERID, orderid);
    tmpjson.insert(JSON_KEY_ORDERSTATUS, "4");


    recvjson.insert(JSON_KEY_RESULT, tmpjson);

    QLOG_INFO() << "optOrderWithType return json : " << recvjson;

    if(!OrderGetDataProcess::checkStatusCode(recvjson, error))
    {
        QVariantMap tmpmap;

        tmpmap.insert(EVENT_KEY_STATUS, false);
        tmpmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("失败").append(error));

        POSTEVENTTYPE(PosEvent::s_opt_status,tmpmap,QVariantMap);
        return ;
    }

    QVariantMap tmpmap;

    tmpmap.insert(EVENT_KEY_STATUS, true);
    tmpmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("成功"));

    POSTEVENTTYPE(PosEvent::s_opt_status,tmpmap,QVariantMap);

    QString tmpid, tmpstatus;

    if(!OrderGetDataProcess::getOrderStatus(recvjson, tmpid, tmpstatus))
        return ;

    QLOG_INFO() << "+++++++++++optOrderWithType" << tmpid << tmpstatus;

    PosOrderPool::TryChangeOrderStatus(tmpid, tmpstatus.toInt());

}

bool OrderGetWork::bingToServer(QString &error)
{
//    if(OrderGetDataProcess::isBind())
//        return true;

    error.clear();

    QJsonObject json, recvjson;
    QString realurl;

    if(!OrderGetDataProcess::getBindRequest(_storeinfo, json))
    {
        error = QString::fromLocal8Bit("绑定失败,获取门店信息失败");
        QLOG_ERROR() << "getLogingRequest failed";
        return false;
    }

    QLOG_INFO() << "login request json : " << json;

    if(!OrderGetDataProcess::getRealUrl(FMH_BIND, json, _url, realurl))
    {
        error = QString::fromLocal8Bit("绑定失败,获取请求地址失败");
        QLOG_ERROR() << "getRealUrl failed";
        return false;
    }

    QLOG_INFO() << "login request url :" << realurl;

    if(!BillSocket::S_Request(json, recvjson, realurl, error))
    {
        error = QString::fromLocal8Bit("绑定失败,网络错误:").append(error);
        QLOG_ERROR() << "login failed";
        return false;
    }

    QLOG_INFO() << "login return json : " << recvjson;

    if(!OrderGetDataProcess::checkStatusCode(recvjson, error))
    {
        error = QString::fromLocal8Bit("绑定失败").append(error);
        QLOG_ERROR() << "checkStatusCode failed";
        return false;
    }

    OrderGetDataProcess::setBind();

    QLOG_INFO() << "bind success";

    return true;
}

#else
void OrderGetWork::SetStoreInfoToConfig()
{
    QString configfile = qApp->applicationDirPath() + "/" + CONFIG_NAME;

    QSettings(configfile, QSettings::IniFormat).setValue(INI_BASE_PARNETID, _storeinfo[JSON_KEY_PARTNERID]);
    QSettings(configfile, QSettings::IniFormat).setValue(INI_BASE_STOREID, _storeinfo[JSON_STOREID]);
    QSettings(configfile, QSettings::IniFormat).setValue(INI_BASE_STATIONIID, _storeinfo[JSON_STATIONID]);
    QSettings(configfile, QSettings::IniFormat).setValue(INI_BASE_USERID, _storeinfo[JSON_KEY_USERID]);
    QSettings(configfile, QSettings::IniFormat).setValue(INI_BASE_PWD, _storeinfo[JSON_KEY_PWD]);
}

bool OrderGetWork::loginToServer(QString &error)
{
//    if(_islogin)
//        return true;

    error.clear();

    QJsonObject json, recvjson;
    QString realurl;

    if(!OrderGetDataProcess::getLogingRequest(_storeinfo, json))
    {
        error = QString::fromLocal8Bit("登录失败,获取门店信息失败");
        QLOG_ERROR() << "getLogingRequest failed";
        return false;
    }

    QLOG_INFO() << "login request json : " << json;

    if(!OrderGetDataProcess::getRealUrl(FMH_LOGIN, json, _url, realurl))
    {
        error = QString::fromLocal8Bit("登录失败,获取请求地址失败");
        QLOG_ERROR() << "getRealUrl failed";
        return false;
    }

    QLOG_INFO() << "login request url :" << realurl;

    if(!BillSocket::S_Request(json, recvjson, realurl, error))
    {
        error = QString::fromLocal8Bit("登录失败,网络错误:").append(error);
        QLOG_ERROR() << "login failed";
        return false;
    }

    QLOG_INFO() << "login return json : " << recvjson;

    if(!OrderGetDataProcess::checkStatusCode(recvjson, error))
    {
        error = QString::fromLocal8Bit("登录失败:").append(error);
        QLOG_ERROR() << "checkStatusCode failed";
        return false;
    }

    _islogin = true;

    OrderGetDataProcess::setToken(recvjson, _token);

    QString tcptoken;

    SetStoreInfoToConfig();

    if(OrderGetDataProcess::getToken(recvjson, tcptoken))
        POSTEVENTTYPE(PosEvent::s_token_change,tcptoken,QString);

    return true;
}

bool OrderGetWork::bingToServer(QString &error)
{
//    if(OrderGetDataProcess::isBind())
//        return true;

    error.clear();

    QJsonObject json, recvjson;
    QString realurl;

    if(!OrderGetDataProcess::getBindRequest(_storeinfo, json))
    {
        error = QString::fromLocal8Bit("绑定失败,获取门店信息失败");
        QLOG_ERROR() << "getLogingRequest failed";
        return false;
    }

    QLOG_INFO() << "login request json : " << json;

    if(!OrderGetDataProcess::getRealUrl(FMH_BIND, json, _url, realurl))
    {
        error = QString::fromLocal8Bit("绑定失败,获取请求地址失败");
        QLOG_ERROR() << "getRealUrl failed";
        return false;
    }

    QLOG_INFO() << "login request url :" << realurl;

    if(!BillSocket::S_Request(json, recvjson, realurl, error))
    {
        error = QString::fromLocal8Bit("绑定失败,网络错误:").append(error);
        QLOG_ERROR() << "login failed";
        return false;
    }

    QLOG_INFO() << "login return json : " << recvjson;

    if(!OrderGetDataProcess::checkStatusCode(recvjson, error))
    {
        error = QString::fromLocal8Bit("绑定失败").append(error);
        QLOG_ERROR() << "checkStatusCode failed";
        return false;
    }

    OrderGetDataProcess::setBind();

    QLOG_INFO() << "bind success";

    return true;
}

void OrderGetWork::setUrl(const QString &url)
{
    _url = url;
}

void OrderGetWork::setStoreinfo(const QVariantMap &storeinfo)
{
    _storeinfo = storeinfo;
}

bool OrderGetWork::PullOrder(unsigned int timeout, QString &error)
{
    error.clear();

    QJsonObject json, recvjson;
    QString realurl;

    if(!OrderGetDataProcess::getOrderRequest(_storeinfo, json, _timestamp, _token, _autoconfirm))
    {
        error = QString::fromLocal8Bit("拉单失败,获取门店信息失败");
        QLOG_ERROR() << "getLogingRequest failed";
        return false;
    }

    QLOG_INFO() << "pullorder request json : " << json;

    if(!OrderGetDataProcess::getRealUrl(FMH_GETRORDER, json, _url, realurl))
    {
        error = QString::fromLocal8Bit("拉单失败,获取请求地址失败");
        QLOG_ERROR() << "getRealUrl failed";
        return false;
    }

    QLOG_INFO() << "pullorder request url :" << realurl;

    if(!BillSocket::S_Request(json, recvjson, realurl, error))
    {
        error = QString::fromLocal8Bit("拉单失败,网络错误:").append(error);
        QLOG_ERROR() << "pullorder failed : " << error;
        return false;
    }

    QLOG_INFO() << "pullorder return json : " << recvjson;

    if(!OrderGetDataProcess::checkStatusCode(recvjson, error))
    {
        error = QString::fromLocal8Bit("拉单失败").append(error);
        QLOG_ERROR() << "checkStatusCode failed";
        return false;
    }

    QJsonArray array;

    if(!OrderGetDataProcess::getOrders(recvjson, array))
        QLOG_WARN() << "getOrders failed";

    optOrder(array);

    OrderGetDataProcess::getRSTTimeout(recvjson, timeout, _timeout);

    OrderGetDataProcess::getTimestamp(recvjson, _timestamp);

    return true;
}

void OrderGetWork::setTimeout(unsigned int timeout)
{
    _timeout = timeout;
}

void OrderGetWork::optOrderWithType(const QVariantMap &map)
{
    QVariantMap smap;
    smap.insert(EVENT_KEY_ORDERSTATUS, 0);
    smap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("通讯中..."));
    POSTEVENTTYPE(PosEvent::s_opt_status,smap,QVariantMap);

    if(!map.contains(EVENT_KEY_STATUS) || !map.contains(EVENT_KEY_ORDERID))
        return ;

    QString status = map[EVENT_KEY_STATUS].toString();
    QString orderid = map[EVENT_KEY_ORDERID].toString();
    int type = -1;

    QString realurl;
    QString error;
    QJsonObject recvjson;

    if(status.isEmpty() || orderid.isEmpty())
        return ;

    QJsonObject json;

    OrderGetDataProcess::getOptRequest(map, json);

    QLOG_INFO() << "optOrderWithType order : " << json;

    OrderGetDataProcess::getRequestType(status, type);

    QLOG_INFO() << "optOrderWithType status and reqtype : " << status << type;

    if(!OrderGetDataProcess::getRealUrl(type, json, _url, realurl))
    {
        QVariantMap tmpmap;

        tmpmap.insert(EVENT_KEY_STATUS, false);
        tmpmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("获取请求链接失败"));

        POSTEVENTTYPE(PosEvent::s_opt_status,tmpmap,QVariantMap);
        return ;
    }

    QLOG_INFO() << "optOrderWithType request url :" << realurl;

    if(!BillSocket::S_Request(json, recvjson, realurl, error))
    {
        QVariantMap tmpmap;

        tmpmap.insert(EVENT_KEY_STATUS, false);
        tmpmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("网络错误").append(error));

        POSTEVENTTYPE(PosEvent::s_opt_status,tmpmap,QVariantMap);

        return ;
    }

    QLOG_INFO() << "optOrderWithType return json : " << recvjson;

    if(!OrderGetDataProcess::checkStatusCode(recvjson, error))
    {
        QVariantMap tmpmap;

        tmpmap.insert(EVENT_KEY_STATUS, false);
        tmpmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("失败").append(error));

        POSTEVENTTYPE(PosEvent::s_opt_status,tmpmap,QVariantMap);
        return ;
    }

    QVariantMap tmpmap;

    tmpmap.insert(EVENT_KEY_STATUS, true);
    tmpmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("成功"));

    POSTEVENTTYPE(PosEvent::s_opt_status,tmpmap,QVariantMap);

    QString tmpid, tmpstatus, refundstatus;

    if(!OrderGetDataProcess::getOrderStatus(recvjson, tmpid, tmpstatus, refundstatus))
        return ;

    //PosOrderPool::TryChangeOrderStatus(tmpid, tmpstatus.toInt());

    QVariantMap maps;

    maps.insert(EVENT_KEY_ORDERID, tmpid);
    maps.insert(EVENT_KEY_MSG, tmpstatus.toInt());

    if(!refundstatus.isEmpty() && refundstatus.toInt() != 0)
        maps.insert(EVENT_KEY_STATUS, refundstatus.toInt());

    POSTEVENTTYPE(PosEvent::s_change_orderpool,maps,QVariantMap);
}

void OrderGetWork::setAutoconfirm(const QString &autoconfirm)
{
    _autoconfirm = autoconfirm;
}

void OrderGetWork::loginStart()
{
    QString error;

    do
    {
        if(!OrderGetDataProcess::isBind())
        {
            QVariantMap tmpmap;
            tmpmap.insert(EVENT_KEY_ORDERSTATUS, 0);
            tmpmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("绑定中..."));
            POSTEVENTTYPE(PosEvent::s_opt_status,tmpmap,QVariantMap);
            if(!bingToServer(error))
            {
                QLOG_ERROR() << QThread::currentThreadId() << "loginToServer failed";
                QVariantMap map;
                map.insert(EVENT_KEY_STATUS, false);
                map.insert(EVENT_KEY_MSG, error);
                POSTEVENTTYPE(PosEvent::s_opt_status,map,QVariantMap);
                break;
            }

            QVariantMap bmap;
            bmap.insert(EVENT_KEY_STATUS, true);
            bmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("绑定成功"));
            POSTEVENTTYPE(PosEvent::s_opt_status,bmap,QVariantMap);
        }

        if(!_islogin)
        {
            QVariantMap tmpmap;
            tmpmap.insert(EVENT_KEY_ORDERSTATUS, 0);
            tmpmap.insert(EVENT_KEY_MSG, QString::fromLocal8Bit("登录中..."));
            POSTEVENTTYPE(PosEvent::s_opt_status,tmpmap,QVariantMap);

            if(!loginToServer(error))
            {
                QLOG_ERROR() << QThread::currentThreadId() << "loginToServer failed";
                QVariantMap map;
                map.insert(EVENT_KEY_STATUS, false);
                map.insert(EVENT_KEY_MSG, error);
                POSTEVENTTYPE(PosEvent::s_login_status,map,QVariantMap);
                break;
            }

            QVariantMap map;
            map.insert(EVENT_KEY_STATUS, true);
            POSTEVENTTYPE(PosEvent::s_login_status,map,QVariantMap);
            emit quit();
        }
    }while(0);
}

#endif

void OrderGetWork::optOrder(const QJsonArray &orders)
{
    foreach(QJsonValue order, orders)
    {
        QJsonObject jsonObject = order.toObject();
        OrderObject orderObject;
        orderObject.FromJson(jsonObject);

        QLOG_INFO() << "----------------------------:" << orderObject.delivery_time;

        //PosOrderPool::TryInsertOrder(orderObject);
        POSTEVENTTYPE(PosEvent::s_inset_orderpool,orderObject,OrderObject);
    }
}

unsigned int OrderGetWork::timeout() const
{
    return _timeout;
}

void OrderGetWork::setStopflag(bool stopflag)
{
    _stopflag = stopflag;
    emit quit();
}

bool OrderGetWork::event(QEvent *e)
{

    if(e->type() == PosEvent::s_need_get_order)
    {
        QLOG_INFO() << QThread::currentThreadId() << "OrderGetWork PosEvent::s_need_get_order";
        emit quit();
        return true;
    }

    if(e->type() == PosEvent::s_opt_order)
    {
        QVariantMap value;
        GETEVENTINFO(value,e,QVariantMap);
        optOrderWithType(value);

        return true;
    }

    if(e->type() == PosEvent::s_login_storeinfo)
    {
        QVariantMap map;

        GETEVENTINFO(map, e, QVariantMap);

        _storeinfo = map;

        loginStart();

        return true;
    }

    return QObject::event(e);
}
