#include <QMessageBox>
#include "editortrainees.h"
#include "ui_editortrainees.h"
#include "dialogeditgroup.h"
#include "dialogedittrainee.h"

EditorTrainees::EditorTrainees(ConnectorToServer* connectorToServer, bool adminMode, QWidget *parent) :
    TraineesView(connectorToServer, CommonView::TypeView::control, parent),
    ui(new Ui::EditorTrainees)
{
    ui->setupUi(this);

    connect(treeWidget, &QTreeWidget::currentItemChanged, this, &EditorTrainees::on_treeWidget_currentItemChanged);

    ui->verticalLayout_1->addWidget(treeWidget);

    this->adminMode = adminMode;

    preparationTreeWidget();
    //setNotLoggedInVisible(true);
    loadTraineesFromDB();

    if(adminMode)
        ui->btnArchive->click();
}

EditorTrainees::~EditorTrainees()
{
    delete ui;
}

void EditorTrainees::on_btnNewGroup_clicked()
{
    Group group;
    Group group_edit;

    if(editGroup(group, &group_edit))
       connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_NEW_GROUP, 0, &group_edit);

    return;
    /*
    if(int id_group = dbLMS->newGroup())
    {
        loadTraineesFromDB();
        setCurrentGroup(id_group);

        DialogEditGroup dlg(this);

        Group group = dbLMS->getGroup(id_group);
        if(group.getID() == 0)
            return;

        dlg.setGroup(group);

        while (true)
        {
            switch( dlg.exec() )
            {
            case QDialog::Accepted:
            {
                Group group_edit = dlg.getGroup();

                if(int id_edit = dbLMS->editGroup(group_edit))
                {//Отредактировано
                    loadTraineesFromDB();
                    setCurrentGroup(id_edit);
                    return;
                }
                else
                {
                    dlg.setGroup(group_edit);
                    continue;
                }

            }
            case QDialog::Rejected:
                dbLMS->delGroup(id_group);
                loadTraineesFromDB();
                return;
            default:
                dbLMS->delGroup(id_group);
                loadTraineesFromDB();
                return;
            }
        }
    }*/
}

void EditorTrainees::on_btnDeleteGroup_clicked()
{
    QTreeWidgetItem *treeItemCurrent = treeWidget->currentItem();

    if(treeItemCurrent != nullptr)
    {
        QTreeWidgetItem *treeItemParent = treeItemCurrent->parent();
        if(treeItemParent == nullptr)
        {//Выбрана группа
            int id_group = treeItemCurrent->text(ColumnsTreeTrainees::clmn_ID).toInt();

            if(connectorToServer->getListTraineesInGroup(id_group).count() > 0)
            {
                QMessageBox::critical(this, tr("Editing error!"), tr("The group is not empty.\nIt is not possible to delete a non-empty group."));
                return;
            }
            else
            {//Пустая группа
                if(QMessageBox::warning(this, tr("Attention!"), tr("The deletion will be irrevocable.\nDelete anyway?"), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok)
                {
                    connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_DEL_GROUP, id_group);
                }
            }
        }
    }
}

