#include "flowControl.h"
#include "fmPlugin.h"
#include "fmPrinter.h"
#include "QsLog.h"
#include "DTools/dataManger.h"
#include "preDefine.h"
#include "DTools/configManger.h"
#include "Model/cashierObject.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QTimer>
#include <QDir>
#include <QApplication>
#include "DTools/orderstatus.h"

extern QString g_appDir;

FlowControl &FlowControl::GetInstance()
{
    static FlowControl fc;
    return fc;
}

FlowControl::FlowControl()
{
    m_loginSocket = NULL;
    m_pullOrderSocket = NULL;
    m_procOrderSocket = NULL;
    m_pullDishesSocket = NULL;
    netErrorIndex = 0;

    //QTimer::singleShot(10000,this, &FlowControl::_PostBill);
}

bool FlowControl::_GetStoreInfo()
{
    QString error;
    bool result;

    emit showAlert(AlertForm::LOADING, "正在获取门店信息......");
    QLOG_INFO() << QString("[---get storeInfo---]");
    result = FmPlugin::GetInstance().GetStoreInfo(m_storeId, m_posId, m_cashierId, m_bDate, error);
    QLOG_INFO() << QString("get storeInfo finsh. [result:%1][msg:%2][storeId:%3,posId:%4,cashierId:%5,bdate:%6]")
                   .arg(result).arg(error, m_storeId, m_posId, m_cashierId, m_bDate.toString("yyyy-MM-dd"));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "获取门店信息失败!");
    }

    return result;
}

bool FlowControl::_Login()
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetLoginData(ConfigManger::GetInstance().GetPrefix()+m_storeId, SERVER_PASSWORD, m_posId, m_cashierId);


    emit showAlert(AlertForm::LOADING, "正在登录......");
    QLOG_INFO() << QString("[---login---][requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_loginSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("login finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "登录失败![网络错误]");
        if(neterror)//如果之前网络是正常的，则开始语音提示网络错误
        {
            emit startNetErrorRemind();
        }
        neterror=false;
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            result = false;
            emit showAlert(AlertForm::ERROR, QString("登录失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            m_timestamp = recvJson[JSON_TIMESTAMPS].toString();
            DataManger::GetInstance().SetToken(recvJson[JSON_TOKEN].toString());
            emit hideAlert();
            emit setStoreInfo(m_storeId);
            m_storeName = recvJson[JSON_STORENAME].toString();
            FmPrinter::GetInstance().setStoreName(m_storeName);

            //
            // 初始化本地数据库
            QString dbPath = QString("%1/%2.db").arg(g_appDir, m_storeId);
            QFile file( dbPath );
            bool bInit = !file.exists();
            m_db = QSqlDatabase::addDatabase("QSQLITE","bills");
            m_db.setDatabaseName(dbPath);
            m_db.open();
            if( bInit )
            {
                QSqlQuery query(m_db);
                query.exec( "CREATE TABLE orders( orderId VARCHAR, createTime DATETIME, \
                             jsonStr VARCHAR, bPrinted BOOLEAN, bRecord BOOLEAN );");
                query.clear();
                query.exec( QString("INSERT INTO orders VALUES ('freemud', '1970-01-01', '0', 0, 0);") );
                query.clear();
            }
            // 获取本地数据库订单信息
            QSqlQuery query(m_db);
            query.exec( QString("SELECT * from orders where createTime = '%1';")
                        .arg(QDate::currentDate().toString("yyyy-MM-dd")) );
            if( query.next() )
            {
                do
                {
                    QLOG_INFO() << QString(">>>>>>>>>>>>>>>>>>>>>>>>>");
                    QLOG_INFO() << QString("获取到本地订单[%1]: %2").arg(query.value("orderId").toString())
                                   .arg(query.value("jsonStr").toString());
                    QJsonObject order = QJsonDocument::fromJson(query.value("jsonStr").toByteArray()).object();
                    OrderObject *orderObj;
                    orderObj = new OrderObject(this);
                    orderObj->FromJson(order);
                    m_ordersMap.insert(orderObj->order_id, orderObj);
                    emit changeOrderStatus(orderObj);
                }while( query.next() );
            }

            query.clear();
            query.exec( QString("SELECT jsonStr from orders where orderId = 'freemud';") );
            if( query.next() )
            {
                m_timestamp = query.value(0).toString();
            }
            //


            _PullOrder();
        }
    }

    if(!result)
    {
        QLOG_INFO() << QString("%1 msec after login...").arg(VALUE_RELOGINTIME);
        QTimer::singleShot(VALUE_RELOGINTIME, this, &FlowControl::_Login);
    }

    return result;
}

