#include <QFile>
#include <QXmlStreamReader>
#include <QDomDocument>
#include <QMessageBox>
#include <QThread>
#include <QResizeEvent>
#include <QScrollBar>
#include "ammtaskswidget.h"
#include "ui_ammtaskswidget.h"
#include "checkertask.h"
#include "specialmessagebox.h"

AMMtasksWidget::AMMtasksWidget(ConnectorToServer* connectorToServer, TypeListTreeAMMFIM type, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::AMMtasksWidget),
    connectorToServer(connectorToServer),
    treeWidget(nullptr),
    type(type),
    idTraineeSelected(0),
    threadPreparation(nullptr),
    taskTreePreparation(nullptr),
    waitAnimationWidget(nullptr),
    dlgCheckerTask(nullptr),
    dlgListSubProc(nullptr),
    flOnlyActive(false),
    lastCurrentID(0)
{
    ui->setupUi(this);    

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

    treeWidget = new QTreeWidget();
    if(type == TypeListTreeAMMFIM::listForTrainee)
        treeWidget->setObjectName("treeWidget_AMMforTrainee");
    ui->horizontalLayout_Tree->addWidget(treeWidget);

    connect(treeWidget, &QTreeWidget::itemClicked, this, &AMMtasksWidget::on_treeWidgetItemClicked);
    connect(treeWidget, &QTreeWidget::itemDoubleClicked, this, &AMMtasksWidget::on_treeWidgetDoubleClicked);

    preparationTreeWidget();

    taskTreePreparation = new TaskAMMFIMTreePreparation(type, treeWidget);
    if(type == TypeListTreeAMMFIM::listCommon)
    {
        threadPreparation = new QThread();
        taskTreePreparation->moveToThread(threadPreparation);
        threadPreparation->start();
        threadPreparation->setPriority(QThread::HighestPriority);
    }

    connect(this, &AMMtasksWidget::signal_prepareAMMListItems, taskTreePreparation, &TaskAMMFIMTreePreparation::slot_prepareAMMListItems);
    connect(this, &AMMtasksWidget::signal_prepareAMMListItemsForTrainee, taskTreePreparation, &TaskAMMFIMTreePreparation::slot_prepareAMMListItemsForTrainee);
    connect(taskTreePreparation, &TaskAMMFIMTreePreparation::signal_listAMMItemsReady, this, &AMMtasksWidget::slot_AMMlistItemsReady);
    connect(this, &AMMtasksWidget::signal_stopParserPreparation, taskTreePreparation, &TaskAMMFIMTreePreparation::slot_stopParserPreparation);

    connect(this->connectorToServer, &ConnectorToServer::signal_UpdateSubProcForDMCode, this, &AMMtasksWidget::slot_UpdateSubProcForDMCode);

    waitAnimationWidget = new WaitAnimationWidget;    
    QMovie *movie = new QMovie(":/resources/icons/762.gif");
    waitAnimationWidget->setParent(this);
    waitAnimationWidget->initialize(movie,this);

    ui->btnDelete->setObjectName("btnDelete");
    ui->btnDelete->setEnabled(false);
    ui->btnCheck->setObjectName("btnCheck");
    ui->btnCheck->setEnabled(false);
    ui->btnOnlyActive->setObjectName("btnOnlyActive");
    ui->btnOnlyActive->setEnabled(false);
    ui->btnAssignTask->setObjectName("btnAssignTask");
    ui->btnAssignTask->setEnabled(false);    
    ui->btnDocsUpdating->setObjectName("btnDocsUpdating");
    ui->btnDocsUpdating->setEnabled(false);

    if(type == TypeListTreeAMMFIM::listCommon)
    {
        ui->btnDelete->setVisible(false);
        ui->btnCheck->setVisible(false);
    }
    else
    {
        ui->btnOnlyActive->setVisible(false);
        ui->btnAssignTask->setVisible(false);

        ui->label_DocsActualed->setVisible(false);
        ui->label_Actual->setVisible(false);
        ui->btnDocsUpdating->setVisible(false);
    }
}