void EditorTrainees::on_btnNewTrainee_clicked()
{
    QTreeWidgetItem *treeItemCurrent = treeWidget->currentItem();

    if(treeItemCurrent != nullptr)
    {
        QTreeWidgetItem *treeItemParent = treeItemCurrent->parent();
        if(treeItemParent == nullptr)
        {//Выбрана группа. Можно добавить Обучаемого
            int id_group = treeItemCurrent->text(ColumnsTreeTrainees::clmn_ID).toInt();

            Trainee trainee;
            Trainee trainee_edit;

            if(editTrainee(trainee, &trainee_edit))
               connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_NEW_TRAINEE, id_group, &trainee_edit);

            return;

            /*
            if(int id_trainee = dbLMS->newTrainee(id_group))
            {
                loadTraineesFromDB();
                setCurrentGroup(id_group);

                DialogEditTrainee dlg(this);

                Trainee trainee = dbLMS->getTrainee(id_trainee);
                if(trainee.getID() == 0)
                    return;

                dlg.setTrainee(trainee);

                while (true)
                {
                    switch( dlg.exec() )
                    {
                    case QDialog::Accepted:
                        {
                            Trainee trainee_edit = dlg.getTrainee();

                            if(int id_edit = dbLMS->editTrainee(trainee_edit))
                            {//Отредактировано
                                loadTraineesFromDB();
                                //setCurrentTrainee(id_edit);
                                setCurrentGroup(id_group);
                                return;
                            }
                            else
                            {
                                dlg.setTrainee(trainee_edit);
                                continue;
                            }

                            break;
                        }
                    case QDialog::Rejected:
                        dbLMS->delTrainee(id_trainee);
                        loadTraineesFromDB();
                        setCurrentGroup(id_group);
                        return;
                    default:
                        dbLMS->delTrainee(id_trainee);
                        loadTraineesFromDB();
                        setCurrentGroup(id_group);
                        return;
                    }
                }
            }*/
        }
    }
}

void EditorTrainees::on_btnDeleteTrainee_clicked()
{
    QTreeWidgetItem *treeItemCurrent = treeWidget->currentItem();

    if(treeItemCurrent != nullptr)
    {
        QTreeWidgetItem *treeItemParent = treeItemCurrent->parent();
        if(treeItemParent != nullptr)
        {//Выбран обучаемый

            int id_trainee = treeItemCurrent->text(ColumnsTreeTrainees::clmn_ID).toInt();
            int id_group = treeItemParent->text(ColumnsTreeTrainees::clmn_ID).toInt();

            if(connectorToServer->isLoggedInTrainee(id_trainee))
            {//Обучаемый залогирован!
                QMessageBox::critical(this, tr("Error!"), tr("You cannot delete a logged-in trainee."));
                return;
            }

            if(QMessageBox::warning(this, tr("Attention!"), tr("The deletion will be irrevocable.\nDelete anyway?"), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok)
            {
                connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_DEL_TRAINEE, id_trainee);
            }
        }
    }
}

void EditorTrainees::on_btnToOrFromArchiveTrainee_clicked()
{
    QTreeWidgetItem *treeItemCurrent = treeWidget->currentItem();

    if(treeItemCurrent != nullptr)
    {
        QTreeWidgetItem *treeItemParent = treeItemCurrent->parent();
        if(treeItemParent != nullptr)
        {//Выбран обучаемый

            int id_trainee = treeItemCurrent->text(ColumnsTreeTrainees::clmn_ID).toInt();

            Trainee trainee = connectorToServer->getTrainee(id_trainee);
            if(trainee.getID() == 0)
                return;

            if(connectorToServer->isArchivedTrainee(id_trainee))
            {//Архивный
                trainee.setArchived(false);
                connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_EDIT_TRAINEE, id_trainee, &trainee);
            }
            else
            {//Не Архивный                
                if(connectorToServer->isLoggedInTrainee(id_trainee))
                {//Обучаемый залогирован!
                    QMessageBox::critical(this, tr("Error!"), tr("You cannot archive a logged-in trainee."));
                    return;
                }

                trainee.setArchived(true);
                connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_EDIT_TRAINEE, id_trainee, &trainee);
                if(!archiveVisible)
                    ui->btnArchive->click();
            }
        }
    }
}