bool FlowControl::_PullOrder()
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;
    int syncTime = VALUE_PULLSYNCTIME;

    sendJson = DataManger::GetInstance().GetPullOrderData(m_timestamp);

    QLOG_INFO() << QString("[---pull order---][requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_pullOrderSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("pull order finsh. [result:%1][msg:%2][data: %3]")
                   .arg(result).arg(error).arg(_GetJsonStr(recvJson));
    if(!result)
    {
        netErrorIndex++;
        emit setNetStatus("<font color='#ff0000'>异常</font>");
        if(netErrorIndex > 50)
        {
            if(neterror)//如果之前网络正常，则开始语音提示网络错误
            {
                emit startNetErrorRemind();
            }
            neterror=false;
        }
    }else
    {
        netErrorIndex = 0;
        emit setNetStatus("正常");
        if(!neterror)//如果之前网络异常，现在正常，则停止语音提示
        {
            emit stopNetErrorRemind();
        }
        neterror=true;
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            QString error = recvJson[JSON_MESSAGE].toString();
            QLOG_ERROR() << QString("pull orders error.[msg->%1]").arg(error);
            emit showAlert(AlertForm::ERROR, QString("获取订单失败![%1]").arg(error));
        }else
        {
            // 获取门店营业状态
            QString strOpeStatus("正常");
            QJsonArray opeStatus = recvJson[JSON_SHOPSTATUS].toArray();
            qDebug() << "11111" << opeStatus;
            foreach(QJsonValue status, opeStatus)
            {
                QJsonObject jsonObject =  status.toObject();
                if(jsonObject[JSON_SHOPSTATUSDESC].toString().compare("营业中"))
                {
                    strOpeStatus = QString("<font color='#ff0000'>异常</font>");
                    break;
                }
            }
            emit setOpeStatus(strOpeStatus);

            // 开启事务提高数据插入效率
            m_db.transaction();
            QSqlQuery query(m_db);

            // 获取订单信息
            QJsonArray orders = recvJson[JSON_ORDERS].toArray();
            foreach(QJsonValue order, orders)
            {
                QJsonObject jsonObject = order.toObject();
                OrderObject *orderObject = NULL;
                QString orderId=jsonObject[JSON_ORDERID].toString();
                orderObject = m_ordersMap.value(jsonObject[JSON_ORDERID].toString());
                if(orderObject == NULL)
                {
                    //新数据
                    orderObject = new OrderObject(this);
                    orderObject->FromJson(jsonObject);
                    if(QDateTime::fromTime_t(orderObject->create_time).date() == QDate::currentDate()
                            || ((orderObject->order_type == 2)   && (orderObject->status != 6)) )
                    {
                        m_ordersMap.insert(orderObject->order_id, orderObject);
                        if(!orderObject->order_view_id.isEmpty())
                        {
                            m_view2Id.insert(orderObject->order_view_id, orderObject->order_id);
                        }

                        QLOG_INFO() << QString("new order[%1:%2].[data:%3]")
                                       .arg(orderObject->order_id, orderObject->status_desc)
                                       .arg(_GetJsonStr(jsonObject));

                        emit changeOrderStatus(orderObject);

                        if(!Orderstatus::getInstance().isorderexit(orderId))
                        {
                            Orderstatus::getInstance().statusinsert(orderId,0);
                        }
                        if(orderObject->status==2&&!Orderstatus::getInstance().isprint(orderId))
                        {
                            // 打印
                            QLOG_INFO() << QString("[---begin print---]");

                            if(FmPrinter::GetInstance().DoPrint(ConfigManger::GetInstance().GetPrinterName(), orderObject))
                            {
                                QLOG_INFO() << QString("print sucessful");
                                Orderstatus::getInstance().printupdate(orderId,1);
                            }else
                            {
                                emit showAlert(AlertForm::ERROR, QString("打印冲突，请稍后手动打印或重启收银程序"));
                                QLOG_INFO() << QString("print failed");
                            }
                        }
                    }else
                    {
                        QLOG_INFO() << QString("过期订单[%1]").arg(orderObject->order_id);
                    }
                }else
                {
                    // 如果是自提单则自动变为送出状态（方便自提单只做完成动作）
                    if(orderObject->order_type == 3 && orderObject->status ==2 )
                    {
                        orderObject->status =4;
                    }

                    //旧数据有更新
                    int oldStatus = orderObject->status;
                    orderObject->FromJson(jsonObject);

                    QLOG_INFO() << QString("\r\n\r\n old order[%1:%2].[data:%3]")
                                   .arg(orderObject->order_id, orderObject->status_desc)
                                   .arg(_GetJsonStr(jsonObject));

                    if(oldStatus != orderObject->status)
                    {
                        emit changeOrderStatus(orderObject, oldStatus);
                    }

                    if(orderObject->delivery_status==2 && orderObject->status==2)
                    {
                        emit changeOrderStatus(orderObject, oldStatus);
                    }
                }
                // 将订单数据存入本地
                if(orderObject != NULL)
                {
                    query.exec( QString("SELECT orderId from orders where orderId = '%1';").arg(orderObject->order_id) );
                    if( query.next() )
                    {
                        query.clear();

                        query.exec( QString("UPDATE orders SET jsonStr = '%1' WHERE orderId = '%2';")
                                    .arg(orderObject->toString(), orderObject->order_id) );
                        QLOG_INFO() << "更新订单";
                    }else
                    {
                        query.clear();

                        query.exec( QString("INSERT INTO orders VALUES ('%1', '%2', '%3', 0, 0);")
                                    .arg(orderObject->order_id,
                                         QDateTime::fromTime_t(orderObject->create_time).toString("yyyy-MM-dd"),
                                         QString(orderObject->toString())) );
                        QLOG_INFO() << "插入订单";
                    }
                }



                if(orderObject->status == 22 && orderObject->refundProList.isEmpty())
                {
                    QString error;
                    bool result;
                    QJsonObject sendJson;
                    QJsonObject recvJson;

                    sendJson = DataManger::GetInstance().GetRefundDetailData(orderObject->order_id);

                    QLOG_INFO() << QString("[---get refundDetail---][requestData:%1]").arg(_GetJsonStr(sendJson));
                    result = m_pullOrderSocket->Request(sendJson, recvJson, error);
                    QLOG_INFO() << QString("get refundDetail finsh. [result:%1][msg:%2]")
                                   .arg(result).arg(error);
                    if( recvJson["statusCode"].toInt() == 100 )
                    {
                        QJsonArray items = recvJson["refund_info"].toObject()["refund_items"].toArray();
                        foreach(QJsonValue item, items)
                        {
                           QJsonObject itemObj = item.toObject();
                           ProductObject *product = new ProductObject;
                           product->pid = itemObj["pid"].toString();
                           product->name = itemObj["name"].toString();
                           product->productAmount = itemObj["product_amount"].toInt();
                           orderObject->refundProList.append(product);
                        }
                        orderObject->refund_total_fee = recvJson["refund_total"].toInt();
                    }
                }

              }
            m_timestamp = recvJson[JSON_TIMESTAMPS].toString();
            query.clear();
            query.exec( QString("UPDATE orders SET jsonStr = '%1' WHERE orderId = 'freemud';")
                        .arg(m_timestamp) );
            m_db.commit();
            syncTime = recvJson[JSON_SYNCTIME].toInt()*1000;
        }
    }

    QLOG_INFO() << QString("%1 msec after pull order...").arg(syncTime);
    QTimer::singleShot(syncTime, this, &FlowControl::_PullOrder);

    return result;
}

