#include "printMsgQueueDB.h"
#include "QsLog.h"
#include <QDateTime>
#include "Control/flowControl.h"

PrintMsgQueueDB::PrintMsgQueueDB()
{
    QLOG_INFO()<<"[<<<<---PrintMsgQueueDB:: Structure POS Print Message Queue INFO DataBase--->>>>]";
}


bool PrintMsgQueueDB::initPrintMsgQueueDB(){
    bool bRet = false;
    m_sqlDb = QSqlDatabase::addDatabase("QODBC","PrintMsgQueueDB");   //数据库驱动类型为SQL Server
    if ( m_sqlDb.isValid() ) {
        QLOG_INFO()<<"[<<<<---SqlServer ODBC driver is valid--->>>>]";
        QString dsn="DRIVER={SQL SERVER};SERVER=127.0.0.1\\sqlexpress;DATABASE=MMXBenefits";
        m_sqlDb.setDatabaseName(dsn);                            //设置数据源名称
        m_sqlDb.setUserName("sa");                               //登录用户
        m_sqlDb.setPassword("SIM29@123");
        if(!m_sqlDb.open()) {                                      //打开数据库

            QLOG_ERROR()<<"[<<<<---SqlServer Open Database error:--->>>>]"<<m_sqlDb.lastError().text();
        } else {

            QLOG_INFO()<<"[<<<<---PrintMsgQueueDB::SqlServer Test Open database success!:--->>>>]";
            QSqlQuery query(m_sqlDb);
            QString selectsql ="select * from sys.tables where name='tb_print_msr_customer'" ;
            if(!query.exec(selectsql)) {
                QLOG_ERROR()<<"[<<<<---PrintMsgQueueDB::SqlServer Database  check tb_print_msr_customer failed--->>>>]"<<query.lastError().text();
            }
            if(query.next()) {
                QLOG_INFO() << "[<<<<---PrintMsgQueueDB::Table tb_print_msr_customer Has Exist--->>>>]";
                bRet = true;
            } else {
                QLOG_INFO() << "[<<<<---PrintMsgQueueDB::Table tb_print_msr_customer Does Not Exist--->>>>]";

                query.prepare( QString("CREATE TABLE [dbo].[tb_print_msr_customer] ("
                                    " [id] [int] IDENTITY(1,1) NOT NULL, [chk_num] [int] NOT NULL,  [print_status] [int] NULL, "
                                    "[order_id] [varchar](50) NULL,  [order_status] [int] NULL,"
                                    " [create_datetime] [datetime] NULL, [modify_datetime] [datetime] NULL,"

                                    " [reserve0] [int] NULL, [reserve1] [int] NULL,[reserve2] [int] NULL,"
                                    " [reserve3] [varchar](100) NULL, [reserve4] [varchar](200) NULL,[reserve5] [varchar](400) NULL,"
                                    " [reserve6] [int] NULL, [reserve7] [int] NULL, [reserve8] [varchar](80) NULL, [reserve9] [varchar](80) NULL"
                                    " PRIMARY KEY CLUSTERED ( [id] ASC"
                                    ")WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = "
                                    " OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]") );

                if(!query.exec()){
                    QLOG_ERROR()<< "[<<<<---Create Table tb_print_msr_customer Faild--->>>>]" <<query.lastError().text()<<QString::number(query.lastError().type());
                }else {
                    bRet = true;
                }
            }

            QLOG_INFO()<<"[<<<<---SqlServer Test Open database success!:--->>>>]";
            m_sqlDb.close();
        }
    } else {
        QLOG_ERROR()<<"[<<<<---SqlServer ODBC driver no valid--->>>>]";
    }

    return bRet;
}


PrintMsgQueueDB &PrintMsgQueueDB::getInstance()
{
    static PrintMsgQueueDB PrintMsgQueueDB;
    return PrintMsgQueueDB;
}

