#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QXmlStreamAttribute>
#include <QFile>
#include <QMessageBox>
#include <QThread>
#include <QErrorMessage>
#include "serverlmswidget.h"
#include "ui_serverlmswidget.h"

ServerLMSWidget::ServerLMSWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ServerLMSWidget),
    server(nullptr),
    updateThread(nullptr),
    loggerThread(nullptr),
    dataParser(nullptr),
    processingSystem(nullptr),
    updateController(nullptr),
    providerDBLMS(nullptr)
{
    ui->setupUi(this);
    mutex = new QMutex;

    qRegisterMetaType<PacketType>("PacketType");
    qRegisterMetaType<UserType>("UserType");
    qRegisterMetaType<LogLevel>("LogLevel");
    errorCode = 0;

    ui->btnStopServer->setEnabled(false);
    ui->btnStartServer->setEnabled(true);

    // Сделаем первоначальную инициализацию перевода для окна виджета
    //qtLanguageTranslator.load(QString("translations/ServerLMS_") + QString("en_EN"), ".");
    //qApp->installTranslator(&qtLanguageTranslator);

    updateThread = new QThread;
    loggerThread = new QThread;

    providerDBLMS = new ProviderDBLMS(this);
    providerDBLMS->ConnectionToDB();
    providerDBLMS->deAuthorizationAll();

    chatSystem = new ChatSystem();

    connect(providerDBLMS, &ProviderDBLMS::signal_BlockAutorization, this, &ServerLMSWidget::slot_BlockAutorization);

    assetsManager = new AssetsManager;
    assetsManager->moveToThread(updateThread);

    updateController = new UpdateController;
    updateController->moveToThread(updateThread);

    processingSystem = new ProcessingSystem(providerDBLMS, updateController);
    //processingSystem->moveToThread(updateThread);

    dataParser = new DataParser(assetsManager,processingSystem);

    commonClientHandler = new CommonClientHandler;
    server = new MultiThreadServer(this,updateController,processingSystem,dataParser,6000);

    loggerThread->start();
    updateThread->start();

    commonClientHandler->initialize(server->getClientsMap(),processingSystem,dataParser);
    processingSystem->initialize(server,dataParser,commonClientHandler,updateController,chatSystem);
    chatSystem->initialize(commonClientHandler,dataParser,server->getClientsMap());

    Logger::instance().moveToThread(loggerThread);
    Logger::instance().setLoggingType(LoggingType::WIDGET);
    Logger::instance().setLogToFile(true);

    connect(this,&ServerLMSWidget::sigUpdateController,updateController,&UpdateController::initialize,Qt::DirectConnection);
    connect(this,&ServerLMSWidget::sigCalculateFullHash,updateController,&UpdateController::calculateFullHash,Qt::AutoConnection);
    connect(updateController,&UpdateController::sigErrorRequired,this,&ServerLMSWidget::setError);
    connect(&Logger::instance(),&Logger::sigLogToWidget,this, &ServerLMSWidget::addToLog,Qt::QueuedConnection);

    emit sigUpdateController(commonClientHandler,dataParser,assetsManager);
    on_btnStartServer_clicked();

    first = true;
    qDebug() << "MAIN THREAD: " << QThread::currentThreadId();
}

void ServerLMSWidget::setError(int code)
{
    errorCode = code;
}

ServerLMSWidget::~ServerLMSWidget()
{
    server->stopServer();
    updateThread->exit();
    loggerThread->exit();
    delete ui;
}


void ServerLMSWidget::slotUpdateListClients()
{
    //Очищаем список
    ui->listWidget_Clients->clear();

    for (const ClientHandler *handler : server->getClientsMap()->values())
    {
        QString strClient = handler->getClient()->getFullName();

        ui->listWidget_Clients->addItem(strClient);
        ui->listWidget_Clients->scrollToBottom();
        ui->listWidget_Clients->setCurrentRow(ui->listWidget_Clients->count() - 1);
    }

    int countClients = (*server->getClientsMap()).count();
    Logger::instance().log("SERVER: countClients = " + QString::number(countClients));
}

void ServerLMSWidget::addToLog(QString message)
{
    ui->loggerTextField->appendPlainText(message);
}

void ServerLMSWidget::slot_BlockAutorization(bool block)
{
    if(block)
        server->blockAutorization();
    else
        server->unBlockAutorization();
}

void ServerLMSWidget::slot_LanguageChanged(QString language)
{
    qtLanguageTranslator.load(QString("translations/ServerLMS_") + language, ".");
    qApp->installTranslator(&qtLanguageTranslator);
}

void ServerLMSWidget::on_btnStartServer_clicked()
{
    if(server->startServer())
    {
        QApplication::setOverrideCursor(Qt::WaitCursor);
        QApplication::restoreOverrideCursor();

        ui->btnStartServer->setEnabled(false);
        ui->btnStopServer->setEnabled(true);
        ui->lblOnOff->setPixmap(QPixmap(QStringLiteral(":/resources/icons/switchOn.png")));
    }
}

void ServerLMSWidget::on_btnStopServer_clicked()
{
    if(server->stopServer())
    {
        ui->btnStopServer->setEnabled(false);
        ui->btnStartServer->setEnabled(true);
        ui->lblOnOff->setPixmap(QPixmap(QStringLiteral(":/resources/icons/switchOff.png")));
    }
}

QMutex *ServerLMSWidget::getMutex() const
{
    return mutex;
}

void ServerLMSWidget::changeEvent(QEvent *event)
{
    // В случае получения события изменения языка приложения
    if (event->type() == QEvent::LanguageChange)
    {
        ui->retranslateUi(this);    // переведём окно заново
    }
}
