#include "mainForm.h"
#include <QApplication>
#include <QDir>
#include <QResource>
#include <QThread>
#include "QsLog.h"
#include "preDefine.h"
#include "Control/flowControl.h"
#include "Control/SocketCommunicate.h"
#include "floatForm.h"
#include "DTools/configManger.h"
#include <windows.h>
#include <QProcess>
#include <QSqlDatabase>
#include "DTools/dump.h"

using namespace QsLogging;

QString g_appDir;
QThread tcpThread;
QThread workThread;

void InitLogger(){
    QString logDir = QString("%1/log").arg(g_appDir);
    QDir().mkdir(logDir);
    QsLogging::Logger& logger = QsLogging::Logger::instance();
    logger.setLoggingLevel(QsLogging::TraceLevel);
    //日志按天输出
    QsLogging::DestinationPtr fileDst(QsLogging::DestinationFactory::MakeFileDestination(logDir,"FmPlugin", 30,QsLogging::EnableLogRotation,
    QsLogging::MaxSizeBytes(10*1024*1024), QsLogging::MaxOldLogCount(50)));
    logger.addDestination(fileDst);
    QsLogging::DestinationPtr consoleDst(QsLogging::DestinationFactory::MakeDebugOutputDestination());
    logger.addDestination(consoleDst);
}

void LoadTheme(const QString& theme)
{
    QString rccPath = QString("%1/skin/%2.rcc").arg(g_appDir).arg(theme);
    if(!QFile(rccPath).exists())
    {
        return;
    }
    QResource::registerResource(rccPath);

    QFile qssFile(QString(":/%1.qss").arg(theme));
    if(!qssFile.open(QFile::ReadOnly))
    {
        return;
    }
    qApp->setStyleSheet(qssFile.readAll());
    qssFile.close();
}

void FixAppEnvirment() {
    QString curEnvPath = QProcessEnvironment::systemEnvironment().value("PATH");
    QString dstEnvPath ;
    dstEnvPath.append(g_appDir);
    dstEnvPath.append(curEnvPath);
    if ( !dstEnvPath.isEmpty() ) {
            QLOG_INFO() << QString("Current path env::%s").arg(dstEnvPath);
    } else {
        QLOG_INFO() << QString("Current path env is empty");
    }
}

int main(int argc, char *argv[])
{
#ifdef Q_OS_WIN
    SetUnhandledExceptionFilter(FMExcpHandler);
#endif
    HANDLE m_hMutex  =  CreateMutex(NULL, FALSE,  L"Global\\PmsPlugin" );
    if(nullptr != m_hMutex){
        if  (GetLastError()  ==  ERROR_ALREADY_EXISTS||GetLastError()  ==  ERROR_ACCESS_DENIED)  {
            CloseHandle(m_hMutex);
            m_hMutex  =  nullptr;
            return  -1;
        }
    }
    else{
        return -1;
    }

    QApplication a(argc, argv);
    g_appDir = a.applicationDirPath();

    // 初始化日志
    InitLogger();

    // 修正环境变量;
    // FixAppEnvirment();

    // 加载主题
    LoadTheme(APP_THEME);

    QLOG_INFO() << QString("[<<<<<<<<<<<<<<<<<<<<---->>>>>>>>>>>>>>>>>>>>>>>>>>]");
    QLOG_INFO() << QString("[<<<<<<<<<<<<<<<<<<--  fmPmsPlugin Start  Version:%1 -->>>>>>>>>>>>>>>>>>>>>>]").arg(APP_VERSION);
    QLOG_INFO() << QString("[<<<<<<<<<<<<<<<<<<<<---->>>>>>>>>>>>>>>>>>>>>>>>>>]");

    // 将控制器移到工作线程
    FlowControl::GetInstance().moveToThread(&workThread);
    workThread.start();

    // 等插件正常登录成功后,才能发起 长连接业务;
    SocketCommunicate  sockCommunicate;
    sockCommunicate.moveToThread(&tcpThread, true);

    FloatForm f;
    MainForm w;
    bool connectRet = false;
    qRegisterMetaType<AlertForm::Type>("AlertForm::Type");

    QObject::connect(&w, &MainForm::showFloatForm, &f, &FloatForm::onShow);
    QObject::connect(&w, &MainForm::hideFloatForm, &f, &FloatForm::onHide);

    QObject::connect(&FlowControl::GetInstance(), &FlowControl::startRemind, &f, &FloatForm::onStartRemind);

    QObject::connect(&FlowControl::GetInstance(), &FlowControl::doHideMainShowFloatFrom, &w, &MainForm::on_mainBtnHide_clicked);
    connectRet = QObject::connect(&FlowControl::GetInstance(), &FlowControl::showAlert, &w, &MainForm::onShowAlert);
    if(!connectRet){
        QLOG_INFO() << QString("Connect FlowControl::showAlert to MainForm::onShowAlert Failed");
    }
    connectRet = QObject::connect(&FlowControl::GetInstance(), &FlowControl::setStoreInfo, &w, &MainForm::onSetStoreInfo);
    if(!connectRet){
        QLOG_INFO() << QString("Connect FlowControl::setStoreInfo to MainForm::onSetStoreInfo Failed");
    }
    connectRet = QObject::connect(&FlowControl::GetInstance(), &FlowControl::setCashierInfo, &w, &MainForm::onSetCashierInfo);
    if(!connectRet){
        QLOG_INFO() << QString("Connect FlowControl::setCashierInfo to MainForm::onSetCashierInfo Failed");
    }

    QObject::connect(&FlowControl::GetInstance(), &FlowControl::doLockFloatForm, &f, &FloatForm::onLockFloatForm);
    QObject::connect(&FlowControl::GetInstance(), &FlowControl::doUnLockFloatFrom, &f, &FloatForm::onUnLockFloatForm);
    QObject::connect(&FlowControl::GetInstance(), &FlowControl::doUpdateStoreStatus, &f, &FloatForm::onUpdateStoreStatus);
    QObject::connect(&w, &MainForm::startRemind, &f, &FloatForm::onStartRemind);
    QObject::connect(&w, &MainForm::stopRemind, &f, &FloatForm::onStopRemind);
    QObject::connect(&f, &FloatForm::showMainForm, &w, &MainForm::show);

    // 跨线程 连接 信号与槽， 需要使用 Qt::QueuedConnection 属性;
    QObject::connect(&FlowControl::GetInstance(), &FlowControl::doLoginSuccess,
                     &sockCommunicate,&SocketCommunicate::onFlowControlLoginSuccess, Qt::DirectConnection);
    QObject::connect(&sockCommunicate, &SocketCommunicate::showAlert, &w, &MainForm::onShowAlert);

    w.MyShow();

    return a.exec();
}
