#include <QMessageBox>
#include <QThread>
#include "instructorsandtraineeswidget.h"
#include "ui_instructorsandtraineeswidget.h"
#include "dialogauthorizationinstructor.h"
#include "dialogsettings.h"


const QString InstructorsAndTraineesWidget::languageENG = "en_EN";
const QString InstructorsAndTraineesWidget::languageRUS = "ru_RU";


InstructorsAndTraineesWidget::InstructorsAndTraineesWidget(QWidget *parent) :
    QWidget(parent),    
    connectorToServer(nullptr),
    viewerTrainees(nullptr),
    viewerInstructors(nullptr),
    messangerWidget(nullptr),
    messangerController(nullptr),
    adminMode(false),
    loginInstructorLoggedInLocal(QStringLiteral("")),
    nameInstructorLoggedInLocal(QStringLiteral("")),
    idInstructorLoggedInLocal("0"),
    language(languageENG),
    ui(new Ui::InstructorsAndTraineesWidget)
{
    ui->setupUi(this);

    ui->widget_Control->setObjectName("widgetControl");

    registerMetaType();

    qDebug() << "InstructorsAndTraineesWidget init thread ID " << QThread::currentThreadId();

    updateMyStyleSheet();

    setLanguageInterfase();

    connectorToServer = new ConnectorToServer(this);
    connect(connectorToServer, &ConnectorToServer::sigLoginResult, this, &InstructorsAndTraineesWidget::slot_checkLoginResult);
    connect(connectorToServer, &ConnectorToServer::sigDeLoginResult, this, &InstructorsAndTraineesWidget::slot_checkDeLoginResult);

    messangerController = new MessangerController(connectorToServer, this);

    viewerTrainees = new ViewerTrainees(connectorToServer, messangerController, this);
    viewerInstructors = new ViewerInstructors(connectorToServer, this);
    connect(this, &InstructorsAndTraineesWidget::signal_NeedUpdateUI, viewerTrainees, &ViewerTrainees::slot_NeedUpdateUI);
    connect(this, &InstructorsAndTraineesWidget::signal_NeedUpdateUI, viewerInstructors, &ViewerInstructors::slot_NeedUpdateUI);
    connect(viewerInstructors, &ViewerInstructors::signal_BlockAutorization, this, &InstructorsAndTraineesWidget::signal_BlockAutorization);
    connect(viewerTrainees, &ViewerTrainees::signal_BlockAutorization, this, &InstructorsAndTraineesWidget::signal_BlockAutorization);

    connect(connectorToServer, &ConnectorToServer::signal_ConnectedToServer, this, &InstructorsAndTraineesWidget::slot_ConnectedToServer);

    connect(viewerTrainees, &ViewerTrainees::signal_traineeSelected, this, &InstructorsAndTraineesWidget::slot_traineeSelected);
    connect(viewerInstructors, &ViewerInstructors::signal_instructorSelected, this, &InstructorsAndTraineesWidget::slot_instructorSelected);

    viewerTrainees->clearSelection();
    viewerInstructors->clearSelection();

    //Размещение
    ui->verticalLayout_Trainees->addWidget(viewerTrainees);
    ui->verticalLayout_Instructors->addWidget(viewerInstructors);

    ui->groupBox_Messenger->setMinimumHeight(900);

    ui->groupBox_Messenger->setMaximumWidth(500);
    ui->groupBox_Messenger->setMinimumWidth(500);

    ui->groupBox_Instructors->setMinimumHeight(300);
    ui->groupBox_Instructors->setMaximumHeight(300);

    ui->groupBox_Trainees->setMinimumHeight(600);

    ui->groupBox_Trainees->setMinimumWidth(600);
    ui->groupBox_Instructors->setMinimumWidth(600);


    //Доступность кнопок
    ui->btnAuthorizationInstructor->setEnabled(false);
    ui->btnEditorTrainees->setEnabled(false);
    ui->btnEditorInstructors->setEnabled(false);
}