bool PrintMsgQueueDB::insertOrderPrtMsg( OrderObject* orderObj, const QString& posCheckNo ) {
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        return false;
    }
    bool result = false;

    //刷新 存储订单 销售退货状态的内存标识;
    orderObj->orderSaleRefundStatus = orderObj->orderStatus == 6 ? 6 : 3 ;

    QSqlQuery query(m_sqlDb);
    query.prepare("INSERT INTO tb_print_msr_customer(chk_num, print_status, "
                  " order_id, order_status, create_datetime ) "
                  "VALUES(?, ?, ?, ?, ?) select @@identity ");
    query.addBindValue(posCheckNo.toInt()); // --小票号
    query.addBindValue(0); // --打印状态: 0:未打印  1:已打印;
    query.addBindValue(orderObj->id); // --订单编号
    // query.addBindValue( orderObj->orderStatus );  // --订单状态(int);
    query.addBindValue( orderObj->orderSaleRefundStatus );  // --订单 销售退货状态 内存标识(int);
    QDateTime qdaTi = QDateTime::currentDateTimeUtc();
    QString createTime  =  qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss");
    query.addBindValue(createTime); // --POS开单时间

    if(!query.exec())
    {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:tb_print_msr_customer Error--->>>>]"<<query.lastError().text()<<QString::number(query.lastError().type());
        QLOG_INFO()<<QString("INSERT INTO tb_print_msr_customer(chk_num, print_status, order_id, order_status, create_datetime ) "
                             "VALUES(%1, %2, %3, %4, %5)  select @@identity ")
                     .arg(posCheckNo.toInt()).arg(0).arg(orderObj->id).arg(orderObj->orderStatus).arg(createTime);
    } else {
       int printTabIndex = 0;
        if ( query.first() ) {
            printTabIndex = query.value(0).toInt();
            query.clear();

            if ( orderObj->orderStatus == OrderObject::Refunded ) {
                query.prepare(QString("update tb_msr_customer_info set reserve1=%1 where order_id='%2' and order_status = 6 ")
                              .arg(printTabIndex).arg( orderObj->id) );
            } else {
                query.prepare(QString("update tb_msr_customer_info set reserve1=%1 where order_id='%2' and order_status <> 6 ")
                              .arg(printTabIndex).arg( orderObj->id) );
            }

            if ( !query.exec() ) {
                QLOG_ERROR()<<QString("Update tb_msr_customer_info Failed, orderId:%1, chk_num:%2 , prtTabIndex:%3, Then Rollback tb_print_msr_customer ")
                             .arg(orderObj->id).arg( posCheckNo.toInt() ).arg( printTabIndex );
                query.clear();
                query.prepare(QString("delete from tb_print_msr_customer where id=%1 ").arg(printTabIndex) );  // 根据插表自增ID进行删除,无需使用订单状态。

                if ( !query.exec() ) {
                    QLOG_INFO()<<QString("Rollback  tb_print_msr_customer  Failed, orderId:%1, prtTabIndex:%2 ").arg(orderObj->id).arg( printTabIndex );
                }else {
                    QLOG_INFO()<<QString("Rollback  tb_print_msr_customer  Success, orderId:%1, prtTabIndex:%2 ").arg(orderObj->id).arg( printTabIndex );
                }
            } else {
                result = true;
                QLOG_INFO()<<QString("Update tb_msr_customer_info Success, orderId:%1, chk_num:%2 , prtTabIndex:%3 ")
                             .arg(orderObj->id).arg( posCheckNo.toInt() ).arg( printTabIndex );
            }

            QLOG_INFO()<<QString("[<<<<---PrintMsgQueueDB::insertOrderPrtMsg  Insert OrderId %1,orderStatus:%2, chk_num:%3  Into Success,  printTabIndex:%4--->>>>]")
                         .arg(orderObj->id).arg(orderObj->orderStatus).arg( posCheckNo.toInt() ).arg(printTabIndex);

        } else {
            QLOG_INFO()<<QString("[<<<<---PrintMsgQueueDB::insertOrderPrtMsg  Insert OrderId %1,orderStatus:%2, chk_num:%3  Into Failed,  printTabIndex:%4--->>>>]")
                         .arg(orderObj->id).arg(orderObj->orderStatus).arg( posCheckNo.toInt() ).arg(printTabIndex);
        }

    }

    m_sqlDb.close();
    return result;
}

