#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTimer>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Initialize();

}



void MainWindow::Initialize()
{

    ui->settingsWidget->hide();
    ui->notificationLabel->hide();
    ui->loadingProgressBar->hide();
    ui->updateButton->hide();
    ui->connectButton->hide();
    ui->startButton->setEnabled(false);
    ui->debugText->hide();

    updateControllerThread = new QThread;
    connectionThread = new QThread;

    client = new TCPClient;
    client->moveToThread(connectionThread);

    dataParser = new DataParser;

    updateController = new UpdateController(dataParser);
    updateController->moveToThread(updateControllerThread);

    recognizeSystem = new RecognizeSystem;
    screenChecker = new ScreenChecker;
    externalExecuter = new ExternalExecuter;

    timer = new QTimer;
    connect(timer,&QTimer::timeout,this,&MainWindow::disableNotify);

    connect(recognizeSystem,&RecognizeSystem::UpdateBytesAvailable,this,&MainWindow::UpdateProgress);
    connect(recognizeSystem,&RecognizeSystem::LoadComplete,this,&MainWindow::LoadComplete);
    connect(recognizeSystem,&RecognizeSystem::onNeedUpdate,this,&MainWindow::SetNeedUpdate);
    connect(recognizeSystem,&RecognizeSystem::onSendDebugLog,this,&MainWindow::DebugLog);
    connect(recognizeSystem,&RecognizeSystem::SockedDisabled,this,&MainWindow::LostConnection);
    connect(recognizeSystem,&RecognizeSystem::SaveLoginData,this,&MainWindow::CheckLoginResult);
    connect(recognizeSystem,&RecognizeSystem::SocketWaitForReadyRead,client,&TCPClient::WaitRead,Qt::AutoConnection);

    connectionThread->start();
    updateControllerThread->start();

    updateControllerThread->setPriority(QThread::LowPriority);
    connectionThread->setPriority(QThread::HighestPriority);

    connect(client,&TCPClient::onSendDebugLog,this,&MainWindow::DebugLog,Qt::AutoConnection);

    connect(this,&MainWindow::onInitializeClient,client,&TCPClient::Initialize,Qt::AutoConnection);
    connect(this,&MainWindow::onSetConnect,client,&TCPClient::SetConnect,Qt::AutoConnection);
    connect(this,&MainWindow::onSendMessage,client,&TCPClient::MessageEntered,Qt::AutoConnection);
    connect(this,&MainWindow::SendClientAuthorization,client,&TCPClient::SendClientAutorization,Qt::AutoConnection);
    connect(client,&TCPClient::ConnectionState,this,&MainWindow::onConnectionState);

    connect(this,&MainWindow::onCalculateHash,updateController,&UpdateController::CalculateHash);

    emit onCalculateHash();
    emit onInitializeClient(recognizeSystem,externalExecuter);

    recognizeSystem->Initialize(updateController,dataParser);

    screenChecker->Check();
    ui->updateButton->setEnabled(false);
    ui->startButton->setEnabled(false);

    maxBytesAvailable = 0;
    globalValue = 0;
    ui->loadingProgressBar->setValue(0);

    emit onSetConnect(dataParser->GetServerSettings());

    CheckAppAvailable();
}

void MainWindow::UpdateProgress(qint64 size,quint64 sended)
{
    float currentValue = 100.00 / (maxBytesAvailable / size);
    globalValue += currentValue;

    ui->loadingProgressBar->setValue(globalValue);
}

void MainWindow::LoadComplete()
{
    ui->loadingProgressBar->setValue(100);
    ui->updateButton->setEnabled(false);
    externalExecuter->FindApp();
    ui->startButton->setEnabled(true);
}

