 /**************************************************************************
 * Copyright (C) 2015-2017 by Savoir-faire Linux                           *
 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
 * Author: Anthony Léonard <anthony.leonard@savoirfairelinux.com>          *
 * Author: Olivier Soldano <olivier.soldano@savoirfairelinux.com>          *
 *                                                                         *
 * This program is free software; you can redistribute it and/or modify    *
 * it under the terms of the GNU General Public License as published by    *
 * the Free Software Foundation; either version 3 of the License, or       *
 * (at your option) any later version.                                     *
 *                                                                         *
 * This program is distributed in the hope that it will be useful,         *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 * GNU General Public License for more details.                            *
 *                                                                         *
 * You should have received a copy of the GNU General Public License       *
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
 **************************************************************************/

#include "wizarddialog.h"
#include "ui_wizarddialog.h"

#include <QMovie>
#include <QMessageBox>

#include "accountmodel.h"
#include "account.h"
#include "profilemodel.h"
#include "profile.h"
#include "namedirectory.h"

#include "utils.h"

const QString DEFAULT_RING_ACCT_ALIAS = QObject::tr("Ring account", "Default alias for new Ring account");

WizardDialog::WizardDialog(WizardMode wizardMode, Account* toBeMigrated, QWidget* parent) :
    QDialog(parent),
    ui(new Ui::WizardDialog),
    account_(toBeMigrated),
    wizardMode_(wizardMode),
    nameLookupTimer_(this)
{
    ui->setupUi(this);

    Qt::WindowFlags flags = windowFlags();
    flags = flags & (~Qt::WindowContextHelpButtonHint);

    setWindowFlags(flags);

    QPixmap logo(":/images/logo-ring-standard-coul.png");

    ui->welcomeLogo->setPixmap(logo.scaledToHeight(65, Qt::SmoothTransformation));
    ui->welcomeLogo->setAlignment(Qt::AlignHCenter);

    ui->fullNameEdit->setText(Utils::GetCurrentUserName());

    movie_ = new QMovie(":/images/loading.gif");
    ui->spinnerLabel->setMovie(movie_);
    movie_->start();

    if (wizardMode_ == MIGRATION) {
        ui->stackedWidget->setCurrentWidget(ui->profilePage);
        ui->usernameEdit->setEnabled(false);
        ui->usernameEdit->setText(toBeMigrated->displayName());
        ui->previousButton->hide();
        ui->photoBooth->hide();
        ui->pinEdit->hide();
        ui->infoLabel->setText(tr("Your account needs to be migrated. Enter your password."));
    } else {
        ui->navBarWidget->hide();
    }

    ui->searchingStateLabel->clear();
    connect(&NameDirectory::instance(), SIGNAL(registeredNameFound(Account*,NameDirectory::LookupStatus,const QString&,const QString&)),
            this, SLOT(handle_registeredNameFound(Account*,NameDirectory::LookupStatus,const QString&,const QString&)));

    nameLookupTimer_.setSingleShot(true);
    connect(&nameLookupTimer_, QTimer::timeout, this, WizardDialog::timeoutNameLookupTimer);
    connect(ui->photoBooth, &PhotoboothWidget::photoTaken, this, WizardDialog::on_photoTaken);
    ui->avatarLabel->hide();
    ui->disablePassword->setChecked(false);

    connect(ui->disablePassword, QCheckBox::stateChanged, [=](int state){
        if (state == Qt::Checked){
            ui->passwordEdit->setEnabled(false);
            ui->passwordEdit->clear();
            ui->confirmPasswordEdit->setEnabled(false);
            ui->confirmPasswordEdit->clear();
        } else if (Qt::Unchecked || Qt::PartiallyChecked) {
            ui->passwordEdit->setEnabled(true);
            ui->confirmPasswordEdit->setEnabled(true);
        }
    });
}

WizardDialog::~WizardDialog()
{
    disconnect(&NameDirectory::instance(), SIGNAL(registeredNameFound(Account*,NameDirectory::LookupStatus,const QString&,const QString&)),
               this, SLOT(handle_registeredNameFound(Account*,NameDirectory::LookupStatus,const QString&,const QString&)));
    delete ui;
}