void FlowControl::_PostBill()
{
    if(m_billList.isEmpty())
    {
        QTimer::singleShot(10000, this, &FlowControl::_PostBill);
        return;
    }
    OrderObject* orderObject = m_billList.first();
    if(orderObject->status == 6 || orderObject->status == 200)
    {
       QString error, bill_data, fee_data;
       for(int i=0; i<5; i++)
       {
           QLOG_INFO() << QString("第%1次尝试写入订单%2").arg(i+1).arg(orderObject->order_id);
           bool bServerFailed = false;
           if(FmPlugin::GetInstance().DoOrderEntry(orderObject,"","",bill_data, fee_data,error, bServerFailed))
           {
               QLOG_INFO() << QString("销售单数据%1   配送费数据%2").arg(bill_data,fee_data);
               QLOG_INFO() << QString("_PullOrder DoOrderEntry successful %1 %2").arg(orderObject->order_id).arg(error);
               this->_ReportBillEntryResult(orderObject->order_id, 1, QString("成功"));
               m_mutex.lock();
               m_billList.removeOne(orderObject);
               QLOG_INFO() << QString("订单%1移出队列").arg(orderObject->order_id);
               m_mutex.unlock();

               break;
           }else
           {
               QLOG_INFO() << QString("销售单数据%1   配送费数据%2").arg(bill_data,fee_data);
               QLOG_INFO() << QString("_PullOrder DoOrderEntry failed %1 %2").arg(orderObject->order_id, error);
               this->_ReportBillEntryResult(orderObject->order_id, 0, error);

               if(bServerFailed)
               {
                   m_mutex.lock();
                   m_billList.removeOne(orderObject);
                   QLOG_INFO() << QString("订单%1移出队列").arg(orderObject->order_id);
                   m_mutex.unlock();
                   break;
               }
           }
           QEventLoop loop;
           QTimer::singleShot(1000*60, &loop, &QEventLoop::quit);
           loop.exec();
       }
    }else
    {
       QLOG_INFO() << QString("cancle entry %1").arg(orderObject->order_id);
       m_mutex.lock();
       m_billList.removeOne(orderObject);
       QLOG_INFO() << QString("订单%1移出队列").arg(orderObject->order_id);
       m_mutex.unlock();
    }

    //QTimer::singleShot(10000, this, &FlowControl::_PostBill);
}