AMMtasksWidget::~AMMtasksWidget()
{
    waitAnimationWidget->hideWithStop();
    emit signal_stopParserPreparation();


    if(type == TypeListTreeAMMFIM::listCommon)
    {
        threadPreparation->quit();
        threadPreparation->wait();

        delete threadPreparation;
    }

    delete taskTreePreparation;
    delete waitAnimationWidget;
    delete treeWidget;

    delete ui;
}

void AMMtasksWidget::deactivate()
{
    ui->btnAssignTask->setEnabled(false);
    ui->btnOnlyActive->setEnabled(false);
    treeWidget->clear();
    idTraineeSelected = 0;
}

void AMMtasksWidget::waitAnimationWidgetShowWithPlay()
{
    waitAnimationWidget->showWithPlay();
}

void AMMtasksWidget::setDocsActualed(bool flActualed)
{
    if(flActualed)
    {
        ui->label_DocsActualed->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGreen.png")));
        ui->label_Actual->setText(tr("actual"));
        ui->btnDocsUpdating->setEnabled(false);
    }
    else
    {
        ui->label_DocsActualed->setPixmap(QPixmap(QStringLiteral(":/resources/icons/warning.png")));
        ui->label_Actual->setText(tr("update required"));
        ui->btnDocsUpdating->setEnabled(true);
    }
}

void AMMtasksWidget::resizeEvent(QResizeEvent *event)
{
    setWidthColumnsTree();

    QSize size = event->size();
    waitAnimationWidget->resize(size);
}

void AMMtasksWidget::closeDlgCheckTask()
{
    if(dlgCheckerTask)
        dlgCheckerTask->close();
}

void AMMtasksWidget::closeDlgListSubProc()
{
    if(dlgListSubProc)
        dlgListSubProc->close();
}

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

        reSetHeadTreeWidget();

        if(type == TypeListTreeAMMFIM::listCommon)
        {
            //slot_NeedUpdateUI();
        }
        else if(type == TypeListTreeAMMFIM::listForTrainee)
            if(idTraineeSelected)
                slot_UpdateTasksAMMforTrainee(idTraineeSelected);
    }
}

void AMMtasksWidget::on_treeWidgetItemClicked(QTreeWidgetItem *item, int column)
{
    if(item == nullptr)
    {
        ui->btnDelete->setEnabled(false);
        ui->btnCheck->setEnabled(false);
        ui->btnAssignTask->setEnabled(false);
        return;
    }

    if(this->type == TypeListTreeAMMFIM::listCommon)
    {
        int id = item->text(ColumnsTreeAMM::clmnAMM_ID).toInt();
        TaskAmmFim task = taskTreePreparation->getTaskAMMbyID(id);

        if(taskTreePreparation->getTypeModuleAMMbyID(id) == ModuleType::TYPE_PM)
            ui->btnAssignTask->setEnabled(false);
        else
        {
            ui->btnAssignTask->setEnabled(true);
        }

        if(task.getID())
            lastCurrentID = id;

        ui->btnDelete->setEnabled(false);
        ui->btnCheck->setEnabled(false);
    }
    else if(this->type == TypeListTreeAMMFIM::listForTrainee)
    {
        QTreeWidgetItem *treeItemParent = item->parent();
        if(treeItemParent == nullptr)
        {//Выбрана задача
            ui->btnCheck->setEnabled(true);
            ui->btnDelete->setEnabled(true);

            int id = item->text(ColumnsTreeAMM::clmnAMM_ID).toInt();
            TaskAmmFim task = taskTreePreparation->getTaskAMMbyID(id);

            if(task.getID())
                lastCurrentID = id;
        }
        else
        {
            ui->btnCheck->setEnabled(false);
            ui->btnDelete->setEnabled(false);
        }
        ui->btnAssignTask->setEnabled(false);
    }
    else
        lastCurrentID = 0;
}

