#include "PrintOrderPromotionDB.h"
#include "QsLog.h"
#include "alertForm.h"
#include <QDateTime>
#include "Control/flowControl.h"
#include <Model/dishesObject.h>
#include <Model/couponsObject.h>

PrintOrderPromotionDB::PrintOrderPromotionDB()
{
    QLOG_INFO()<<"[<<<<---PrintOrderPromotionDB:: Structure POS Print Order Promotion  INFO DataBase--->>>>]";
}

bool PrintOrderPromotionDB::initPrintOrderPromotionDB(){
    bool bRetCheckColumn = false;
    bool bRet = false;
    m_sqlDb = QSqlDatabase::addDatabase("QODBC","PrintOrderPromotionDB");   //数据库驱动类型为SQL Server
    if ( m_sqlDb.isValid() ) {
        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()<<"[<<<<---PrintOrderPromotionDB::SqlServer Test Open database success!:--->>>>]";
            QSqlQuery query(m_sqlDb);
            QString selectsql ="select * from sys.tables where name='tb_order_promotions'" ;
            if(!query.exec(selectsql)) {
                QLOG_ERROR()<<"[<<<<---PrintOrderPromotionDB::SqlServer Database  check tb_order_promotions failed--->>>>]"<<query.lastError().text();
            }
            if(query.next()) {
                QLOG_INFO() << "[<<<<---PrintOrderPromotionDB::Table  tb_order_promotions  Has Exist--->>>>]";
                bRet = true;
            } else {
                QLOG_INFO() << "[<<<<---PrintOrderPromotionDB::Table  tb_order_promotions  Does Not Exist--->>>>]";

                query.prepare( QString("CREATE TABLE [dbo].[tb_order_promotions] ("
                                    " [id] [int] IDENTITY(1,1) NOT NULL, [order_id] [varchar](50) NOT NULL, [create_datetime] [datetime] NULL,"
                                    " [prod_seq] [int] NULL, [coupon_seq] [int] NULL,"
                                    " [promotion_type] [int] NULL, [discount_fee] [int] NULL, [promotion_qty] [int] NULL, "
                                    " [promotion_sku] [varchar](20) NULL, [promotion_name] [varchar](60) NULL, "
                                    " [resv0] [int] NULL, [resv1] [int] NULL,[resv2] [int] NULL,[resv3] [int] NULL, [resv4] [int] NULL,[resv5] [int] NULL,[resv6] [varchar](60) NULL,"
                                    " [resv7] [varchar](60) NULL, [resv8] [varchar](60) NULL, [resv9] [varchar](80) NULL, [resv10] [varchar](80) NULL,[resv11] [varchar](80) NULL,"
                                    " [resv12] [varchar](100) NULL,[resv13] [varchar](100) NULL,[resv14] [varchar](100) 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_order_promotions  Faild--->>>>]" <<query.lastError().text()<<QString::number(query.lastError().type());
                }else {
                    bRet = true;
                }
            }
            m_sqlDb.close();
        }
    } else {
        QLOG_ERROR()<<"[<<<<---SqlServer ODBC driver no valid--->>>>]";
    }

    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---FM TakeOut Plugin Version:2.2021.4.19  Begin check table tb_order_promotions Column--->>>>]");
    bRetCheckColumn = alterTablePrintOrderPromotionAndCheck();

    return bRet && bRetCheckColumn ;
}


bool PrintOrderPromotionDB::alterTablePrintOrderPromotionAndCheck() {

    QMutexLocker mutex(&m_mutex);
    int checkSuccessNum = 0;
    QSqlQuery query(m_sqlDb);
    QString selectsql;
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---alterTablePrintOrderPromotionAndCheck::SqlServer Database:Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        return false;
    }

    // Alter Table order_status;
    selectsql = "select * from syscolumns where id=object_id('tb_order_promotions') and name='order_status'";
    query.exec(selectsql);
    if(!query.next()){
        selectsql = "alter table tb_order_promotions add order_status int null ";
        if(!query.exec(selectsql)){
            QLOG_ERROR()<< "[<<<<---alter table tb_order_promotions Add order_status Faild--->>>>]" <<query.lastError().text()<<QString::number(query.lastError().type());
        } else { checkSuccessNum++; }
    } else { checkSuccessNum++;}

    // Alter Table chk_num;
    selectsql = "select * from syscolumns where id=object_id('tb_order_promotions') and name='chk_num'";
    query.exec(selectsql);
    if(!query.next()){
        selectsql = "alter table tb_order_promotions add chk_num int null ";
        if(!query.exec(selectsql)){
            QLOG_ERROR()<< "[<<<<---alter table tb_order_promotions Add chk_num Faild--->>>>]" <<query.lastError().text()<<QString::number(query.lastError().type());
        } else { checkSuccessNum++; }
    } else { checkSuccessNum++;}

    m_sqlDb.close();

    if (2 == checkSuccessNum) {
        QLOG_INFO()<<"[<<<<---alterTablePrintOrderPromotionAndCheck::checkSuccessNum = 2 --->>>>]";
        return true;
    } else {
        QLOG_ERROR()<<QString("[<<<<---alterTablePrintOrderPromotionAndCheck::checkSuccessNum < 2 = %1>>>>]").arg(checkSuccessNum);
        return false;
    }

}


