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


ServerLMSWidget::ServerLMSWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ServerLMSWidget),
    tcpServer(nullptr),
    hostPort(6000),
    stateServer(stoped),
    stateBlockAutorization(unblocked),
    updateThread(nullptr),
    loggerThread(nullptr),
    dataParser(nullptr),
    processingSystem(nullptr),
    updateController(nullptr),
    logger(nullptr),
    providerDBLMS(nullptr)
{
    ui->setupUi(this);

    qRegisterMetaType<PacketType>("PacketType");

    ui->comboTasks->addItem("Задача 1");
    ui->comboTasks->addItem("Задача 2");
    ui->comboTasks->addItem("Задача 3");
    ui->comboTasks->addItem("Задача 4");
    ui->comboTasks->addItem("Задача 5");

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

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

    updateThread = new QThread;
    loggerThread = new QThread;

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

    logger = new Logger(ui->listWidgetLogger);

    connect(providerDBLMS, &ProviderDBLMS::signal_BlockAutorization, this, &ServerLMSWidget::slot_BlockAutorization);
    connect(logger,&Logger::sigSendTextToLogger,this,&ServerLMSWidget::slotAddToLog,Qt::AutoConnection);

    logger->moveToThread(loggerThread);

    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;

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

    commonClientHandler->initialize(&clientsMap,processingSystem,dataParser,logger);
    processingSystem->initialize(this,dataParser,commonClientHandler,logger,updateController);

    logger->setTypeLog("widget");


    connect(dataParser,&DataParser::sigLogMessage,logger,&Logger::addTextToLogger);

    connect(this,&ServerLMSWidget::sigUpdateController,updateController,&UpdateController::initialize,Qt::DirectConnection);
    connect(this,&ServerLMSWidget::sigLog,logger,&Logger::addTextToLogger,Qt::AutoConnection);
    connect(this,&ServerLMSWidget::sigCalculateFullHash,updateController,&UpdateController::calculateFullHash,Qt::AutoConnection);

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

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

void ServerLMSWidget::autorizationHandler(QString login)
{
    //Отмена авторизации в БД

    if(providerDBLMS->deAuthorizationTrainee(login))
    {//Деавторизовался обучаемый

    }
    else  if(providerDBLMS->deAuthorizationInstructor(login))
    {//Деавторизовался инструктор

    }
}

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

bool ServerLMSWidget::startServer()
{
    if(stateServer == stoped)
    {
        tcpServer = new MultiThreadServer(this,updateController,dataParser,logger);

        //connect(tcpServer, &QTcpServer::newConnection, this, &ServerLMSWidget::slotNewConnection,Qt::AutoConnection);

        if(!tcpServer->listen(QHostAddress::Any, hostPort))
        {
            logger->addTextToLogger("SERVER: start ERROR");
            stateServer = stoped;
            return false;
        }
        else
        {
            logger->addTextToLogger("SERVER: start OK");
            stateServer = started;
            return true;
        }
    }
    else
        return false;
}

bool ServerLMSWidget::stopServer()
{
    if(stateServer == started)
    {
        QByteArray arrayAnswer = dataParser->ClientAnswer()->notify(NOTIFY_SERVER_END);

        //Закрываем все открытые сокеты
        foreach(int idSocket, clientsMap.keys())
        {
            clientsMap[idSocket]->sigSocketWrite(arrayAnswer);
            //while (!clientsMap[idSocket]->sigSocketFlush()) {}

            QString str = QString(arrayAnswer);
            emit sigLog("To Client: " + str);

            //slotDisconnectClient(clientsMap[idSocket]->get, QString peerPort)
            autorizationHandler(clientsMap[idSocket]->getClient()->getLogin());

            clientsMap[idSocket]->sigSocketClose();
            //clientsMap.remove(idSocket);
            removeClient(idSocket);
        }

        //Закрываем сервер
        tcpServer->close();
        stateServer = stoped;
        delete tcpServer;
        emit sigLog("Server is stopped");
        return true;
    }
    else
        return false;
}

Logger *ServerLMSWidget::getLogger() const
{
    return logger;
}

QMap<int, ClientHandler *> ServerLMSWidget::getClientsMap() const
{
    return clientsMap;
}

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

    //Проходим все открытые сокеты
    foreach(int idSocket, clientsMap.keys())
    {
        //Добавляем в список Клиентов
        QString strClient = clientsMap[idSocket]->getClient()->getFullName();

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

    int countClients = clientsMap.count();
    emit sigLog("SERVER: countClients = " + QString::number(countClients));
}

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

void ServerLMSWidget::removeClient(int idSocket)
{
    clientsMap.remove(idSocket);
    slotUpdateListClients();
}

void ServerLMSWidget::addClient(qintptr descriptor, ClientHandler *client)
{
    clientsMap[descriptor] = client;
    slotUpdateListClients();
}

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


void ServerLMSWidget::on_btnTaskSet_clicked()
{
    QString fullNameClient = ui->listWidget_Clients->currentItem()->text();
    QString textTask = ui->comboTasks->currentText();

    commonClientHandler->slot_sendTaskToClient(fullNameClient,textTask);
}

void ServerLMSWidget::slotAddToLog(QString msg)
{
    ui->listWidgetLogger->addItem(msg);
    ui->listWidgetLogger->scrollToBottom();
}


void ServerLMSWidget::on_btnStartServer_clicked()
{
    if(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(stopServer())
    {
        ui->btnStopServer->setEnabled(false);
        ui->btnStartServer->setEnabled(true);
        ui->lblOnOff->setPixmap(QPixmap(QStringLiteral(":/resources/icons/switchOff.png")));
    }
}

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