void AMMtasksWidget::slot_NeedUpdateUI()
{
    qDebug() << "AMMtasksWidget::slot_NeedUpdateUI thread ID " << QThread::currentThreadId();
    loadTasksAMM();
    setDocsActualed(true);
}

void AMMtasksWidget::slot_traineeSelected(int id_trainee)
{
    qDebug() << "AMMtasksWidget::slot_traineeSelected thread ID " << QThread::currentThreadId();

    idTraineeSelected = id_trainee;

    if(type == TypeListTreeAMMFIM::listForTrainee)
    {
        waitAnimationWidget->showWithPlay();
        connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_GET_TASKS_AMM_FOR_TRAINEE, idTraineeSelected);
    }
}

void AMMtasksWidget::slot_UpdateTasksAMMforTrainee(int trainee_id)
{
    qDebug() << "slot_UpdateTasksAMMforTrainee" << QThread::currentThreadId();
    if(type == TypeListTreeAMMFIM::listForTrainee)
    {
        if(idTraineeSelected == trainee_id)
        {
            QList<TaskAmmFim> listTask = connectorToServer->getListTasksAMMforTrainee(trainee_id);
            emit signal_prepareAMMListItemsForTrainee(listTask);

            emit signal_countTasksAMMforTraineeChanged(trainee_id, listTask.count());
        }
    }
}

void AMMtasksWidget::loadTasksAMM(bool flRequestFirst)
{
    //Обновление дерева
    treeWidget->clear();

    waitAnimationWidget->showWithPlay();

    QByteArray arrayAMM;

    arrayAMM = connectorToServer->getListTaskAmmArray();

    emit signal_prepareAMMListItems(arrayAMM, flOnlyActive, flRequestFirst);
}

void AMMtasksWidget::slot_AMMlistItemsReady(QList<QTreeWidgetItem *> listItems)
{
    if(type != TypeListTreeAMMFIM::listForTrainee)
    {
        //Обновление дерева
        treeWidget->clear();

        for(QTreeWidgetItem * item : listItems)
            treeWidget->addTopLevelItem(item);
    }

    /*
    QTreeWidgetItem * item = treeWidget->topLevelItem(0);
    if(item != nullptr)
        treeWidget->setCurrentItem(item);
        */

    if(type == TypeListTreeAMMFIM::listForTrainee)
        setCurrentTask(lastCurrentID);

    waitAnimationWidget->hideWithStop();

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

void AMMtasksWidget::slot_UpdateSubProcForDMCode(QString dmCode)
{
    if(lastSelectedTask.ammProcedure.dmCode == dmCode)
    {//Его ждем
        QList<SubProc> list = connectorToServer->getListSubProcForDMCode(dmCode);
        lastSelectedTask.listSubProc = list;

        waitAnimationWidget->hideWithStop();

        if(lastSelectedTask.listSubProc.count())
        {
            dlgListSubProc = new DialogListSubProc(this);
            dlgListSubProc->setTask(&lastSelectedTask);

            switch( dlgListSubProc->exec() )
            {
            case QDialog::Accepted:
            {
                //Здесь нужно забрать список отмеченных подпроцедур
                lastSelectedTask.listSubProc.clear();
                dlgListSubProc->getListCheckedSubProc(&lastSelectedTask.listSubProc);

                if(SpecialMessageBox(this, SpecialMessageBox::TypeSpecMsgBox::warningYesNo, tr("Assign this task?")).exec() == QDialog::Accepted)
                {
                    connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE, idTraineeSelected, &lastSelectedTask);
                }
                break;
            }
            case QDialog::Rejected:
                break;
            default:
                break;
            }

            if(dlgListSubProc)
            {
                delete dlgListSubProc;
                dlgListSubProc = nullptr;
            }
        }
        else
        {
            lastSelectedTask.listSubProc.clear();

            if(SpecialMessageBox(this, SpecialMessageBox::TypeSpecMsgBox::warningYesNo, tr("Assign this task?")).exec() == QDialog::Accepted)
            {
                connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE, idTraineeSelected, &lastSelectedTask);
            }
        }
    }
}

