#include <QDomDocument>
#include <QFile>
#include <QMessageBox>
#include <QTreeWidget>
#include <QThread>
#include <QResizeEvent>
#include <QScrollBar>
#include "fimtaskswidget.h"
#include "ui_fimtaskswidget.h"
#include "tasksAmmFim.h"
#include "checkertask.h"
#include "specialmessagebox.h"

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

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

    treeWidget = new QTreeWidget();
    ui->horizontalLayout_Tree->addWidget(treeWidget);

    //connect(treeWidget, &QTreeWidget::currentItemChanged, this, &FIMtasksWidget::on_treeWidgetCurrentItemChanged);
    connect(treeWidget, &QTreeWidget::itemClicked, this, &FIMtasksWidget::on_treeWidgetItemClicked);

    preparationTreeWidget();

    threadPreparation = new QThread();
    taskTreePreparation = new TaskAMMFIMTreePreparation(type, treeWidget);
    taskTreePreparation->moveToThread(threadPreparation);
    threadPreparation->start();
    threadPreparation->setPriority(QThread::HighestPriority);
    connect(this, &FIMtasksWidget::signal_prepareFIMListItems, taskTreePreparation, &TaskAMMFIMTreePreparation::slot_prepareFIMListItems);
    connect(this, &FIMtasksWidget::signal_prepareFIMListItemsForTrainee, taskTreePreparation, &TaskAMMFIMTreePreparation::slot_prepareFIMListItemsForTrainee);
    connect(taskTreePreparation, &TaskAMMFIMTreePreparation::signal_listFIMItemsReady, this, &FIMtasksWidget::slot_FIMlistItemsReady);
    connect(this, &FIMtasksWidget::signal_stopParserPreparation, taskTreePreparation, &TaskAMMFIMTreePreparation::slot_stopParserPreparation);

    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->btnAssignTask->setObjectName("btnAssignTask");
    ui->btnAssignTask->setEnabled(false);

    if(type == TypeListTreeAMMFIM::listCommon)
    {
        //ui->horizontalLayout_3->addWidget(ui->btnAssignTask);
        //ui->horizontalLayout_3->addWidget(ui->btnCheck);
        //ui->horizontalLayout_3->addWidget(ui->btnDelete);
        //ui->horizontalLayout_3->setAlignment(Qt::AlignmentFlag::AlignLeft);

        ui->btnDelete->setVisible(false);
        ui->btnCheck->setVisible(false);
    }
    else if(type == TypeListTreeAMMFIM::listOneTask)
    {
        ui->btnDelete->setVisible(false);
        ui->btnCheck->setVisible(false);
        ui->btnAssignTask->setVisible(false);
        this->treeWidget->headerItem()->setHidden(true);
        this->treeWidget->setSelectionMode(QAbstractItemView::SelectionMode::NoSelection);        
    }
    else
    {
        ui->btnAssignTask->setVisible(false);

        //ui->verticalLayout->setAlignment(Qt::AlignmentFlag::AlignBottom);
        //ui->horizontalLayout_3->setAlignment(Qt::AlignmentFlag::AlignLeft);
    }
}

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

    threadPreparation->quit();
    threadPreparation->wait();

    delete threadPreparation;

    delete taskTreePreparation;
    delete waitAnimationWidget;
    delete treeWidget;

    if(dlgCheckerTask)
    {
        dlgCheckerTask->close();
    }

    delete ui;
}

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

void FIMtasksWidget::setOneTaskFim(TaskAmmFim* task)
{
    QList<TaskAmmFim> listTask;
    listTask.append(*task);
    emit signal_prepareFIMListItemsForTrainee(listTask);
}

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

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

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

void FIMtasksWidget::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_UpdateTasksFIMforTrainee(idTraineeSelected);
    }
}

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

    QTreeWidgetItem *treeItemParent = item->parent();
    if(treeItemParent == nullptr)
    {//Выбрана задача
        int id = item->text(ColumnsTreeFIM::clmnFIM_ID).toInt();

        TaskAmmFim task = taskTreePreparation->getTaskFIMbyID(id);

        if(!task.getID())
        {
            ui->btnAssignTask->setEnabled(false);

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

        ui->btnAssignTask->setEnabled(true);

        ui->btnDelete->setEnabled(true);

        if(task.status != "new")
            ui->btnCheck->setEnabled(true);
        else
            ui->btnCheck->setEnabled(false);
    }
    else
    {
        setCurrentParentTask(item);

        /*
        ui->btnAssignTask->setEnabled(false);

        ui->btnDelete->setEnabled(false);
        ui->btnCheck->setEnabled(false);
        */
    }
}

void FIMtasksWidget::slot_NeedUpdateUI()
{
    qDebug() << "FIMtasksWidget::slot_NeedUpdateUI thread ID " << QThread::currentThreadId();
    loadTasksFIM();
}

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

    idTraineeSelected = id_trainee;

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