bool FlowControl::_GetDelivers(const QString &orderId)
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;
    OrderObject *orderObj;

    orderObj = m_ordersMap.value(orderId);
    sendJson = DataManger::GetInstance().GetPullDeliverData(m_storeId, orderObj->channel,orderId);

    emit showAlert(AlertForm::LOADING, "正在获取配送员信息......");
    QLOG_INFO() << QString("[---get delivers---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_procOrderSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("get delivers finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "获取配送员失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            result = false;
            emit showAlert(AlertForm::ERROR, QString("获取配送员失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            QList<DeliverObject> deliverList;
            QJsonArray delivers = recvJson[JSON_DELIVERS].toArray();
            foreach(QJsonValue deliver, delivers)
            {
                QJsonObject jsonObject = deliver.toObject();
                DeliverObject deliverObject;
                deliverObject.FetchDataFromJson(jsonObject);
                deliverList.append(deliverObject);
            }
            emit hideAlert();
            //如果配送员为空则直接调用配送接口
            if(deliverList.isEmpty())
            {
                _SendOrder(orderId,DeliverObject());
            }
            else{
                emit showDeliverPickForm(orderId, deliverList);
            }
        }
    }

    return result;
}

bool FlowControl::_ConfirmOrder(const QString &orderId, const DeliverObject &deliverObj)
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetConfirmOrderData(orderId, deliverObj.id, deliverObj.name, deliverObj.phone);

    emit showAlert(AlertForm::LOADING, "正在通信......");
    QLOG_INFO() << QString("[---confirm order---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_procOrderSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("confirm order finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "接单失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            result = false;
            emit showAlert(AlertForm::ERROR, QString("接单失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            OrderObject *orderObject = m_ordersMap.value(orderId);


            QString remark(orderObject->remark), deliveryTime;
            remark = remark.isEmpty()? "" : QString("[备注: %1]").arg(remark);
            deliveryTime = QString("[期望送达时间: %1]").arg(orderObject->delivery_time==0? "立即送出" : QDateTime::fromTime_t(orderObject->delivery_time).toString("yyyy-MM-dd hh:mm:ss"));
            emit showAlert(AlertForm::SUCCESS, QString("接单成功!%1<br/>%2").arg(remark).arg(deliveryTime));

            // 通知主界面移动订单
            int oldStatus = orderObject->status;
            orderObject->status = recvJson[JSON_STATUS].toInt();
            orderObject->status_desc = recvJson[JSON_STATUSDESC].toString();
            emit changeOrderStatus(orderObject, oldStatus);

            // 打印
            QLOG_INFO() << QString("[---begin print---]");

            if(FmPrinter::GetInstance().DoPrint(ConfigManger::GetInstance().GetPrinterName(), orderObject))
            {
                QLOG_INFO() << QString("print sucessful");
                Orderstatus::getInstance().printupdate(orderId,1);
            }else
            {
                emit showAlert(AlertForm::ERROR, QString("打印冲突，请稍后手动打印或重启收银程序"));
                QLOG_INFO() << QString("print failed");
            }
        }
    }

    return result;
}

bool FlowControl::_RefuseOrder(const QString &orderId, int refuseCode)
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetRefuseOrderData(refuseCode, orderId);

    emit showAlert(AlertForm::LOADING, "正在通信......");
    QLOG_INFO() << QString("[---refuse order---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_procOrderSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("refuse order finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "拒单失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            result = false;
            emit showAlert(AlertForm::ERROR, QString("拒单失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            emit showAlert(AlertForm::SUCCESS, "拒单成功!");

            // 通知主界面移动订单
            OrderObject *orderObject = m_ordersMap.value(orderId);
            int oldStatus = orderObject->status;
            orderObject->status = recvJson[JSON_STATUS].toInt();
            orderObject->status_desc = recvJson[JSON_STATUSDESC].toString();
            emit changeOrderStatus(orderObject, oldStatus);
        }
    }

    return result;
}

bool FlowControl::_SendOrder(const QString& orderId, const DeliverObject &deliverObj)
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetSendOrderData(orderId,deliverObj.id, deliverObj.name,deliverObj.phone);

    emit showAlert(AlertForm::LOADING, "正在通信......");
    QLOG_INFO() << QString("[---sendout order---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_procOrderSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("sendout order finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "送出失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            result = false;
            emit showAlert(AlertForm::ERROR, QString("送出失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            emit showAlert(AlertForm::SUCCESS, "送出成功!");

            // 通知主界面移动订单
            OrderObject *orderObject = m_ordersMap.value(orderId);
            orderObject->bAppointSender = true;
            int oldStatus = orderObject->status;
            orderObject->status = recvJson[JSON_STATUS].toInt();
            orderObject->status_desc = recvJson[JSON_STATUSDESC].toString();
            emit changeOrderStatus(orderObject, oldStatus);
        }
    }

    return result;
}

bool FlowControl::_CompleteOrder(const QString& orderId)
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetCompleteOrderData(orderId);

    emit showAlert(AlertForm::LOADING, "正在通信......");
    QLOG_INFO() << QString("[---complete order---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_procOrderSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("complete order finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "完成失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            result = false;
            emit showAlert(AlertForm::ERROR, QString("完成失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            emit showAlert(AlertForm::SUCCESS, "完成成功!");
            // 通知主界面移动订单
            OrderObject *orderObject = m_ordersMap.value(orderId);
            int oldStatus = orderObject->status;
            orderObject->status = recvJson[JSON_STATUS].toInt();
            orderObject->status_desc = recvJson[JSON_STATUSDESC].toString();
            emit changeOrderStatus(orderObject, oldStatus);
        }
    }

    return result;
}