void AMMtasksWidget::preparationTreeWidget()
{
    treeWidget->setColumnCount(clmnAMM_count);

    reSetHeadTreeWidget();

    if(type == TypeListTreeAMMFIM::listCommon)
    {
        treeWidget->setColumnHidden(ColumnsTreeAMM::clmnAMM_ID, true);
        treeWidget->setColumnHidden(ColumnsTreeAMM::clmnAMM_status, true);

#ifdef PROJECT_TYPE_DEBUG
           treeWidget->setColumnHidden(ColumnsTreeAMM::clmnAMM_canplay, false);
#else
           treeWidget->setColumnHidden(ColumnsTreeAMM::clmnAMM_canplay, true);
#endif
    }
    else
    {
#ifdef PROJECT_TYPE_DEBUG
           treeWidget->setColumnHidden(ColumnsTreeAMM::clmnAMM_ID, false);
#else
           treeWidget->setColumnHidden(ColumnsTreeAMM::clmnAMM_ID, true);
#endif

           treeWidget->setColumnHidden(ColumnsTreeAMM::clmnAMM_canplay, true);
    }

    /*
#ifdef PROJECT_TYPE_DEBUG
    treeWidget->setColumnHidden(ColumnsTreeAMM::clmnAMM_canplay, false);
#else
    treeWidget->setColumnHidden(ColumnsTreeAMM::clmnAMM_canplay, true);
#endif
    */
}

void AMMtasksWidget::reSetHeadTreeWidget()
{
    QStringList listHeaders;

    if(type == TypeListTreeAMMFIM::listForTrainee)
        listHeaders = QStringList{tr("Procedure AMM"), tr("DM code"), tr("Status"), tr("Canplay"), tr("ID")};
    else
        listHeaders = QStringList{tr("Procedure AMM"), tr("DM code"), tr("Status"), tr("Canplay"), tr("ID")};


    treeWidget->setHeaderLabels(listHeaders);
}

void AMMtasksWidget::setWidthColumnsTree()
{
    listWidthColumn.clear();

    treeWidget->setColumnWidth(ColumnsTreeAMM::clmnAMM_PMorDM, 100);
    listWidthColumn.append(100);
    treeWidget->setColumnWidth(ColumnsTreeAMM::clmnAMM_code, 250);
    listWidthColumn.append(250);    
    treeWidget->setColumnWidth(ColumnsTreeAMM::clmnAMM_status, 150);
    listWidthColumn.append(130);
    treeWidget->setColumnWidth(ColumnsTreeAMM::clmnAMM_canplay, 80);
    listWidthColumn.append(80);
    treeWidget->setColumnWidth(ColumnsTreeAMM::clmnAMM_ID, 50);
    listWidthColumn.append(50);

    treeWidget->setColumnWidth(ColumnsTreeAMM::clmnAMM_PMorDM, calculateWidth_0Column());
}

int AMMtasksWidget::calculateWidth_0Column()
{
    int widthHeader = treeWidget->width() - 25;
    int width0Column = 0;
    int widthSB = 0;
    if(treeWidget->verticalScrollBar()->isVisible())
        widthSB = treeWidget->verticalScrollBar()->size().width();
    int cntColumns = treeWidget->columnCount();
    int widthRightColumns = 0;
    for (int i = 1; i < cntColumns; i++)
    {
        if(! treeWidget->isColumnHidden(i))
        {//Колонка не скрыта
            int w = listWidthColumn.at(i);
            widthRightColumns += w;
        }
    }
    width0Column = widthHeader - widthRightColumns - widthSB;

    return width0Column;
}