void FIMtasksWidget::slot_UpdateTasksFIMforTrainee(int trainee_id)
{
    qDebug() << "slot_UpdateTasksFIMforTrainee" << QThread::currentThreadId();
    if(type == TypeListTreeAMMFIM::listForTrainee)
    {
        if(idTraineeSelected == trainee_id)
        {
            QList<TaskAmmFim> listTask = connectorToServer->getListTasksFIMforTrainee(trainee_id);
            emit signal_prepareFIMListItemsForTrainee(listTask);

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

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

void FIMtasksWidget::loadTasksFIM()
{
    //Обновление дерева
    treeWidget->clear();

    waitAnimationWidget->showWithPlay();

    QByteArray arrayFIM = connectorToServer->getListTaskFimArray();

    emit signal_prepareFIMListItems(arrayFIM);
}

void FIMtasksWidget::slot_FIMlistItemsReady(QList<QTreeWidgetItem *> listItems)
{
    //Обновление дерева
    treeWidget->clear();

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

    QTreeWidgetItem * item = treeWidget->topLevelItem(0);
    if(item != nullptr)
    {
        //treeWidget->setCurrentItem(item);
        if(type == TypeListTreeAMMFIM::listOneTask)
            treeWidget->expandAll();
    }

    setCurrentTask(lastCurrentID);

    waitAnimationWidget->hideWithStop();
}

void FIMtasksWidget::preparationTreeWidget()
{
    treeWidget->setColumnCount(clmnFIM_count);

    reSetHeadTreeWidget();

    if(type == TypeListTreeAMMFIM::listCommon || type == TypeListTreeAMMFIM::listOneTask)
    {
        treeWidget->setColumnHidden(ColumnsTreeFIM::clmnFIM_ID, true);
        treeWidget->setColumnHidden(ColumnsTreeFIM::clmnFIM_status, true);
    }
    else
    {
#ifdef PROJECT_TYPE_DEBUG
        treeWidget->setColumnHidden(ColumnsTreeFIM::clmnFIM_ID, false);
#else
        treeWidget->setColumnHidden(ColumnsTreeFIM::clmnFIM_ID, true);
#endif
    }
}

void FIMtasksWidget::reSetHeadTreeWidget()
{
    QStringList listHeaders;

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

    treeWidget->setHeaderLabels(listHeaders);
}

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

    treeWidget->setColumnWidth(ColumnsTreeFIM::clmnFIM_Title, 100);
    listWidthColumn.append(100);
    treeWidget->setColumnWidth(ColumnsTreeFIM::clmnFIM_status, 150);
    listWidthColumn.append(130);
    treeWidget->setColumnWidth(ColumnsTreeFIM::clmnFIM_ID, 50);
    listWidthColumn.append(50);

    treeWidget->setColumnWidth(ColumnsTreeFIM::clmnFIM_Title, calculateWidth_0Column());
}

int FIMtasksWidget::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 FIMtasksWidget::assignTaskFIMtoTrainee()
{
    QTreeWidgetItem *current = treeWidget->currentItem();

    if(current == nullptr)
        return;

    int id = current->text(ColumnsTreeFIM::clmnFIM_ID).toInt();

    TaskAmmFim task = taskTreePreparation->getTaskFIMbyID(id);

    if(task.getID())
    {
        TaskAmmFim taskNew;
        taskNew.title = task.title;

        //Назначенные неисправности
        for (int i = 0; i < current->childCount(); i++)
        {
            QTreeWidgetItem* itemMalfunction = current->child(i);

            if(itemMalfunction->checkState(0) == Qt::Checked)
            {
                Malfunction malfunction = task.malfunctionList.at(i);
                taskNew.malfunctionList.append(malfunction);
            }
        }

        connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE, idTraineeSelected, &taskNew);

        updateTaskItem(current);
    }
}

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

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

            int id = treeItemCurrent->text(ColumnsTreeFIM::clmnFIM_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_FIM_TO_TRAINEE, id);
            }
        }
    }
}

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

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

            int id = treeItemCurrent->text(ColumnsTreeFIM::clmnFIM_ID).toInt();

            TaskAmmFim task = taskTreePreparation->getTaskFIMbyID(id);

            if(!task.getID())
                return;

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

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

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

void FIMtasksWidget::on_btnAssignTask_clicked()
{
    if(SpecialMessageBox(this, SpecialMessageBox::TypeSpecMsgBox::warningYesNo, tr("Assign this task?")).exec() == QDialog::Accepted)
        assignTaskFIMtoTrainee();
}

void FIMtasksWidget::updateTaskItem(QTreeWidgetItem *itemTask)
{
    for (int i = 0; i < itemTask->childCount(); i++)
    {
        QTreeWidgetItem* itemMalfunction = itemTask->child(i);
        itemMalfunction->setCheckState(0, Qt::Checked);
        itemMalfunction->setExpanded(false);
    }
    itemTask->setExpanded(false);
}

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

void FIMtasksWidget::setCurrentParentTask(QTreeWidgetItem *item)
{
    if(item == nullptr)
        return;

    int id = 0;

    QTreeWidgetItem *treeItemParent = item->parent();
    if(treeItemParent == nullptr)
    {//задача
        id = item->text(ColumnsTreeFIM::clmnFIM_ID).toInt();
    }
    else
    {
        QTreeWidgetItem *treeItemParent1 = treeItemParent->parent();
        if(treeItemParent1 == nullptr)
        {//задача
            id = treeItemParent->text(ColumnsTreeFIM::clmnFIM_ID).toInt();
        }
        else
        {
            QTreeWidgetItem *treeItemParent2 = treeItemParent1->parent();
                if(treeItemParent2 == nullptr)
                {//задача
                    id = treeItemParent1->text(ColumnsTreeFIM::clmnFIM_ID).toInt();
                }
        }
    }

    if(id)
        setCurrentTask(id);
}