PrintOrderPromotionDB &PrintOrderPromotionDB::getInstance()
{
    static PrintOrderPromotionDB printOrderPromotionDB;
    return printOrderPromotionDB;
}


bool PrintOrderPromotionDB::insertOrderPromotion(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;
    }

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

    // 开启数据库事务实现原子操作: 保证  tb_order_promotions: 订单促销优惠列表   同时插入成功;
    // m_sqlDb.transaction(); 驱动不支持;
    QSqlQuery query(m_sqlDb);
    if ( !query.exec("begin tran") ) {
       QLOG_ERROR()<<"[<<<<---PrintCupStickPosDB::insertOrderPromotion: Begin transaction Failed--->>>>]"<<m_sqlDb.lastError().text();
    }

    bool retInsCoupProm = false;
    bool retInsNorProm = false;
    // WSG-杯贴祝福-商品券号关联数据;
    if ( ( "WSG-MOD" == orderObj->channel || "WSG-MOP" == orderObj->channel ) && "4" == orderObj->platformSource   ) {
        retInsCoupProm = insertCouponPromotion(orderObj, posCheckNo);
    } else {  // All Channel 商品关联数据;
        retInsNorProm = insertNormalPromotion(orderObj, posCheckNo);
    }

    // 结束数据库事务操作 保证  tb_order_promotions:父商品与子商品  同时插入成功;
    // Sleep(10*1000);   // test  sqldb transaction
    // m_sqlDb.commit()  and m_sqlDb.rollback() 都是不支持的;
    if ( retInsCoupProm || retInsNorProm ) {
        if ( !query.exec( "commit" ) ) {
            QLOG_ERROR()<<"[<<<<---insertOrderProduct::insertOrderPromotion: Begin Commit Failed--->>>>]"<<m_sqlDb.lastError().text();
            if ( !query.exec( "rollback" ) ) {
                QLOG_ERROR()<<"[<<<<---insertOrderProduct::insertOrderPromotion: Begin Rollback Failed--->>>>]"<<m_sqlDb.lastError().text();
            }
        }
    }

    m_sqlDb.close();
    return retInsCoupProm || retInsNorProm;
}