bool FlowControl::_ReportBillEntryResult(const QString &orderId, int status, const QString &error)
{
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetReportOERData(orderId, status, error);

    QLOG_INFO() << QString("[---report bill result---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    QString error1;
    result = m_procOrderSocket->Request(sendJson, recvJson, error1);
    QLOG_INFO() << QString("report bill result finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error1, _GetJsonStr(recvJson));

    return result;
}

bool FlowControl::_RefuseRefund(const QString& orderId)
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetRefuseRefundData("菜品已送出",orderId);

    emit showAlert(AlertForm::LOADING, "正在通信......");
    QLOG_INFO() << QString("[---refuseRefund order---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_procOrderSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("refuseRefund order finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "拒绝退单失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            result = false;
            emit showAlert(AlertForm::ERROR, QString("拒绝退单失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            emit showAlert(AlertForm::SUCCESS, "拒绝退单成功!");

            // 通知主界面移动订单
            OrderObject *orderObject = m_ordersMap.value(orderId);
            int oldStatus = orderObject->status;
            orderObject->status = recvJson[JSON_STATUS].toInt();
            orderObject->status_desc = recvJson[JSON_STATUSDESC].toString();
            emit changeOrderStatus(orderObject, oldStatus);
        }
    }

    return result;
}

bool FlowControl::_AgreeRefund(const QString &orderId)
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetAgreeRefundOrderData(orderId);

    emit showAlert(AlertForm::LOADING, "正在通信......");
    QLOG_INFO() << QString("[---agreeRefund order---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_procOrderSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("agreeRefund order finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "同意退款失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            result = false;
            emit showAlert(AlertForm::ERROR, QString("同意退款失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            emit showAlert(AlertForm::SUCCESS, "同意退款成功!");

            // 通知主界面移动订单
            OrderObject *orderObject = m_ordersMap.value(orderId);
            int oldStatus = orderObject->status;
            orderObject->status = recvJson[JSON_STATUS].toInt();
            orderObject->status_desc = recvJson[JSON_STATUSDESC].toString();
            emit changeOrderStatus(orderObject, oldStatus);
        }
    }

    return result;
}

bool FlowControl::_GetCashiers(QList<CashierObject> &cashiersList)
{
    QString strCashiers, error;
    bool result;

    emit showAlert(AlertForm::LOADING, "正在查询收银员信息.....");
    QLOG_INFO() << QString("[---get cashiers---].");
    result = FmPlugin::GetInstance().GetOnDutyCashiers(cashiersList, error);
    foreach (CashierObject cashier, cashiersList)
    {
        strCashiers.append(QString("|%1,%2,%3,%4|").arg(cashier.id, cashier.name, cashier.shiftId, cashier.shiftName));
    }
    QLOG_INFO() << QString("get cashiers finsh. [result:%1][msg:%2][data:%3]").arg(result).arg(error, strCashiers);
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "查询收银员信息失败!");
    }
    return result;
}

