#include <QXmlStreamReader>
#include <QMessageBox>
#include "dialogsettingstray.h"
#include "Systems/tools.h"
#include "ui_dialogsettingstray.h"
#include "dialogcheckdb.h"
#include "dialogauthorization.h"

DialogSettingsTray::DialogSettingsTray(ProviderDBLMS* providerDBLMS, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogSettingsTray),
    settings(nullptr),
    providerDBLMS(providerDBLMS),
    flSettingsServerChanged(false)
{
    ui->setupUi(this);

    ui->btnSave->setObjectName("btnSave");
    ui->btnCheckDB->setObjectName("btnCheckDB");
    ui->btnUpdateDocs->setObjectName("btnUpdateDocs");

    /* Создаем строку для регулярного выражения */
    QString ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])";
    /* Создаем регулярное выражение с применением строки, как
     * повторяющегося элемента
     */
    QRegExp ipRegex ("^" + ipRange
                     + "\\." + ipRange
                     + "\\." + ipRange
                     + "\\." + ipRange + "$");
    /* Создаем Валидатор регулярного выражения с применением
     * созданного регулярного выражения
     */
    QRegExpValidator *ipValidator = new QRegExpValidator(ipRegex, this);
    /* Устанавливаем Валидатор на QLineEdit */
    ui->editHostName->setValidator(ipValidator);

    settings = new ServerDBSettings();

    //Задаём два пункта с текстом локалей в комбобоксе
    ui->cmbLanguage->addItems(QStringList() << "English" << "Русский");

    //Скрываем пароль
    ui->editPassword->setEchoMode(QLineEdit::EchoMode::Password);

    if(loadSettings(settings))
    {
        if(settings->Language == "ENG")
            ui->cmbLanguage->setCurrentText("English");
        else
            ui->cmbLanguage->setCurrentText("Русский");

        ui->editNameDB->setText(settings->NameDB);

        if(settings->HostName == "localhost")
        {
            ui->checkLocalhost->setChecked(true);
        }
        else
        {
            ui->checkLocalhost->setChecked(false);
        }
        ui->editHostName->setText(settings->HostName);

        ui->editPort->setText(settings->Port);
        ui->editUserName->setText(settings->UserName);
        ui->editPassword->setText(settings->Password);

        ui->btnSave->setEnabled(false);
        ui->btnCheckDB->setEnabled(true);
        flSettingsServerChanged = false;
    }
    else
    {
        ui->checkLocalhost->setChecked(true);
        //ui->editHostName->setEnabled(true);
        ui->editPort->setEnabled(true);
        ui->editNameDB->setEnabled(true);
        ui->editUserName->setEnabled(true);
        ui->editPassword->setEnabled(true);

        ui->btnSave->setEnabled(false);

        ui->btnSave->setEnabled(false);
        ui->btnCheckDB->setEnabled(false);
        flSettingsServerChanged = false;
    }
}

DialogSettingsTray::~DialogSettingsTray()
{
    delete ui;
    delete settings;
}

ServerDBSettings DialogSettingsTray::getSettings()
{
    return *settings;
}

bool DialogSettingsTray::loadSettings(ServerDBSettings *settings)
{
    QFile file(settingsName);
    if(! file.open(QIODevice::ReadOnly))
        return false;

    QXmlStreamReader xmlReader(&file);

    while (!xmlReader.atEnd()){

        if(xmlReader.isStartElement()){

            if(xmlReader.name() == "DataBaseSettings")
            {

                foreach(const QXmlStreamAttribute &attr, xmlReader.attributes()){
                    QString name = attr.name().toString();
                    QString value = attr.value().toString();

                    if(name == "Type"){
                        settings->Type = value;
                    }

                    if(name == "Name"){
                        settings->NameDB = value;
                    }

                    if(name == "UserName"){
                        settings->UserName = value;
                    }

                    if(name == "Password"){
                        settings->Password = value;
                    }

                    if(name == "HostName"){
                        settings->HostName = value;
                    }

                    if(name == "Port"){
                        settings->Port = value;
                    }

                    if(name == "Language"){
                        settings->Language = value;
                    }

                }
            }
        }

        xmlReader.readNext();
    }

    file.close();

    return true;
}

bool DialogSettingsTray::saveSettings()
{
    QFile file(settingsName);

    if(! file.open(QIODevice::WriteOnly))
        return false;

    QXmlStreamWriter xmlWriter(&file);

    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();

    xmlWriter.writeStartElement("ServerSettingsContainer");
    xmlWriter.writeStartElement("DataBaseSettings");

    xmlWriter.writeAttribute("Type", settings->Type);
    xmlWriter.writeAttribute("Name", settings->NameDB);
    xmlWriter.writeAttribute("UserName", settings->UserName);
    xmlWriter.writeAttribute("Password", settings->Password);
    xmlWriter.writeAttribute("HostName", settings->HostName);
    xmlWriter.writeAttribute("Port", settings->Port);
    xmlWriter.writeAttribute("Language", settings->Language);

    xmlWriter.writeEndElement();
    xmlWriter.writeEndElement();

    xmlWriter.writeEndDocument();

    file.close();

    return true;
}