InstructorsAndTraineesWidget::~InstructorsAndTraineesWidget()
{
    if(authorizationIsCompleted())
        deAuthorizationInstructor(loginInstructorLoggedInLocal);

    delete messangerController;
    delete viewerInstructors;
    delete viewerTrainees;
    delete connectorToServer;
    delete ui;
}

QString InstructorsAndTraineesWidget::getLanguage()
{
    return language;
}

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

        updateLabelLoggedInInstructor(loginInstructorLoggedInLocal, nameInstructorLoggedInLocal);
        updateLabelServer();
    }
}

void InstructorsAndTraineesWidget::updateMyStyleSheet()
{
    QString styleSheet = loadStyleSheet();
    styleSheet = styleSheet.replace("\n", "");

    this->setStyleSheet(styleSheet);
}

QString InstructorsAndTraineesWidget::loadStyleSheet()
{
    QString fileName = "./resources/css/styleSheetMain.css";
    QFile styleSheetFile(fileName);
    if (!styleSheetFile.open(QFile::ReadOnly | QFile::Text))
    {
        QMessageBox::critical(this, tr("Attention!"), tr("The file could not be opened ") + fileName);
        return QStringLiteral("");
    }
    else
    {
        QByteArray byteArray = styleSheetFile.readAll();
        styleSheetFile.close();

        QString style = byteArray;
        return style;
    }
}

void InstructorsAndTraineesWidget::slot_LanguageChanged(QString language)
{
    qtLanguageTranslator.load(QString(QStringLiteral("translations/InstructorsAndTraineesWidget_")) + language, QStringLiteral("."));
    qApp->installTranslator(&qtLanguageTranslator);

    emit signal_LanguageChanged(language);
}

void InstructorsAndTraineesWidget::slot_UpdateStyleSheet()
{
    updateMyStyleSheet();
}

void InstructorsAndTraineesWidget::slot_checkLoginResult(ServerAuthorization *serverAuth)
{
    if (serverAuth->Result)
    {
        loginInstructorLoggedInLocal = serverAuth->Login;
        nameInstructorLoggedInLocal = serverAuth->ClientName;
        idInstructorLoggedInLocal = serverAuth->Id;

        if(loginInstructorLoggedInLocal == QStringLiteral("admin"))
            adminMode = true;
        else
            adminMode = false;

        viewerInstructors->setAdminMode(adminMode);
        viewerTrainees->setAdminMode(adminMode);
        viewerInstructors->setAuthComplited(true);
        viewerTrainees->setAuthComplited(true);

        ui->btnEditorTrainees->setEnabled(true);
        if(adminMode)
            ui->btnEditorInstructors->setEnabled(true);

        emit signal_NeedUpdateUI(true, true);

        updateLabelLoggedInInstructor(serverAuth->Login, serverAuth->ClientName);
        connectorToServer->setLoginName(nameInstructorLoggedInLocal);

        messangerController->setGUIclientId(serverAuth->Id);

        connectorToServer->sendQueryTasksXML("fim");
        connectorToServer->sendQueryTasksXML("amm");
        //QMessageBox::information(this, tr("Instructor authorization"), tr("Successfully!"));
    }
    else
    {
        ui->btnAuthorizationInstructor->setChecked(false);
        QMessageBox::warning(this, tr("Instructor authorization"), tr("Invalid login or password!"));
    }
}

void InstructorsAndTraineesWidget::slot_checkDeLoginResult(ServerDeAuthorization *serverDeAuth)
{
    if (serverDeAuth->Result)
    {
        loginInstructorLoggedInLocal = QStringLiteral("");
        nameInstructorLoggedInLocal = QStringLiteral("");
        adminMode = false;

        viewerInstructors->setAdminMode(adminMode);
        viewerTrainees->setAdminMode(adminMode);
        viewerInstructors->setAuthComplited(false);
        viewerTrainees->setAuthComplited(false);

        ui->btnEditorTrainees->setEnabled(false);
        ui->btnEditorInstructors->setEnabled(false);

        updateLabelLoggedInInstructor("","");
        //QMessageBox::information(this, tr("Instructor deauthorization"), tr("Successfully!"));
    }
    else
    {
        ui->btnAuthorizationInstructor->setChecked(true);
        QMessageBox::warning(this, tr("Instructor deauthorization"), tr("Error!"));
    }
}