void EditorTrainees::on_btnEdit_clicked()
{
    QTreeWidgetItem *treeItemCurrent = treeWidget->currentItem();

    if(treeItemCurrent == nullptr)
        return;

    QTreeWidgetItem *treeItemParent = treeItemCurrent->parent();
    if(treeItemParent == nullptr)
    {//Выбрана группа

        int id_group = treeItemCurrent->text(ColumnsTreeTrainees::clmn_ID).toInt();

        Group group = connectorToServer->getGroup(id_group);
        if(group.getID() == 0)
            return;

        Group group_edit;

        if(editGroup(group, &group_edit))
            connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_EDIT_GROUP, id_group, &group_edit);
    }
    else
    {//Выбран обучаемый

        int id_trainee = treeItemCurrent->text(ColumnsTreeTrainees::clmn_ID).toInt();

        if(connectorToServer->isLoggedInTrainee(id_trainee))
        {//Обучаемый залогирован!
            QMessageBox::critical(this, tr("Error!"), tr("You cannot edit a logged-in trainee."));
            return;
        }

        Trainee trainee = connectorToServer->getTrainee(id_trainee);
        if(trainee.getID() == 0)
            return;

        Trainee trainee_edit;

        if(editTrainee(trainee, &trainee_edit))
            connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_EDIT_TRAINEE, id_trainee, &trainee_edit);
    }
}

void EditorTrainees::on_btnArchive_clicked()
{
    bool state = ui->btnArchive->isChecked();
    setArchiveVisible(state);
    if(!state)
    {
        lastCurrentID = 0;
        typeObject = TypeObject::objGroup;
    }
    loadTraineesFromDB();
}

void EditorTrainees::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
    //Определяем доступность и функционал кнопок для выбранного элемента

    if(current == nullptr)
        return;

    QTreeWidgetItem *treeItemParent = current->parent();
    if(treeItemParent == nullptr)
    {//Выбрана группа
        int id_group = current->text(ColumnsTreeTrainees::clmn_ID).toInt();

        lastCurrentID = id_group;
        typeObject = TypeObject::objGroup;

        if(adminMode)
        {
            ui->btnNewGroup->setEnabled(true);

            if(connectorToServer->getListTraineesInGroup(id_group).count() > 0)
            {//Группа не пуста
                ui->btnDeleteGroup->setEnabled(false);
            }
            else
            {//Группа пуста
                ui->btnDeleteGroup->setEnabled(true);
            }
        }
        else
        {
            ui->btnNewGroup->setEnabled(false);
            ui->btnDeleteGroup->setEnabled(false);
        }

        ui->btnNewTrainee->setEnabled(true);
        ui->btnDeleteTrainee->setEnabled(false);
        ui->btnToOrFromArchiveTrainee->setEnabled(false);
        ui->btnEdit->setEnabled(true);
        ui->btnArchive->setEnabled(true);

        ui->btnToOrFromArchiveTrainee->setText(tr("To archive"));
        ui->btnToOrFromArchiveTrainee->setIcon(QIcon(QStringLiteral(":/resources/icons/traineeArchive.png")));
    }
    else
    {//Выбран обучаемый
        int id_trainee = current->text(ColumnsTreeTrainees::clmn_ID).toInt();

        lastCurrentID = id_trainee;
        typeObject = TypeObject::objTrainee;

        ui->btnNewGroup->setEnabled(false);
        ui->btnDeleteGroup->setEnabled(false);
        ui->btnNewTrainee->setEnabled(false);        

        if(connectorToServer->isArchivedTrainee(id_trainee))
        {//Архивный
            //ui->btnDeleteTrainee->setEnabled(true);

            ui->btnToOrFromArchiveTrainee->setText(tr("From archive"));
            ui->btnToOrFromArchiveTrainee->setIcon(QIcon(QStringLiteral(":/resources/icons/traineeFromArchive.png")));
        }
        else
        {//Не Архивный
            //ui->btnDeleteTrainee->setEnabled(false);

            ui->btnToOrFromArchiveTrainee->setText(tr("To archive"));
            ui->btnToOrFromArchiveTrainee->setIcon(QIcon(QStringLiteral(":/resources/icons/traineeArchive.png")));
        }

        if(connectorToServer->isLoggedInTrainee(id_trainee))
        {//Это залогированный! Удалять/Архивировать/Редактировать нельзя!
            ui->btnDeleteTrainee->setEnabled(false);
            ui->btnToOrFromArchiveTrainee->setEnabled(false);
            ui->btnEdit->setEnabled(false);
        }
        else
        {
            ui->btnToOrFromArchiveTrainee->setEnabled(true);

            if(connectorToServer->isArchivedTrainee(id_trainee))
                ui->btnDeleteTrainee->setEnabled(true);
            else
                ui->btnDeleteTrainee->setEnabled(false);

            ui->btnEdit->setEnabled(true);
        }

        //ui->btnToOrFromArchiveTrainee->setEnabled(true);

        //ui->btnEdit->setEnabled(true);
        ui->btnArchive->setEnabled(true);
    }
}