void DialogSettingsTray::on_btnSave_clicked()
{
    if(ui->cmbLanguage->currentText() == QStringLiteral("English"))
    {
        settings->Language = "ENG";
    }
    else
    {
        settings->Language = "RUS";
    }

    settings->NameDB = ui->editNameDB->text();
    settings->HostName = ui->editHostName->text();
    settings->Port = ui->editPort->text();
    settings->UserName = ui->editUserName->text();
    settings->Password = ui->editPassword->text();

    saveSettings();

    ui->btnCheckDB->setEnabled(true);

    this->accept();
}

void DialogSettingsTray::on_cmbLanguage_currentIndexChanged(int index)
{
    ui->btnSave->setEnabled(true);
}

void DialogSettingsTray::on_DialogSettingsTray_accepted()
{
    QString language;

    if(settings->Language == "ENG")
        language = QString("en_EN");
    else
        language = QString("ru_RU");

    emit signal_LanguageChanged(language);
}

void DialogSettingsTray::on_editNameDB_textChanged(const QString &arg1)
{
    ui->btnSave->setEnabled(true);
    ui->btnCheckDB->setEnabled(false);
    flSettingsServerChanged = true;
}

void DialogSettingsTray::on_editHostName_textChanged(const QString &arg1)
{
    ui->btnSave->setEnabled(true);
    ui->btnCheckDB->setEnabled(false);
    flSettingsServerChanged = true;
}

void DialogSettingsTray::on_editPort_textChanged(const QString &arg1)
{
    ui->btnSave->setEnabled(true);
    ui->btnCheckDB->setEnabled(false);
    flSettingsServerChanged = true;
}

void DialogSettingsTray::on_editUserName_textChanged(const QString &arg1)
{
    ui->btnSave->setEnabled(true);
    ui->btnCheckDB->setEnabled(false);
    flSettingsServerChanged = true;
}

void DialogSettingsTray::on_editPassword_textChanged(const QString &arg1)
{
    ui->btnSave->setEnabled(true);
    ui->btnCheckDB->setEnabled(false);
    flSettingsServerChanged = true;
}

void DialogSettingsTray::on_checkLocalhost_stateChanged(int arg1)
{
    if(arg1)
    {
        ui->editHostName->setText("localhost");
        ui->editHostName->setEnabled(false);
    }
    else
    {
        ui->editHostName->setText("0.0.0.0");
        ui->editHostName->setEnabled(true);
    }
}

void DialogSettingsTray::on_btnCheckDB_clicked()
{
    //Проверяем, установлен ли PostgreSQL
    if(!providerDBLMS->checkDriverQPSQLavailable())
    {
        QMessageBox::critical(this, tr("Error!"), tr("Driver PostgreSQL is not installed!"));
        return;
    }

    //Запрос Логина и Пароля Суперюзера PostgreSQL (postgres)
    QString UserNamePostgres;
    QString PasswordPostgres;

    DialogAuthorization dlg(this);
    dlg.setWindowTitle(tr("Superuser PostgreSQL authorization"));
    dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    dlg.setStyleSheet(this->styleSheet());
    dlg.setLogin("postgres");
    dlg.setPassword("");

    switch( dlg.exec() )
    {
    case QDialog::Accepted:
    {
        UserNamePostgres = dlg.getLogin();
        PasswordPostgres = dlg.getPassword();

        break;
    }
    case QDialog::Rejected:
        return;
    default:
        return;
    }

    if(providerDBLMS->setUserPasswordPostgres(UserNamePostgres, PasswordPostgres))
    {
        DialogCheckDB dlgCheckDB(providerDBLMS, this);
        dlgCheckDB.setWindowFlags(dlgCheckDB.windowFlags() & ~Qt::WindowContextHelpButtonHint);

        switch( dlgCheckDB.exec() )
        {
        case QDialog::Accepted:
            ui->btnSave->setEnabled(true);
            flSettingsServerChanged = true;
            break;
        case QDialog::Rejected:
            break;
        default:
            break;
        }
    }
    else
    {
        if(settings->HostName == "localhost")
            QMessageBox::critical(this, tr("Error!"), tr("Error connecting to PostgreSQL!") + "\n\n" +
                                        tr("Possible reasons:") + "\n" +
                                        tr("*superuser PostgreSQL login or password is incorrect;") + "\n" +
                                        tr("*Port is incorrect."));
        else
            QMessageBox::critical(this, tr("Error!"), tr("Error connecting to PostgreSQL!") + "\n\n" +
                                        tr("Possible reasons:") + "\n" +
                                        tr("*superuser PostgreSQL login or password is incorrect;") + "\n" +
                                        tr("*Port is incorrect;") + "\n" +
                                        tr("*file 'pg_hba.conf' does not contain an entry for the IP address:") + settings->HostName + ".");
        return;
    }
}

void DialogSettingsTray::on_btnUpdateDocs_clicked()
{
    emit signal_UpdateDocs();
}