bool FlowControl::_SynStock()
{
    QList<StockObject> stockList;
    QString strStock, error;
    int synInterval = VALUE_SYNSTOCKINTERVAL;
    bool result;

    QLOG_INFO() << QString("[---get stockInfo---].");
    result = FmPlugin::GetInstance().GetStockInfo(stockList, error);
    foreach (StockObject stock, stockList)
    {
        strStock.append(QString("|%1,%2,%3|").arg(stock.id, stock.upc).arg(QString::number(stock.num)));
    }
    QLOG_INFO() << QString("get stockInfo finsh. [result:%1][msg:%2][data:%3]").arg(result).arg(error, strStock);
    if(result)
    {
        // 获取库存信息成功则推送到服务器
        QJsonObject sendJson;
        QJsonObject recvJson;
        sendJson = DataManger::GetInstance().GetSynStockData(stockList);
        QLOG_INFO() << QString("[---push stockInfo---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
        result = m_syncStockSocket->Request(sendJson, recvJson, error);
        QLOG_INFO() << QString("push stockInfo finsh. [result:%1][msg:%2][recvData:%3]")
                       .arg(result).arg(error, _GetJsonStr(recvJson));
        if(result)
        {
            if(JSON_STATUSCODE_OK == recvJson[JSON_STATUSCODE].toInt())
            {
                synInterval = recvJson[JSON_SYNCTIME].toInt()*1000;
            }
        }
    }

    QLOG_INFO() << QString("%1 msec after synStock...").arg(synInterval);
    QTimer::singleShot(synInterval, this, &FlowControl::_SynStock);

    return result;
}

bool FlowControl::_CheckCashiers()
{
    bool result = false;

    QList<CashierObject> cashiersList;
    if(_GetCashiers(cashiersList))
    {
        foreach (CashierObject cashier, cashiersList)
        {
            if(!cashier.id.compare(m_cashierObject.id))
            {
                m_cashierObject = cashier;
                result = true;
                break;
            }
        }
        if(result == false)
        {
            emit showAlert(AlertForm::ERROR, "当前收银员已下班请重新选择!");
        }
    }

    return result;
}



QString FlowControl::_GetJsonStr(const QJsonObject &json)
{
    return QString(QJsonDocument(json).toJson(QJsonDocument::Compact)).replace("\"","");
}

bool FlowControl::_RefundOrder(const QString &orderId, const QString &reason)
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetRefundOrderData(reason,orderId);

    emit showAlert(AlertForm::LOADING, "正在通信......");
    QLOG_INFO() << QString("[---refund order---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_procOrderSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("refund order finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "完成失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            result = false;
            emit showAlert(AlertForm::ERROR, QString("退款失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            emit showAlert(AlertForm::SUCCESS, "退款成功!");

            // 通知主界面移动订单
            OrderObject *orderObject = m_ordersMap.value(orderId);
            int oldStatus = orderObject->status;
            orderObject->status = recvJson[JSON_STATUS].toInt();
            orderObject->status_desc = recvJson[JSON_STATUSDESC].toString();
            emit changeOrderStatus(orderObject, oldStatus);
        }
    }

    return result;
}


void FlowControl::onFlowStart()
{
    m_timestamp = "0";
    m_loginSocket = new BillSocket(this);
    m_pullOrderSocket = new BillSocket(this);
    m_procOrderSocket = new BillSocket(this);
    m_syncStockSocket = new BillSocket(this);
    m_pullDishesSocket = new BillSocket(this);

    if(_GetStoreInfo())
    {
        _Login();
    }
    return;
}

void FlowControl::onConnectDb(const QString &host, const QString &username, const QString &password, const QString &dbname)
{
    QString error; bool result;
    QLOG_INFO() << QString("[---connect database---]. [host:%1][username:%2][password:%3][dbname:%4]")
                   .arg(host, username, password, dbname);
    result = FmPlugin::GetInstance().ConnectDb(host, username, password, dbname, error);
    QLOG_INFO() << QString("connect finsh. [result:%1][msg:%2]").arg(result).arg(error);
    emit connectDbFinsh(result, error);
    return;
}

void FlowControl::onProcessOrder(const QString &operation, const QString &orderId, const DeliverObject &deliverObj)
{
    qDebug() << operation << orderId;

    if(!operation.compare(OPERATION_GETDELIVERS))
    {
        _GetDelivers(orderId);
    }else if(!operation.compare(OPERATION_CONFRIM))
    {
        _ConfirmOrder(orderId, deliverObj);
    }else if(!operation.compare(OPERATION_REFUSE))
    {
        _RefuseOrder(orderId, 2);
    }else if(!operation.compare(OPERATION_SENDOUT))
    {
        _SendOrder(orderId,deliverObj);
    }else if(!operation.compare(OPERATION_COMPLETE))
    {
        _CompleteOrder(orderId);
    }else if(!operation.compare(OPERATION_REFUSEREFUND))
    {
        _RefuseRefund(orderId);
    }
    else if(!operation.compare(OPERATION_AGREEREFUND))
    {
        _AgreeRefund(orderId);
    }
}

void FlowControl::onGetOnDutyCashiers()
{
    QList<CashierObject> cashiersList;
    if(_GetCashiers(cashiersList))
    {
        emit hideAlert();
        emit showCashierPickForm(cashiersList);
    }
}

void FlowControl::onUpdateCashier(const CashierObject &cashier)
{
    m_cashierObject = cashier;
}

void FlowControl::onGetOrderDetails(const QString &orderId)
{
    //    if(_CheckCashiers())
    //    {
    emit hideAlert();
    QString lOrderId;
    if(m_view2Id.contains(orderId))
    {
        lOrderId = m_view2Id.value(orderId);
    }else
    {
        lOrderId = orderId;
    }
    emit showOrderDetails(m_ordersMap.value(lOrderId));
    //    }
}

void FlowControl::onReEntryOrder(const QString &orderId)
{
//    emit showAlert(AlertForm::LOADING, "正在补录到天天饮食......");

//    QLOG_INFO() << QString("[---order reEntry begin---]");
//    // 写入销售单
//    OrderObject *orderObject = m_ordersMap.value(orderId);
//    QString error;
//    if(!FmPlugin::GetInstance().DoOrderEntry(orderObject, m_cashierObject.id, m_cashierObject.name,
//                                             m_cashierObject.shiftId, m_cashierObject.shiftName, error))
//    {
//        QLOG_ERROR() << QString("order reEntry failed,[%1]").arg(error);
//        emit showAlert(AlertForm::ERROR, "<font color=\"#FF0000\">补录天天饮食失败,请联系管理员或者进群咨询(205821431)</font>");
//    }else
//    {
//        QFile file(QString("%1/orders/%2").arg(QApplication::applicationDirPath(), orderObject->order_id));
//        file.remove();
//        QLOG_INFO() << QString("order reEentry success.");
//        emit showAlert(AlertForm::SUCCESS, "补录天天饮食成功");
//    }
}

void FlowControl::onSerachOrder(const QString &text)
{
    QStringList orderIdList;
    if(!text.isEmpty())
    {
        QMap<QString, OrderObject*>::iterator order;
        for(order = m_ordersMap.begin(); order!=m_ordersMap.end(); order++)
        {
            QString orderId = order.key();
            while (!orderId.at(0).isDigit())
            {
                orderId = orderId.mid(1);
            }
            if(orderId.startsWith(text))
            {
                orderIdList.append(order.key());
            }
        }
    }
    emit showSearchOrderResult(orderIdList);
}

void FlowControl::onRefund(const QString &orderId, const QString &reason)
{
    _RefundOrder(orderId,reason);
}

void FlowControl::onPullDishes()
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    m_dishesMap.clear();

    sendJson = DataManger::GetInstance().GetStoreChannelInfoData();
    emit showAlert(AlertForm::LOADING, "正在获取平台列表......");
    QLOG_INFO() << QString("[---GetStoreChannelInfo---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_pullDishesSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("GetStoreChannelInfo finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "获取平台列表失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            emit showAlert(AlertForm::ERROR, QString("获取平台列表失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            // 分别获取每个平台的菜品信息
            QJsonArray jaChannels = recvJson[JSON_SHOPSTATUS].toArray();
            foreach(QJsonValue v, jaChannels)
            {
                QJsonObject channel =  v.toObject();
                QString channelName = channel["name"].toString();
                QString channelCode = channel["code"].toString();

                sendJson = DataManger::GetInstance().GetPullDishesData(channelCode);
                emit showAlert(AlertForm::LOADING, QString("正在获取[%1]菜品信息......").arg(channelName));
                QLOG_INFO() << QString("[---pullDishes %1---]. [requestData:%2]").arg(channelName, _GetJsonStr(sendJson));
                result = m_pullDishesSocket->Request(sendJson, recvJson, error);
                QLOG_INFO() << QString("pullDishes finsh. [result:%1][msg:%2][recvData:%3]")
                               .arg(result).arg(error, _GetJsonStr(recvJson));
                if(!result)
                {
                    emit showAlert(AlertForm::ERROR, QString("获取[%1]菜品信息失败![网络超时]").arg(channelName));
                    break;
                }else
                {
                    if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
                    {
                        //result = false;
                        //emit showAlert(AlertForm::ERROR, QString("获取[%1]菜品信息失败![%2]").arg(channelName, recvJson[JSON_MESSAGE].toString()));
                        //break;
                    }else
                    {
                        QJsonArray categoriesJA =recvJson["categories"].toArray();
                        foreach(QJsonValue jv, categoriesJA)
                        {
                            QJsonObject jo = jv.toObject();
                            QString categoryName = jo["name"].toString();
                            QJsonArray dishesJA = jo["dishes"].toArray();
                            foreach(QJsonValue jv1, dishesJA)
                            {
                                QJsonObject jo1 = jv1.toObject();
                                dishesObject dishesObj;
                                dishesObj.FetchDataFromJson(jo1);

                                QMap<QString, dishesObject> tmpMap;
                                if( m_dishesMap.contains(categoryName) )
                                {
                                    if( m_dishesMap.value(categoryName).contains(dishesObj.name) )
                                    {
                                        dishesObject tmpObj = m_dishesMap.value(categoryName).value(dishesObj.name);
                                        tmpObj.channelCode_status.insert(channelName+":"+channelCode+":"+dishesObj.code, dishesObj.status);

                                        tmpMap = m_dishesMap.value(categoryName);
                                        tmpMap.insert(dishesObj.name, tmpObj);
                                    }else
                                    {
                                        dishesObj.channelCode_status.insert(channelName+":"+channelCode+":"+dishesObj.code, dishesObj.status);
                                        tmpMap = m_dishesMap.value(categoryName);
                                        tmpMap.insert(dishesObj.name, dishesObj);
                                    }
                                }else
                                {
                                    dishesObj.channelCode_status.insert(channelName+":"+channelCode+":"+dishesObj.code, dishesObj.status);
                                    tmpMap.insert(dishesObj.name, dishesObj);
                                }
                                m_dishesMap.insert(categoryName, tmpMap);
                            }
                        }
                    }
                }
            }


            if(!m_dishesMap.isEmpty())
            {
                emit hideAlert();
                // 通知界面显示
                emit iniDishesData(m_dishesMap);
            }else
            {
                emit showAlert(AlertForm::ERROR, QString("未获取到菜品信息!"));
            }
        }
    }
}