void
WizardDialog::accept()
{
    if (ui->pinEdit->isVisible() && ui->pinEdit->text().isEmpty()) {
        ui->pinEdit->setStyleSheet("border-color: rgb(204, 0, 0);");
        return;
    }

    if (ui->disablePassword->checkState() == Qt::Checked) {
        ui->passwordEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
        ui->confirmPasswordEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
    } else if (ui->passwordEdit->text().isEmpty() ||
               ui->passwordEdit->text() != ui->confirmPasswordEdit->text()) {
        ui->passwordEdit->setStyleSheet("border-color: rgb(204, 0, 0);");
        ui->confirmPasswordEdit->setStyleSheet("border-color: rgb(204, 0, 0);");
        return;
    } else {
        ui->passwordEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
        ui->confirmPasswordEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
        ui->pinEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
    }

    if (wizardMode_ == MIGRATION)
        ui->progressLabel->setText(tr("Migrating your Ring account..."));
    else
        ui->progressLabel->setText(tr("Generating your Ring account..."));

    ui->navBarWidget->hide();
    ui->stackedWidget->setCurrentWidget(ui->spinnerPage);

    auto profile = ProfileModel::instance().selectedProfile();

    repaint();

    Utils::CreateStartupLink();

    if (account_ == nullptr) {
        QString accountAlias = (ui->usernameEdit->text().isEmpty())? DEFAULT_RING_ACCT_ALIAS : ui->usernameEdit->text();
        account_ = AccountModel::instance().add(accountAlias, Account::Protocol::RING);
        if (not ui->fullNameEdit->text().isEmpty()) {
            account_->setDisplayName(ui->fullNameEdit->text());
            profile->person()->setFormattedName(ui->fullNameEdit->text());
        }
        else {
            profile->person()->setFormattedName(tr("Unknown"));
        }
    }

    account_->setRingtonePath(Utils::GetRingtonePath());
    account_->setUpnpEnabled(true);

    account_->setArchivePassword(ui->passwordEdit->text());
    ui->passwordEdit->setEnabled(false);
    ui->confirmPasswordEdit->setEnabled(false);

    if (not ui->pinEdit->text().isEmpty()) {
        account_->setArchivePin(ui->pinEdit->text());
    }

    connect(account_, SIGNAL(stateChanged(Account::RegistrationState)), this, SLOT(endSetup(Account::RegistrationState)));

    account_->performAction(Account::EditAction::SAVE);

    profile->setAccounts({account_});
    profile->save();
}

void
WizardDialog::endSetup(Account::RegistrationState state)
{
    switch (state) {
    case Account::RegistrationState::READY:
    {
        if (ui->signUpCheckbox->isChecked()) { // If the user wants to register its name on the blockchain
            bool regSuccess = account_->registerName(ui->passwordEdit->text(), ui->usernameEdit->text());
            if (!regSuccess) usernameFailedRegistration();
            else {
                connect(account_, SIGNAL(nameRegistrationEnded(NameDirectory::RegisterNameStatus,QString)),
                        this, SLOT(handle_nameRegistrationEnded(NameDirectory::RegisterNameStatus,QString)));
                ui->progressLabel->setText(tr("Registering your public username, it may take a few minutes..."));

            }
        } else {
            account_->performAction(Account::EditAction::RELOAD);
            QDialog::accept();
        }
        break;
    }
    case Account::RegistrationState::UNREGISTERED:
    case Account::RegistrationState::TRYING:
    case Account::RegistrationState::COUNT__:
        break;
    }
}

void
WizardDialog::closeEvent(QCloseEvent* event)
{
    Q_UNUSED(event);
    if (wizardMode_ == WIZARD){
        done(QDialog::Rejected);
    } else {
        QDialog::closeEvent(event);
    }
}

void
WizardDialog::usernameFailedRegistration()
{
    QMessageBox::warning(this, "Username not registered", "Your account has been created, but we could not register your username. Try again from the settings menu.");
}