void InstructorsAndTraineesWidget::slot_ConnectedToServer(bool state)
{
    if(state)
    {//Сервер подключен
        ui->btnConnectionToServer->setEnabled(false);
        ui->btnAuthorizationInstructor->setEnabled(true);

        ui->lblDBisConnected->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGreen.png")));

        updateLabelLoggedInInstructor(loginInstructorLoggedInLocal, nameInstructorLoggedInLocal);
        updateLabelServer();
    }
    else
    {//Сервер отключен
        ui->btnConnectionToServer->setEnabled(true);
        ui->btnAuthorizationInstructor->setEnabled(false);
        ui->btnAuthorizationInstructor->setChecked(false);
        ui->lblDBisConnected->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGray.png")));

        viewerInstructors->setAuthComplited(false);
        viewerTrainees->setAuthComplited(false);

        ui->btnEditorTrainees->setEnabled(false);
        ui->btnEditorInstructors->setEnabled(false);

        viewerTrainees->deactivate();
        viewerInstructors->deactivate();

        messangerController->deleteAllWidgets();

        loginInstructorLoggedInLocal = "";
        nameInstructorLoggedInLocal = "";

        updateLabelLoggedInInstructor(loginInstructorLoggedInLocal, nameInstructorLoggedInLocal);
        updateLabelServer();

        QMessageBox::warning(this, tr("Warning!"), tr("The server is not available"));
    }
}

void InstructorsAndTraineesWidget::slot_traineeSelected(int id_trainee)
{
    viewerInstructors->clearSelection();

    /*Messanger*/
    messangerController->deleteWidget(messangerWidget);
    if(id_trainee)
    {
        Trainee trainee = connectorToServer->getTrainee(id_trainee);
        if(trainee.getID())
            messangerWidget = messangerController->newWidget(this, &trainee, ui->verticalLayout_Messenger);
    }
}

void InstructorsAndTraineesWidget::slot_instructorSelected(int id_instructor)
{
    viewerTrainees->clearSelection();

    /*Messanger*/
    messangerController->deleteWidget(messangerWidget);
    if(id_instructor && id_instructor != idInstructorLoggedInLocal.toInt())
    {
        Instructor instructor = connectorToServer->getInstructor(id_instructor);
        if(instructor.getID())
            messangerWidget = messangerController->newWidget(this, &instructor, ui->verticalLayout_Messenger);
    }
}

bool InstructorsAndTraineesWidget::authorizationInstructorDialog(QWidget* parent)
{
    DialogAuthorizationInstructor dlg(parent);
    dlg.setWindowTitle(tr("Instructor authorization"));

    do
    {
        switch( dlg.exec() )
        {
        case QDialog::Accepted:
        {
            QString login = dlg.getLogin();
            QString password = dlg.getPassword();

            connectorToServer->authorizationInstructorLocal(login, password);

            return true;
        }
        case QDialog::Rejected:
            return false;
        default:
            return false;
        }
    }
    while(true);

    return false;
}

bool InstructorsAndTraineesWidget::deAuthorizationInstructor(QString login)
{
    connectorToServer->deAuthorizationInstructorLocal(login);
    return true;
}

bool InstructorsAndTraineesWidget::authorizationIsCompleted()
{
    if(loginInstructorLoggedInLocal == QStringLiteral(""))
        return false;
    else
        return true;
}

void InstructorsAndTraineesWidget::on_btnConnectionToServer_clicked()
{
    connectorToServer->SetConnectToServer();
}