void MainWindow::SetNeedUpdate(bool flag,quint64 size)
{
    maxBytesAvailable = 0;
    if(flag){
        quint64 megaByte = size / (1024 * 1024);
        QString result = "Доступно обновление: " + QString::number(megaByte) + " мегабайт";
        ui->inlineTextDebug->setText(result);
        maxBytesAvailable = size;
    }else{
        ui->inlineTextDebug->setText("Установлена последняя версия");
    }

    ui->updateButton->setEnabled(flag);
    ui->startButton->setEnabled(!flag);
    ui->loadingProgressBar->setRange(0,100);
}

void MainWindow::LostConnection()
{
    ui->loadingProgressBar->setValue(0);
}

void MainWindow::CheckLoginResult(ServerAuthorization *serverAuth)
{
    if (serverAuth->Result){
        emit onSendMessage("check");

        ui->inlineTextDebug->setText("Проверка обновлений...");
        ui->loadingProgressBar->show();
        ui->updateButton->show();
        dataParser->CreateAuthData(serverAuth);
        ui->loginWidget->hide();

    }
    else {
        ui->notificationLabel->setText("Неверный логин/пароль");
        timer->setInterval(3000);
        timer->start();

        QPalette palette = ui->notificationLabel->palette();
        palette.setColor(ui->notificationLabel->foregroundRole(), Qt::red);

        ui->notificationLabel->setPalette(palette);
        ui->notificationLabel->show();
    }

}

void MainWindow::CheckAppAvailable()
{
    bool isAvailable = externalExecuter->FindApp();
    ui->startButton->setEnabled(isAvailable);
}


void MainWindow::on_loginButton_clicked()
{
    QString username = ui->loginInputField->text();
    QString password = ui->passwordInputField->text();

    ClientAutorization *autorization = new ClientAutorization;
    autorization->Login = username;
    autorization->Password = password;

    dataParser->CreateAuthMessage(autorization);
    emit SendClientAuthorization();
}

void MainWindow::on_updateButton_clicked()
{
    emit onSendMessage("update");
    ui->loadingProgressBar->setValue(0);
}

void MainWindow::on_startButton_clicked()
{
    externalExecuter->CallApp();
}


void MainWindow::on_saveServerButton_clicked()
{
    ui->settingsWidget->hide();
    ui->loginWidget->show();

    QString server = ui->serverInputField->text();
    QString port = ui->portInputField->text();

    dataParser->CreateServerSettings(server,port);

    emit onSetConnect(dataParser->GetServerSettings());
}

void MainWindow::on_settingsButton_clicked()
{
    ui->settingsWidget->show();
    ui->loginWidget->hide();

    ServerSettings *currentSettings = dataParser->GetServerSettings();

    ui->serverInputField->setText(currentSettings->Address);
    ui->portInputField->setText(currentSettings->Port);
}

void MainWindow::disableNotify()
{
    ui->notificationLabel->hide();

    QPalette palette = ui->notificationLabel->palette();
    palette.setColor(ui->notificationLabel->foregroundRole(), Qt::black);

    ui->notificationLabel->setPalette(palette);
    timer->stop();
}

void MainWindow::onConnectionState(bool flag)
{
    ui->notificationLabel->show();
    QPalette palette = ui->notificationLabel->palette();

    if(flag)
    {
        palette.setColor(ui->notificationLabel->foregroundRole(),Qt::green);
        ui->notificationLabel->setText("Соединение установлено");
        ui->connectButton->hide();
    }
    else
    {
        palette.setColor(ui->notificationLabel->foregroundRole(),Qt::red);
        ui->notificationLabel->setText("Соединение отсутсвует");
        ui->connectButton->show();
    }

    ui->notificationLabel->setPalette(palette);
    timer->start(3000);
}

void MainWindow::DebugLog(QString message)
{
    ui->debugText->append(message);
}


MainWindow::~MainWindow()
{
    connectionThread->quit();
    connectionThread->wait();

    updateControllerThread->quit();
    updateControllerThread->wait();

    delete connectionThread;
    delete updateControllerThread;
    delete ui;
}

void MainWindow::on_connectButton_clicked()
{
    emit onSetConnect(dataParser->GetServerSettings());
}