void
WizardDialog::on_photoTaken(QString fileName)
{
    auto image = QImage(fileName);
    auto avatar = image.scaled(100, 100, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
    ProfileModel::instance().selectedProfile()->person()->setPhoto(avatar);
    ui->avatarLabel->setPixmap(QPixmap::fromImage(Utils::getCirclePhoto(avatar, ui->avatarLabel->width())));
    ui->photoBooth->stopBooth();
    ui->avatarLabel->show();
}

void
WizardDialog::on_existingPushButton_clicked()
{
    changePage(true);
}

void
WizardDialog::on_newAccountButton_clicked()
{
    changePage(false);
}

void
WizardDialog::changePage(bool existingAccount)
{
    if (existingAccount) { // If user want to add a device
        ui->accountLabel->setText(tr("Add a device"));
        ui->stackedWidget->setCurrentWidget(ui->explanationPage);
        ui->photoBooth->hide();
    } else { // If user want to create a new account
        ui->accountLabel->setText(tr("Create your account"));
        ui->stackedWidget->setCurrentWidget(ui->profilePage);
        ui->photoBooth->startBooth();
        ui->photoBooth->show();
    }
    ui->navBarWidget->show();
    ui->avatarLabel->setHidden(true);
    ui->infoLabel->setHidden(existingAccount);
    ui->usernameEdit->setHidden(existingAccount);
    ui->signUpCheckbox->setHidden(existingAccount);
    ui->signUpCheckbox->setChecked(!existingAccount);
    ui->confirmPasswordEdit->setHidden(existingAccount);
    ui->searchingStateLabel->setHidden(existingAccount);

    ui->pinEdit->setVisible(existingAccount);
}

void
WizardDialog::on_nextButton_clicked()
{
    const QWidget* curWidget = ui->stackedWidget->currentWidget();

    if (curWidget == ui->profilePage) {
        ui->stackedWidget->setCurrentWidget(ui->accountPage);
    }
    else if (curWidget == ui->explanationPage) {
        ui->stackedWidget->setCurrentWidget(ui->accountPage);
    }
    else if (curWidget == ui->accountPage) {
        accept();
    }
}

void
WizardDialog::on_previousButton_clicked()
{
    const QWidget* curWidget = ui->stackedWidget->currentWidget();

    if (curWidget == ui->profilePage) {
        ui->navBarWidget->hide();
        ui->stackedWidget->setCurrentWidget(ui->welcomePage);
    }
    else if (curWidget == ui->explanationPage) {
        ui->navBarWidget->hide();
        ui->stackedWidget->setCurrentWidget(ui->welcomePage);
    }
    else if (curWidget == ui->accountPage) {
        if (ui->pinEdit->isVisible()) // If we are adding a device
            ui->stackedWidget->setCurrentWidget(ui->explanationPage);
        else // If we are creating a new account
            ui->stackedWidget->setCurrentWidget(ui->profilePage);
    }

    ui->passwordEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
    ui->confirmPasswordEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
    ui->pinEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
}

void
WizardDialog::on_passwordEdit_textChanged(const QString& arg1)
{
    Q_UNUSED(arg1)

    if (ui->pinEdit->isVisible()) {
        ui->confirmPasswordEdit->setText(ui->passwordEdit->text());
    }
}

void
WizardDialog::on_usernameEdit_textChanged(const QString &arg1)
{
    Q_UNUSED(arg1)
    if(ui->signUpCheckbox->isChecked() && !arg1.isEmpty()) {
        ui->searchingStateLabel->setText(tr("Searching..."));
        nameLookupTimer_.start(1500);
    } else {
        ui->searchingStateLabel->clear();
        nameLookupTimer_.stop();
    }
}

void
WizardDialog::timeoutNameLookupTimer()
{
    if(ui->signUpCheckbox->isChecked() && !ui->usernameEdit->text().isEmpty()) {
        NameDirectory::instance().lookupName(nullptr, QString(), ui->usernameEdit->text());
    } else {
        ui->searchingStateLabel->clear();
    }
}

void
WizardDialog::handle_registeredNameFound (Account* account, NameDirectory::LookupStatus status, const QString& address, const QString& name)
{
    Q_UNUSED(account)
    Q_UNUSED(address)
    Q_UNUSED(name)
#pragma push_macro("ERROR")
#undef ERROR
    switch(status) {
    case NameDirectory::LookupStatus::SUCCESS:
        ui->searchingStateLabel->setText(tr("Username not available."));
        break;
    case NameDirectory::LookupStatus::NOT_FOUND:
        ui->searchingStateLabel->setText(tr("Username is available."));
        break;
    case NameDirectory::LookupStatus::INVALID_NAME:
        ui->searchingStateLabel->setText(tr("Username is invalid."));
        break;
    case NameDirectory::LookupStatus::ERROR:
        ui->searchingStateLabel->setText(tr("Network error."));
        break;
    }
#pragma pop_macro("ERROR")
}

void
WizardDialog::handle_nameRegistrationEnded(NameDirectory::RegisterNameStatus status, const QString& name)
{
    Q_UNUSED(name)

    disconnect(account_, SIGNAL(nameRegistrationEnded(NameDirectory::RegisterNameStatus,QString)),
               this, SLOT(handle_nameRegistrationEnded(NameDirectory::RegisterNameStatus,QString)));
    if(status != NameDirectory::RegisterNameStatus::SUCCESS) {
        usernameFailedRegistration();
    }
    account_->performAction(Account::EditAction::RELOAD);
    QDialog::accept();
}

void WizardDialog::on_signUpCheckbox_toggled(bool checked)
{
    if (checked) {
        ui->usernameEdit->setEnabled(true);
    } else {
        ui->usernameEdit->setEnabled(false);
        ui->usernameEdit->clear();
    }
}