void InstructorsAndTraineesWidget::on_btnAuthorizationInstructor_clicked()
{
    bool stateIsChecked = ui->btnAuthorizationInstructor->isChecked();

    if(stateIsChecked)
    {//Авторизация Инструктора локальная (Администратора)
        if(authorizationInstructorDialog(this))
        {
            connect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerInstructors,&ViewerInstructors::slot_NeedUpdateUI);
            connect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerTrainees,&ViewerTrainees::slot_NeedUpdateUI);
            connect(connectorToServer,&ConnectorToServer::signal_reInitMessangerByUsers,messangerController,&MessangerController::slot_reinitMessangers);
        }
        else
            ui->btnAuthorizationInstructor->setChecked(false);
    }
    else
    {//ДеАвторизация Инструктора локальная (Администратора)
        if(authorizationIsCompleted())
        {
            if(deAuthorizationInstructor(loginInstructorLoggedInLocal))
            {
                disconnect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerInstructors,&ViewerInstructors::slot_NeedUpdateUI);
                disconnect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerTrainees,&ViewerTrainees::slot_NeedUpdateUI);
                disconnect(connectorToServer,&ConnectorToServer::signal_reInitMessangerByUsers,messangerController,&MessangerController::slot_reinitMessangers);

                viewerTrainees->deactivate();
                viewerInstructors->deactivate();

                messangerController->deleteAllWidgets();
            }
            else
                ui->btnAuthorizationInstructor->setChecked(true);
        }
    }
}

void InstructorsAndTraineesWidget::updateLabelLoggedInInstructor(QString login, QString name)
{
    if(authorizationIsCompleted())
    {
        QString nameLoggedInInstructor = QString("%1 (%2)").arg(name, login);
        ui->lblLoggedInInstructor->setText(nameLoggedInInstructor);
        if(loginInstructorLoggedInLocal == QStringLiteral("admin"))
            ui->lblLoggedIn->setPixmap(QPixmap(QStringLiteral(":/resources/icons/admin.png")));
        else
            ui->lblLoggedIn->setPixmap(QPixmap(QStringLiteral(":/resources/icons/instructor.png")));
    }
    else
    {
        ui->lblLoggedInInstructor->setText(tr("none"));
        ui->lblLoggedIn->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGray.png")));
    }
}

void InstructorsAndTraineesWidget::updateLabelServer()
{
    if(!connectorToServer)
        return;

    if(connectorToServer->getIsConnected())
    {
        ServerSettings serverSettings = connectorToServer->getServerSettings();
        ui->lblServer->setText(serverSettings.Address + " : " +serverSettings.Port);
    }
    else
        ui->lblServer->setText(tr("none"));
}

void InstructorsAndTraineesWidget::setLanguageInterfase()
{
    ServerSettings settings;
    DialogSettings::loadSettings(&settings);

    if(settings.Language == "ENG")
    {
        qtLanguageTranslator.load(QString("translations/InstructorsAndTraineesWidget_") + languageENG, ".");
        language = languageENG;
    }
    else
    {
        qtLanguageTranslator.load(QString("translations/InstructorsAndTraineesWidget_") + languageRUS, ".");
        language = languageRUS;
    }

    qApp->installTranslator(&qtLanguageTranslator);

    emit signal_LanguageChanged(language);
}

void InstructorsAndTraineesWidget::on_btnSettings_clicked()
{
    DialogSettings dlg(connectorToServer, (loginInstructorLoggedInLocal != ""), this);

    connect(&dlg, &DialogSettings::signal_LanguageChanged, this, &InstructorsAndTraineesWidget::slot_LanguageChanged);
    connect(&dlg, &DialogSettings::signal_UpdateStyleSheet, this, &InstructorsAndTraineesWidget::slot_UpdateStyleSheet);


    switch( dlg.exec() )
    {
    case QDialog::Accepted:
    {
        language = dlg.getSettings().Language;

        if(dlg.settingsServerIsChanged())
        {
            QMessageBox::warning(this, tr("Attention!"), tr("Server settings have been changed. Please reconnect to the server."));

            if(authorizationIsCompleted())
                deAuthorizationInstructor(loginInstructorLoggedInLocal);

            connectorToServer->StopConnectToServer();
        }

        break;
    }
    case QDialog::Rejected:
        break;
    default:
        break;
    }    
}

void InstructorsAndTraineesWidget::on_btnEditorTrainees_clicked()
{
    this->viewerTrainees->on_btnEditorTrainees_clicked();
}

void InstructorsAndTraineesWidget::on_btnEditorInstructors_clicked()
{
    this->viewerInstructors->on_btnEditorInstructors_clicked();
}