void FlowControl::onUpdDishes(QStringList channelCode, QString disheId, int status)
{
    QString error;
    bool result = true;
    QJsonObject sendJson;
    QJsonObject recvJson;

    emit showAlert(AlertForm::LOADING, "正在同步菜品销售状态......");
    foreach (QString channel, channelCode) {
        sendJson = DataManger::GetInstance().GetUpdDishesData(channel.split(":").at(1), channel.split(":").at(2), status);

        QLOG_INFO() << QString("[---update dishes---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
        result = m_pullDishesSocket->Request(sendJson, recvJson, error);
        QLOG_INFO() << QString("update dishes finsh. [result:%1][msg:%2][recvData:%3]")
                       .arg(result).arg(error, _GetJsonStr(recvJson));
        if(!result)
        {
            result = false;
            emit showAlert(AlertForm::ERROR, "同步菜品销售状态失败![网络错误]");
            break;
        }else
        {
            if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
            {
                result = false;
                emit showAlert(AlertForm::ERROR, QString("同步菜品销售状态失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
                break;
            }
        }
    }
    if(result )
    {
        emit hideAlert();
        emit processDishiesSuccssful(channelCode, disheId, status);
    }
}

void FlowControl::onUpdDishesForRef(QString channelCode, QMap<QString, int> dishes)
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetUpdDishesForRefData(channelCode, dishes);

    QLOG_INFO() << QString("[---UpdDishesForRef---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_pullDishesSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("UpdDishesForRef finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
}

void FlowControl::onGetBusinessStatus()
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetStoreChannelInfoData();
    emit showAlert(AlertForm::LOADING, "正在获取平台营业状态......");
    QLOG_INFO() << QString("[---GetStoreChannelInfo---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_pullDishesSocket->Request(sendJson, recvJson, error);
    qDebug() << recvJson;
    QLOG_INFO() << QString("GetStoreChannelInfo finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "获取平台营业状态失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            emit showAlert(AlertForm::ERROR, QString("获取平台营业状态失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            // 分别获取每个平台的菜品信息
            QJsonArray jaChannels = recvJson[JSON_SHOPSTATUS].toArray();
            QStringList strListChannels;
            foreach(QJsonValue v, jaChannels)
            {
                QJsonObject channel =  v.toObject();
                QString channelName = channel["name"].toString();
                QString channelCode = channel["code"].toString();
                QString channelStatus = QString::number(channel["status"].toInt());
                strListChannels.append(channelCode+":"+channelName+":"+channelStatus);
            }

            if(!strListChannels.isEmpty())
            {
                emit hideAlert();
                // 通知界面显示
                emit initChannelsData(strListChannels);
            }else
            {
                emit showAlert(AlertForm::ERROR, QString("未获取到平台信息!"));
            }
         }
    }
}

void FlowControl::onGetDailyStatement()
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetDailyStatementData();
    emit showAlert(AlertForm::LOADING, "正在获取门店日结信息......");
    QLOG_INFO() << QString("[---onGetDailyStatement---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_pullDishesSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("onGetDailyStatement finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "获取门店日结信息失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            emit showAlert(AlertForm::ERROR, QString("获取门店日结信息失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            emit hideAlert();
            QList<DailyStatement> infos;
            QJsonArray array = recvJson["daily_summarys"].toArray();
            foreach(QJsonValue v, array)
            {
                QJsonObject json =  v.toObject();
                DailyStatement dailyStatement;
                dailyStatement.channel = json["channel"].toString();
                dailyStatement.total_number = json["total_number"].toInt();
                dailyStatement.total_fee = json["total_fee"].toInt();
                dailyStatement.refund_number = json["refund_number"].toInt();
                dailyStatement.refund_total_fee = json["refund_total_fee"].toInt();
                dailyStatement.total_projected_revenue = json["total_projected_revenue"].toInt();

                dailyStatement.product_fee_zps = json["product_fee_zps"].toInt();
                dailyStatement.send_fee_zps = json["send_fee_zps"].toInt();
                dailyStatement.discount_platform_fee_zps = json["discount_platform_fee_zps"].toInt();
                dailyStatement.discount_shop_fee_zps = json["discount_shop_fee_zps"].toInt();
                dailyStatement.package_fee_zps = json["package_fee_zps"].toInt();
                dailyStatement.service_fee_zps = json["service_fee_zps"].toInt();
                dailyStatement.product_fee = json["product_fee"].toInt();
                dailyStatement.send_fee = json["send_fee"].toInt();
                dailyStatement.discount_platform_fee = json["discount_platform_fee"].toInt();
                dailyStatement.discount_shop_fee = json["discount_shop_fee"].toInt();
                dailyStatement.package_fee = json["package_fee"].toInt();
                dailyStatement.service_fee = json["service_fee"].toInt();


                infos.append(dailyStatement);
            }
            emit showDailyStatement(infos);
        }
    }
}



void FlowControl::onSetStoreOperatingStatus(QString channel, int business_status)
{
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetOperatingStatusData(channel, business_status);
    emit showAlert(AlertForm::LOADING, "正在设置门店营业状态......");
    QLOG_INFO() << QString("[---SetStoreOperatingStatus---]. [requestData:%1]").arg(_GetJsonStr(sendJson));
    result = m_pullDishesSocket->Request(sendJson, recvJson, error);
    QLOG_INFO() << QString("SetStoreOperatingStatus finsh. [result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error, _GetJsonStr(recvJson));
    if(!result)
    {
        emit showAlert(AlertForm::ERROR, "设置门店营业状态失败![网络错误]");
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            emit showAlert(AlertForm::ERROR, QString("设置门店营业状态失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            emit hideAlert();
            emit setStoreOperatingStatusFinsh(channel);
        }
    }
}