void AMMtasksWidget::assignTaskAMMtoTrainee()
{
    QTreeWidgetItem *current = treeWidget->currentItem();

    if(current == nullptr)
        return;

    int id = current->text(ColumnsTreeAMM::clmnAMM_ID).toInt();

    TaskAmmFim taskNew = taskTreePreparation->getTaskAMMbyID(id);

    if(taskNew.getID())
    {
        if(selectSubProcForAssignTaskAMM(taskNew, &taskNew.listSubProc))
        {}
    }
}

bool AMMtasksWidget::selectSubProcForAssignTaskAMM(TaskAmmFim taskNew, QList<SubProc>* listSubProc)
{
    lastSelectedTask = taskNew;

    waitAnimationWidget->showWithPlay();

    if(! connectorToServer->sendQueryListSubProc(lastSelectedTask.ammProcedure.dmCode))
    {
        waitAnimationWidget->hideWithStop();
        return false;
    }

    return true;
}

void AMMtasksWidget::setCurrentTask(int id)
{
    for(int i = 0; i < treeWidget->topLevelItemCount(); i++)
    {
        QTreeWidgetItem * item = treeWidget->topLevelItem(i);
        if(item != nullptr)
            if(item->text(ColumnsTreeAMM::clmnAMM_ID).toInt() == id)
            {
                treeWidget->setCurrentItem(item);
                return;
            }
    }
}

void AMMtasksWidget::on_btnDelete_clicked()
{
    QTreeWidgetItem *treeItemCurrent = treeWidget->currentItem();

    if(treeItemCurrent != nullptr)
    {
        QTreeWidgetItem *treeItemParent = treeItemCurrent->parent();
        if(treeItemParent == nullptr)
        {//Выбрана задача

            int id = treeItemCurrent->text(ColumnsTreeAMM::clmnAMM_ID).toInt();

            if(SpecialMessageBox(this, SpecialMessageBox::TypeSpecMsgBox::warningYesNo, tr("The deletion will be irrevocable.\nDelete it anyway?")).exec() == QDialog::Accepted)
            {
                waitAnimationWidget->showWithPlay();
                connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_DEL_TASK_AMM_TO_TRAINEE, id);
            }
        }
    }
}

void AMMtasksWidget::on_btnCheck_clicked()
{
    QTreeWidgetItem *treeItemCurrent = treeWidget->currentItem();

    if(treeItemCurrent != nullptr)
    {//Выбрана задача

        int id = treeItemCurrent->text(ColumnsTreeAMM::clmnAMM_ID).toInt();

        TaskAmmFim task = taskTreePreparation->getTaskAMMbyID(id);

        if(!task.getID())
            return;

        dlgCheckerTask = new DialogChekerTask(connectorToServer, "amm", this);
        dlgCheckerTask->setTask(&task);
        dlgCheckerTask->exec();

        if(dlgCheckerTask->getFlChanged())
            waitAnimationWidget->showWithPlay();

        if(dlgCheckerTask)
        {
            delete dlgCheckerTask;
            dlgCheckerTask = nullptr;
        }
    }
}

void AMMtasksWidget::on_btnAssignTask_clicked()
{
    assignTaskAMMtoTrainee();
}

void AMMtasksWidget::on_btnOnlyActive_clicked()
{
    if(ui->btnOnlyActive->isChecked())
    {
        flOnlyActive = true;
    }
    else
    {
        flOnlyActive = false;
    }
    loadTasksAMM(false);
}

void AMMtasksWidget::on_treeWidgetDoubleClicked(QTreeWidgetItem *item, int column)
{
    if(item == nullptr)
        return;

    int id = item->text(ColumnsTreeAMM::clmnAMM_ID).toInt();

    TaskAmmFim task = taskTreePreparation->getTaskAMMbyID(id);

    if(taskTreePreparation->getTypeModuleAMMbyID(id) == ModuleType::TYPE_PM)
    {

    }
    else
    {
        assignTaskAMMtoTrainee();
    }
}

void AMMtasksWidget::on_btnDocsUpdating_clicked()
{
    connectorToServer->sendQueryTasksXML("amm");
}
