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

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

    ui->btnUpdateStyleSheet->setObjectName("btnUpdateStyleSheet");

    qRegisterMetaType<PacketType>("PacketType");
    qRegisterMetaType<QList<Instructor>>("QList<Instructor>");
    qRegisterMetaType<QList<Trainee>>("QList<Trainee>");
    qRegisterMetaType<QList<Group>>("QList<Group>");
    qRegisterMetaType<QList<Computer>>("QList<Computer>");
    qRegisterMetaType<QList<Classroom>>("QList<Classroom>");
    qRegisterMetaType<QList<Module*>>("QList<Module*>");
    qRegisterMetaType<QList<QTreeWidgetItem*>>("QList<QTreeWidgetItem*>");

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

    connectorToServer = new ConnectorToServer(this);
    connect(connectorToServer,&ConnectorToServer::sigLoginResult,this,&InstructorsAndTraineesWidget::checkLoginResult);
    connect(connectorToServer,&ConnectorToServer::sigDeLoginResult,this,&InstructorsAndTraineesWidget::checkDeLoginResult);

    viewerTrainees = new ViewerTrainees(connectorToServer, 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_UpdateDB,viewerInstructors,&ViewerInstructors::slot_NeedUpdateUI);
    //connect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerTrainees,&ViewerTrainees::slot_NeedUpdateUI);

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

    ammTasksWidget = new AMMtasksWidget(connectorToServer, AMMtasksWidget::TypeList::listCommon, this);
    fimTasksWidget = new FIMtasksWidget(connectorToServer, FIMtasksWidget::TypeList::listForTrainee, this);

    connect(connectorToServer, &ConnectorToServer::signal_UpdateTasksFIM, fimTasksWidget, &FIMtasksWidget::slot_NeedUpdateUI);
    connect(connectorToServer, &ConnectorToServer::signal_UpdateTasksAMM, ammTasksWidget, &AMMtasksWidget::slot_NeedUpdateUI);
    connect(viewerTrainees, &ViewerTrainees::signal_traineeSelected, fimTasksWidget, &FIMtasksWidget::slot_traineeSelected);
    connect(viewerTrainees, &ViewerTrainees::signal_traineeSelected, ammTasksWidget, &AMMtasksWidget::slot_traineeSelected);

    messangerWidget = new MessangerWidget(this);
    //connect(connectorToServer,&ConnectorToServer::signal_InitMessanger,messangerWidget,&MessangerWidget::slot_InitMessanger);
    connect(viewerTrainees, &ViewerTrainees::signal_traineeSelected, messangerWidget, &MessangerWidget::slot_traineeSelected);
    connect(messangerWidget, &MessangerWidget::signal_tabMessengerChanged, viewerTrainees, &ViewerTrainees::slot_tabMessengerChanged);
    connect(messangerWidget, &MessangerWidget::signal_msgToClientReady, connectorToServer, &ConnectorToServer::slot_msgToClientReady);
    connect(connectorToServer,&ConnectorToServer::signal_msgFromClientReady,messangerWidget,&MessangerWidget::slot_msgFromClientReady);


    ui->horizontalLayout_3->addWidget(viewerTrainees);

    QWidget* wGB2 = new QWidget(this);
    QHBoxLayout* lGB2 = new QHBoxLayout(this);
    wGB2->setLayout(lGB2);
    lGB2->addWidget(ui->groupBox_2);
    ui->horizontalLayout_3->addWidget(wGB2);

    ui->verticalLayout_41->addWidget(ammTasksWidget);
    ui->verticalLayout_42->addWidget(fimTasksWidget);

    ui->verticalLayout_2->addWidget(messangerWidget);

    ui->verticalLayout_2->addWidget(viewerInstructors);

    ui->btnSetVersion->hide();

    viewerTrainees->setMinimumSize(500, 500);
    viewerTrainees->setMaximumWidth(1050);

    wGB2->setMinimumSize(500, 500);
    //wGB2->setMaximumWidth(1050);

    viewerInstructors->setMinimumSize(400, 400);
    viewerInstructors->setMaximumWidth(500);
    viewerInstructors->setMaximumHeight(400);

    messangerWidget->setMinimumSize(500, 500);
    messangerWidget->setMaximumWidth(500);    

    //ui->btnAuthorizationInstructor->setEnabled(false);

    updateMyStyleSheet();
}

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

    delete ammTasksWidget;
    delete fimTasksWidget;
    delete messangerWidget;
    delete viewerInstructors;
    delete viewerTrainees;
    delete connectorToServer;
    delete ui;
}

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

        if(ui->btnAuthorizationInstructor->isChecked())
            ui->btnAuthorizationInstructor->setText(tr("Deauthorization Instructor"));
        else
            ui->btnAuthorizationInstructor->setText(tr("Authorization Instructor"));

        /*
        if(ui->btnConnectionToDB->isChecked())
            ui->btnConnectionToDB->setText(tr("Disconnection DB"));
        else
            ui->btnConnectionToDB->setText(tr("Connection DB"));
            */

        updateLabelLoggedInInstructor(loginInstructorLoggedInLocal, nameInstructorLoggedInLocal);
    }
}

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

    this->setStyleSheet(styleSheet);
}

QString InstructorsAndTraineesWidget::loadStyleSheet()
{
    //QString fileName = ":/resources/css/styleSheetMain.css";
    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);

    Q_EMIT signal_LanguageChanged(language);
}

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

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

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

        Q_EMIT signal_NeedUpdateUI(true, true);
        ui->btnSetVersion->show();
        ui->btnAuthorizationInstructor->setText(tr("Deauthorization Instructor"));

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

        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::checkDeLoginResult(ServerDeAuthorization *serverDeAuth)
{
    if (serverDeAuth->Result)
    {
        loginInstructorLoggedInLocal = QStringLiteral("");
        nameInstructorLoggedInLocal = QStringLiteral("");
        adminMode = false;

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

        //Q_EMIT signal_NeedUpdateUI(true, false);

        ui->btnAuthorizationInstructor->setText(tr("Authorization Instructor"));
        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")));
    }
    else
    {//Сервер отключен
        ui->btnConnectionToServer->setEnabled(true);
        ui->btnAuthorizationInstructor->setEnabled(false);
        ui->btnAuthorizationInstructor->setText(tr("Authorization Instructor"));
        ui->btnAuthorizationInstructor->setChecked(false);
        ui->btnSetVersion->hide();
        ui->lblDBisConnected->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGray.png")));

        viewerTrainees->clearTree();
        viewerInstructors->clearTree();

        ammTasksWidget->clearTree();
        fimTasksWidget->clearTree();

        messangerWidget->clear();
    }
}

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_InitMessanger,messangerWidget,&MessangerWidget::slot_InitMessanger);
        }
        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_InitMessanger,messangerWidget,&MessangerWidget::slot_InitMessanger);

                viewerTrainees->clearTree();
                viewerInstructors->clearTree();

                ammTasksWidget->clearTree();
                fimTasksWidget->clearTree();

                messangerWidget->clear();
            }
            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::on_btnUpdateStyleSheet_clicked()
{
    updateMyStyleSheet();
}

void InstructorsAndTraineesWidget::on_btnSetVersion_clicked()
{
    connectorToServer->showVersionSelect();
}