bool PrintMsgQueueDB::updatePrintMsgStatus(OrderObject* orderObj, const int &printStatus){
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        return false;
    }
    bool result;
    QSqlQuery query(m_sqlDb);
    if (orderObj->orderStatus != 6) {
        query.prepare(QString("update tb_print_msr_customer set print_status=%1 where order_id='%2' and order_status != 6 ")
                      .arg(QString::number(printStatus)).arg(orderObj->id));
    } else {
        query.prepare(QString("update tb_print_msr_customer set print_status=%1 where order_id='%2'  and order_status = 6")
                      .arg(QString::number(printStatus)).arg(orderObj->id));
    }

    if(!query.exec()) {
        QLOG_ERROR()<<query.lastError().text()<<"[<<<<---SqlServer Database:update Order Print Status Failed--->>>>]";
        result= false;
    } else {
        QLOG_INFO()<<QString("[<<<<---SqlServer Database:Update OrderId %1 Print Status success--->>>>]").arg(orderObj->id);
        result = true;
    }
    m_sqlDb.close();
    return result;
}


bool PrintMsgQueueDB::resetPrintMsgStatus(const OrderObject* orderObj, const int &printTypeCode) {
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        return false;
    }
    bool result;
    QString preExeSql = "";
    QString preExeSqlAnother = "";
    QSqlQuery query(m_sqlDb);
    switch (printTypeCode) {
    case 1:  // 全部小票
        preExeSql = QString("update tb_print_msr_customer set  print_status=0,  reserve0=0, reserve1=0, reserve6=0 where order_id='%1' ").arg(orderObj->id);
        preExeSqlAnother  = QString("update tb_main_prod_refinfo set  prod_resv1=0 where order_id='%1' ").arg(orderObj->id);
        break;
    case 2: // 汇总小票
        preExeSql = QString("update tb_print_msr_customer set print_status=0 where order_id='%1' ").arg(orderObj->id);
        break;
    case 3: // 杯贴小票
        // tb_print_msr_customer -> reserve0  unused;
        preExeSql =QString("update tb_main_prod_refinfo set prod_resv1=0 where order_id='%1' ").arg(orderObj->id);
        break;
    case 4: // 预约提醒小票
        preExeSql = QString("update tb_print_msr_customer set reserve1=0 where order_id='%1' ").arg(orderObj->id);
        break;
    case 5: // 街送小票
        preExeSql = QString("update tb_print_msr_customer set reserve6=0 where order_id='%1' ").arg(orderObj->id);
        break;
    default:
        m_sqlDb.close();
        return false;
    }

    if (orderObj->orderStatus != 6) {
        preExeSql = preExeSql + " and order_status != 6 ";
        query.prepare(preExeSql);
        if ( preExeSqlAnother.length() )
            preExeSqlAnother = preExeSqlAnother + " and order_status != 6 ";
    } else {
        preExeSql = preExeSql + " and order_status = 6 ";
        query.prepare(preExeSql);
        if ( preExeSqlAnother.length() )
            preExeSqlAnother = preExeSqlAnother + " and order_status = 6 ";
    }

    QLOG_INFO()<< QString("[<<<<---SqlServer Database:Reset OrderId %1 Print Status: sql1: %2 ; sql2: %3 --->>>>]").arg(orderObj->id).arg(preExeSql).arg(preExeSqlAnother);
    if(!query.exec()) {
        QLOG_ERROR()<<query.lastError().text()<<"[<<<<---SqlServer Database:Reset Order Print Status Failed--->>>>]";
        result= false;
    } else {
        QLOG_INFO()<<QString("[<<<<---SqlServer Database:Reset OrderId %1 Print Status success--->>>>]").arg(orderObj->id);
        result = true;
        if ( preExeSqlAnother.length() ) {
            query.prepare(preExeSqlAnother);
            if ( !query.exec() ){
                QLOG_ERROR()<<query.lastError().text()<<"[<<<<---SqlServer Database:Reset OrderId Cup Ticket Print Status Failed--->>>>]";
                result= false;
            } else {
                QLOG_INFO()<<QString("[<<<<---SqlServer Database:Reset OrderId %1 Cup Ticket Print Status success--->>>>]").arg(orderObj->id);
            }
        }
    }

    m_sqlDb.close();
    return result;
}