bool EditorTrainees::verifyGroup(Group group)
{
    //Проверка корректности имени

    if(group.getName() == QStringLiteral("<group>"))
    {//Имя не корректно!
        QMessageBox::critical(this, tr("Editing error!"),
                              tr("Unacceptable group name has been entered.\nThe changes will not be accepted."));
        return false;
    }

    QList<Group> listGroups = connectorToServer->getListGroups();

    for(Group exist_group : listGroups)
    {
        if(group.getName() == exist_group.getName() && group.getID() != exist_group.getID())
        {//Имя уже существует
            QMessageBox::critical(this, tr("Editing error!"),
                                  tr("An existing group name has been entered.\nThe changes will not be accepted."));
            return false;
        }
    }

    return true;
}

bool EditorTrainees::verifyTrainee(Trainee trainee)
{
    //Проверка корректности логина, имени, пароля

    if(trainee.getName() == QStringLiteral("<trainee>"))
    {//Имя не корректно!
        QMessageBox::critical(this, tr("Editing error!"),
                              tr("Unacceptable trainee name has been entered.\nThe changes will not be accepted."));
        return false;
    }

    if(trainee.getLogin() == QStringLiteral("<login>"))
    {//Логин не корректен!
        QMessageBox::critical(this, tr("Editing error!"),
                              tr("Unacceptable trainee login has been entered.\nThe changes will not be accepted."));
        return false;
    }

    if(trainee.getPassword() == QStringLiteral("<password>"))
    {//Пароль не корректный!
        QMessageBox::critical(this, tr("Editing error!"),
                              tr("Unacceptable trainee password has been entered.\nThe changes will not be accepted."));
        return false;
    }

    QList<Trainee> listTrainees = connectorToServer->getListTrainees();

    for(Trainee exist_trainee : listTrainees)
    {
        if(trainee.getName() == exist_trainee.getName() && trainee.getID() != exist_trainee.getID())
        {//Имя уже существует
            QMessageBox::critical(this, tr("Editing error!"),
                                  tr("An existing trainee name has been entered."));
            return false;
        }

        if(trainee.getLogin() == exist_trainee.getLogin() && trainee.getID() != exist_trainee.getID())
        {//Логин уже существует!
            QMessageBox::critical(this, tr("Editing error!"),
                                  tr("An existing trainee login has been entered.\nThe changes will not be accepted."));
            return false;
        }
    }

    return true;
}

bool EditorTrainees::editGroup(Group group, Group *group_edit)
{
    DialogEditGroup dlg(this);

    dlg.setGroup(group);

    while (true)
    {
        switch( dlg.exec() )
        {
        case QDialog::Accepted:
        {
            *group_edit = dlg.getGroup();

            if(! verifyGroup(*group_edit))
            {
                dlg.setGroup(*group_edit);
                continue;
            }

            return true;
        }
        case QDialog::Rejected:
            return false;
        default:
            return false;
        }
    }
}

bool EditorTrainees::editTrainee(Trainee trainee, Trainee *trainee_edit)
{
    DialogEditTrainee dlg(this);

    dlg.setTrainee(trainee);

    while (true)
    {
        switch( dlg.exec() )
        {
        case QDialog::Accepted:
            {
                *trainee_edit = dlg.getTrainee();

                if(! verifyTrainee(*trainee_edit))
                {
                    dlg.setTrainee(*trainee_edit);
                    continue;
                }

                return true;
            }
        case QDialog::Rejected:
            return false;
        default:
            return false;
        }
    }
}