bool PrintOrderPromotionDB::insertCouponPromotion(OrderObject* orderObj, const QString& posCheckNo) {
    bool  insertCoupPromSuc = true;
    QSqlQuery query(m_sqlDb);
    QDateTime qdaTi = QDateTime::currentDateTimeUtc();

    for (int i=0; i < orderObj->coupList.count(); i++) {
        CouponsObject* coupon = orderObj->coupList.at(i);
        for ( int m = 0; m < coupon->itemsDiscount.count(); m++ ) {
            PromotionItemObject* prom = coupon->itemsDiscount.at(m);
            query.prepare("INSERT INTO tb_order_promotions(order_id, order_status, chk_num, create_datetime, "
                          " prod_seq, coupon_seq, promotion_type, discount_fee, promotion_qty, promotion_sku, promotion_name ) "
                          " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) ");
            query.addBindValue(orderObj->id);  // --订单编号
            // query.addBindValue( orderObj->orderStatus );  // --订单状态(int);
            query.addBindValue( orderObj->orderSaleRefundStatus );  // --订单 销售退货状态 内存标识(int);
            query.addBindValue(posCheckNo.toInt());  // --订单自动生产小票号
            query.addBindValue(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss")); // --商品入库时间
            query.addBindValue(i+1);   // --主商品序号;
            query.addBindValue(i+1);   // --券序号;
            query.addBindValue( prom->type );   // --优惠类型
            if ( OrderObject::Refunded == orderObj->orderStatus) {
                query.addBindValue( 0 - prom->discountFee );   // --退货单优惠金额需为负数;
                query.addBindValue( 0 - prom->promotionQty );   // --退货单优惠数量需为负数;
            } else {
                query.addBindValue( prom->discountFee );   // --优惠金额
                query.addBindValue( prom->promotionQty );   // --优惠数量
            }
            query.addBindValue( prom->promotionSku );   // --优惠SKU
            query.addBindValue( prom->promotionName );   // --优惠名称

            if(!query.exec()) {
                QLOG_ERROR()<<"[<<<<---SqlServer Database: Insert tb_order_promotions Error--->>>>]"<<query.lastError().text()<<QString::number(query.lastError().type());
                QLOG_ERROR()<<QString("INSERT INTO tb_order_promotions(order_id, order_status, chk_num, create_datetime, "
                                      " prod_seq, coupon_seq, promotion_type, discount_fee, promotion_qty, promotion_sku, promotion_name ) "
                                      "VALUES(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11 ) ").arg(orderObj->id).arg(orderObj->orderStatus).arg( posCheckNo.toInt() )
                              .arg(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss"))
                              .arg(i+1).arg(i+1).arg(prom->type).arg(prom->discountFee).arg(prom->promotionQty).arg(prom->promotionSku).arg(prom->promotionName);

                insertCoupPromSuc = false;
                break;
            } else {
                QLOG_INFO()<<QString("[<<<<---SqlServer Database:Insert OrderId %1 MainProductSeq: %2 PromotionCode: %3  Into tb_order_promotions Success--->>>>]")
                             .arg(orderObj->id).arg(i+1).arg(prom->promotionSku);
            }
        }

        if ( !insertCoupPromSuc )
          break;
    }

    return insertCoupPromSuc;
}


bool PrintOrderPromotionDB::insertNormalPromotion(OrderObject* orderObj, const QString& posCheckNo){
    bool  insertProdPromSuc = true;
    bool  insertDeliveryPromSuc = true;
    QSqlQuery query(m_sqlDb);
    QDateTime qdaTi = QDateTime::currentDateTimeUtc();

    for (int i=0; i < orderObj->proList.count(); i++) {
        dishesObject* dish=orderObj->proList.at(i);
        for (int m=0; m < dish->itemsDiscount.count(); m++) {
            PromotionItemObject* prom = dish->itemsDiscount.at(m);
            query.prepare("INSERT INTO tb_order_promotions(order_id, order_status, chk_num, create_datetime, "
                          " prod_seq, coupon_seq, promotion_type, discount_fee, promotion_qty, promotion_sku, promotion_name ) "
                          " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ? , ?, ?) ");
            query.addBindValue(orderObj->id);  // --订单编号
            // query.addBindValue( orderObj->orderStatus );  // --订单状态(int);
            query.addBindValue( orderObj->orderSaleRefundStatus );  // --订单 销售退货状态 内存标识(int);
            query.addBindValue(posCheckNo.toInt());  // --订单自动生产小票号
            query.addBindValue(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss")); // --商品入库时间
            query.addBindValue(i+1);               // --主商品序号;
            query.addBindValue(0);               // --券序号;
            query.addBindValue( prom->type );   // --优惠类型
            if ( OrderObject::Refunded == orderObj->orderStatus ) {
                query.addBindValue(0 - prom->discountFee);    // --退货单优惠金额需为负数;
                query.addBindValue(0 - prom->promotionQty );   // --退货单优惠数量需为负数;
            } else {
                query.addBindValue( prom->discountFee );   // --优惠金额
                query.addBindValue( prom->promotionQty );   // --优惠数量
            }
            query.addBindValue( prom->promotionSku );   // --优惠SKU
            query.addBindValue( prom->promotionName );   // --优惠名称

            if(!query.exec()) {
                QLOG_ERROR()<<"[<<<<---SqlServer Database: Insert tb_order_promotions Error--->>>>]"<<query.lastError().text()<<QString::number(query.lastError().type());
                QLOG_ERROR()<<QString("INSERT INTO tb_order_promotions(order_id, order_status, chk_num, create_datetime, "
                                      " prod_seq, coupon_seq, promotion_type, discount_fee, promotion_qty, promotion_sku, promotion_name ) "
                                      "VALUES(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11) ").arg(orderObj->id).arg(orderObj->orderStatus).arg( posCheckNo.toInt() )
                              .arg(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss"))
                              .arg(i+1).arg(0).arg(prom->type).arg(prom->discountFee).arg(prom->promotionQty).arg(prom->promotionSku).arg(prom->promotionName);

                insertProdPromSuc = false;
                break;
            } else {
                QLOG_INFO()<<QString("[<<<<---SqlServer Database:Insert OrderId %1 MainProductSeq: %2 PromotionCode: %3  Into tb_order_promotions Success--->>>>]")
                             .arg(orderObj->id).arg(i+1).arg(prom->promotionSku);
            }
        }

        if ( !insertProdPromSuc )
          break;
    }
    // 插入打包费方面优惠: 打包费优惠 + 打包费B账户优惠;
    //主商品序号:: 整单打包:orderObj->proList.count() +1  ;  打包费:orderObj->proList.count() +1 +打包的占位符;
    // 插入配送费方面优惠: 配送费优惠 + 配送费B账户优惠;
    // 上游oms 开关已完全打开: 配送费已添加到商品列表中; 顾无需此处配送费整合逻辑; // DeliveryDiscount + DeliveryDiscountB
    return  insertProdPromSuc && insertDeliveryPromSuc;
}


bool PrintOrderPromotionDB::updateOrderPromotionCheckNum(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;
    QSqlQuery query(m_sqlDb);
    if ( orderObj->orderStatus == OrderObject::Refunded) {
        query.prepare(QString("update tb_order_promotions set chk_num =%1 where order_status = 6 and order_id = '%2' ").arg( posCheckNo.toInt() ).arg(orderObj->id) );
    } else {
        query.prepare(QString("update tb_order_promotions set chk_num =%1 where order_status <> 6 and order_id = '%2' ").arg( posCheckNo.toInt() ).arg(orderObj->id) );
    }

    if(!query.exec()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:Update tb_order_promotions Failed --->>>>]"<<orderObj->id<<query.lastError().text();
        result= false;
    }else {
        QLOG_INFO()<<QString("[<<<<---SqlServer Database:Update tb_order_promotions OrderId %1 CheckNum:%2  Success--->>>>]")
                         .arg(orderObj->id).arg(posCheckNo);
         result= true;
    }

    m_sqlDb.close();
    return result;

}

bool PrintOrderPromotionDB::isOrderPromotionExist( 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_order_promotions where order_id='%1' and order_status = 6 ").arg(orderObj->id) );
    } else {
        query.prepare(QString("select order_id from tb_order_promotions where order_id='%1' and order_status <> 6 ").arg(orderObj->id) );
    }

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

bool PrintOrderPromotionDB::deletePromotionRecord(QString creatTime)
{
    bool retTryLock = m_mutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
    if(!retTryLock){
        QLOG_ERROR()<<"[<<<<---PrintOrderPromotionDB::deletePromotionRecord Try Lock Failed--->>>>]";
        return false;
    }
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---PrintOrderPromotionDB::deletePromotionRecord Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        m_mutex.unlock();
        return false;
    }
    bool result=true;
    QLOG_INFO()<<QString("[<<<<---PrintOrderPromotionDB::begin deletePromotionRecord create_datetime: %1--->>>>]").arg(creatTime);
    QSqlQuery query(m_sqlDb);
    query.prepare(QString("delete from tb_order_promotions 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;
}

bool PrintOrderPromotionDB::queryValue(const QString& orderId, const QString& key, QString& error, QVariant &value){
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        error.append(QString("SqlServer Database:Open Failed").append(m_sqlDb.lastError().text()));
        return false;
    }
    QSqlQuery query(m_sqlDb);
    query.prepare(QString("select %1 from tb_order_promotions where order_id='%1'").arg(key).arg(orderId));
    if(!query.exec()) {
        error.append(query.lastError().text());
        m_sqlDb.close();
        return false;
    } else {
        while(query.next()) {
            value= query.value(0);
        }
    }
    m_sqlDb.close();
    return true;
}

bool PrintOrderPromotionDB::queryIsNull(const QString &orderId, const QString& key,QString &error, bool &result){
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        error.append(QString("SqlServer Database:Open Failed").append(m_sqlDb.lastError().text()));
        return false;
    }
    QSqlQuery query(m_sqlDb);
    query.prepare(QString("select %1 from tb_order_promotions where order_id=%2 and %3 is null").arg(orderId,orderId,key));
    if(!query.exec()) {
        error.append(query.lastError().text());
        m_sqlDb.close();
        return false;
    } else {
        if(query.first()) {
            result= true;
        } else{
            result = false;
        }
    }
    m_sqlDb.close();
    return true;
}