bool PrintMsgQueueDB::resetPrintMsgStatus(const OrderObject* orderObj, const QJsonObject& printOptions ) {
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        return false;
    }

    int printAll = 0, printSummary=0, printCup = 0, printSubscribe = 0, printStreet = 0;
    if ( printOptions.contains(JSON_PRINT_OPT_ALL) ) {
        printAll = printOptions[JSON_PRINT_OPT_ALL].toInt();
    }
    if ( printOptions.contains(JSON_PRINT_OPT_SUM) ) {
        printSummary = printOptions[JSON_PRINT_OPT_SUM].toInt();
    }
    if ( printOptions.contains(JSON_PRINT_OPT_CUP) ) {
        printCup = printOptions[JSON_PRINT_OPT_CUP].toInt();
    }
    if ( printOptions.contains(JSON_PRINT_OPT_SUB) ) {
        printSubscribe = printOptions[JSON_PRINT_OPT_SUB].toInt();
    }
    if ( printOptions.contains(JSON_PRINT_OPT_STR) ) {
        printStreet = printOptions[JSON_PRINT_OPT_STR].toInt();
    }

    bool result;
    QString preExeSql = "";
    QString preExeSqlAnother = "";
    QSqlQuery query(m_sqlDb);
    QDateTime qdaTi = QDateTime::currentDateTimeUtc();
    QString createTime  =  qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss");

    // 全部小票;
    if ( printAll ) {

        preExeSql = QString("update tb_print_msr_customer set  print_status=0,  reserve0=0, reserve1=0, reserve6=0, create_datetime='%2'  where order_id='%1' ")
                .arg(orderObj->id).arg(createTime);

        preExeSqlAnother  = QString("update tb_main_prod_refinfo set  prod_resv1=0 where order_id='%1' ").arg(orderObj->id);

        // 非全部小票;
    } else {

        preExeSql = QString("update tb_print_msr_customer set create_datetime='%1', ").arg(createTime);

        if ( printSummary ) { // 汇总小票
            preExeSql += QString(" print_status=0 ");
        }
        if (printSubscribe) { // 预约提醒小票
            preExeSql += QString(" %1 reserve1=0 ").arg( printSummary ? ',' : ' ');
        }
        if (printStreet) { // 街送小票
            preExeSql += QString(" %1 reserve6=0 ").arg( (printSummary || printSubscribe) ? ',' : ' ');
        }
        if (printSummary || printSubscribe || printStreet) { // 拼接订单号;

            preExeSql += QString(" where order_id='%1' ").arg( orderObj->id );
            if ( printCup ) {  // 含杯贴小票重打;
                // 杯贴小票 tb_print_msr_customer -> reserve0  unused;
                preExeSqlAnother  = QString("update tb_main_prod_refinfo set  prod_resv1=0 where order_id='%1' ").arg(orderObj->id);
            }

        } else {

            if ( printCup ) {   // 杯贴小票 tb_print_msr_customer -> reserve0  unused;
                preExeSql  = QString("update tb_main_prod_refinfo set  prod_resv1=0 where order_id='%1' ").arg(orderObj->id);
            } else {
                QLOG_ERROR()<<"[<<<<---SqlServer Database: Push Print Options Invalid, options = --->>>>]"<< printOptions;
                m_sqlDb.close();
                return false;
            }
        }

    }

    if (orderObj->orderStatus != 6) {
        preExeSql = preExeSql + " and order_status != 6 ";
        query.prepare(preExeSql);
        if ( preExeSqlAnother.length() )
            preExeSqlAnother = preExeSqlAnother + " and order_status != 6 ";
    } else {
        preExeSql = preExeSql + " and order_status = 6 ";
        query.prepare(preExeSql);
        if ( preExeSqlAnother.length() )
            preExeSqlAnother = preExeSqlAnother + " and order_status = 6 ";
    }

    QLOG_INFO()<< QString("[<<<<---SqlServer Database:Reset OrderId %1 Print Status: sql1: %2 ; sql2: %3 --->>>>]").arg(orderObj->id).arg(preExeSql).arg(preExeSqlAnother);
    if(!query.exec()) {
        QLOG_ERROR()<<query.lastError().text()<<"[<<<<---SqlServer Database:Reset Order Print Status Failed--->>>>]";
        result= false;
    } else {
        QLOG_INFO()<<QString("[<<<<---SqlServer Database:Reset OrderId %1 Print Status success--->>>>]").arg(orderObj->id);
        result = true;
        if ( preExeSqlAnother.length() ) {
            query.prepare(preExeSqlAnother);
            if ( !query.exec() ){
                QLOG_ERROR()<<query.lastError().text()<<"[<<<<---SqlServer Database:Reset OrderId Cup Ticket Print Status Failed--->>>>]";
                result= false;
            } else {
                QLOG_INFO()<<QString("[<<<<---SqlServer Database:Reset OrderId %1 Cup Ticket Print Status success--->>>>]").arg(orderObj->id);
            }
        }
    }

    m_sqlDb.close();
    return result;
}


bool PrintMsgQueueDB::isOrderPrtMsgExist(OrderObject* orderObj){
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        return false;
    }
    bool result;

    QSqlQuery query(m_sqlDb);
    if ( orderObj->orderStatus == OrderObject::Refunded ) {
        query.prepare(QString("select order_id from tb_print_msr_customer where order_id='%1' and order_status = 6 ").arg(orderObj->id) );
    } else {
        query.prepare(QString("select order_id from tb_print_msr_customer where order_id='%1' and order_status <> 6 ").arg(orderObj->id) );
    }

    if(!query.exec()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:isOrderPrtMsgExist--->>>>] order_id: "<<orderObj->id
                   << " order_status: "<<orderObj->orderStatus <<query.lastError().text();
        result= false;
    }
    if(query.first()) {
        result= true;
    } else {
        result = false;
    }
    return result;
}

bool PrintMsgQueueDB::deletePrintMsgRecord(QString creatTime)
{
    //QMutexLocker mutex(&m_mutex);
    bool retTryLock = m_mutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
    if(!retTryLock){
        QLOG_ERROR()<<"[<<<<---PrintMsgQueueDB::delete print msg queue Record Try Lock Failed--->>>>]";
        return false;
    }
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---PrintMsgQueueDB::delete print msg queue Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        m_mutex.unlock();
        return false;
    }
    bool result=true;
    QLOG_INFO()<<QString("[<<<<---PrintMsgQueueDB::begin delete print msg queue create_datetime:%1--->>>>]").arg(creatTime);
    QSqlQuery query(m_sqlDb);
    query.prepare(QString("delete from tb_print_msr_customer where create_datetime<'%1'").arg(creatTime));
    if(!query.exec()) {
        QLOG_ERROR()<<query.lastError().text()<<__FUNCTION__;
        result= false;
    }
    m_sqlDb.close();
    m_mutex.unlock();
    return result;
}
