#include "activatorwindow.h"

#include <QDebug>
#include <QStack>
#include <QDate>
#include <QTimer>
#include <QPainter>
#include <QLabel>
#include <QFileDialog>
#include <QDesktopServices>

#include <DTitlebar>
#include <ddialog.h>
#include <dlineedit.h>
#include <DThemeManager>
#include <dbasebutton.h>
#include <DWidgetUtil>
#include <DStandardPaths>
#include <DHiDPIHelper>

#include "uihelper.h"
#include "licensewindow.h"

DWIDGET_USE_NAMESPACE

QString randomColor()
{
    static int index = 0;
    index++;
    int colorIndex = index % 5;
    switch (colorIndex) {
    case 0:
        return "red";
    case 1:
        return "green";
    case 2:
        return "blue";
    case 3:
        return "yellow";
    case 4:
        return "grey";
    default:
        return "black";
    }
}

#define LAYOUT_DEBUG

#ifdef LAYOUT_DEBUG
#define DBG(widget) widget->setStyleSheet(QString("%1background:%2;border: 1px solid %3").arg(widget->styleSheet()).arg(randomColor()).arg(randomColor()))
#else
#define DBG(widget) while(0){}
#endif

class ActivatorWindowPrivate
{
public:
    ActivatorWindowPrivate(ActivatorWindow *parent) : q_ptr(parent) {}

    void initUI();
    void setBackground(const QPixmap &pixmap);
    DThinVBoxLayout *initHeader(const QString &titleText);
    QWidget *createActions(QList<QWidget *> buttons);
    QWidget *createAuthorizeInfo();
    QWidget *createCompanyInfo();
    QWidget *createLicenseAction();
    QWidget *wrapLayout(QLayout *layout);

    void replaceCentralWidget(QWidget *view);
    void replaceRootView(QWidget *view);
    void pushView(QWidget *view);
    void pushToRootView(QWidget *view);
    void popView();
    void popToRootView();

    QWidget *createGenerateCodeView();
    QWidget *createGenerateSuccessView();
    QWidget *createUnactiveView();
    QWidget *createInputSerialView();
    QWidget *createImportFileView();
    QWidget *createActiveFailedView();
    QWidget *createActiveView();
    QWidget *createUpdateLicenseView();

    QPushButton *backBt             = Q_NULLPTR;

    QStack<QWidget *> viewStack;
    QWidget *unactiveView           = Q_NULLPTR;
    QWidget *activeView             = Q_NULLPTR;
    QWidget *inputSerialView        = Q_NULLPTR;
    QWidget *importFileView         = Q_NULLPTR;
    QWidget *activeFailedView       = Q_NULLPTR;
    QWidget *updateLicenseView      = Q_NULLPTR;
    QWidget *generateCodeView       = Q_NULLPTR;
    QWidget *generateSuccessView    = Q_NULLPTR;
    LicenseWindow *law              = Q_NULLPTR;

    DLineEdit                   *key1;
    DLineEdit                   *key2;
    DLineEdit                   *key3;
    DLineEdit                   *key4;

    QPixmap backgroundPixmap;

    ActivatorWindow *q_ptr;
    Q_DECLARE_PUBLIC(ActivatorWindow)
};

ActivatorWindow::ActivatorWindow(QWidget *parent) :
    Dtk::Widget::DMainWindow(parent), d_ptr(new ActivatorWindowPrivate(this))
{
    Q_D(ActivatorWindow);
    DThemeManager::registerWidget(this);

    d->initUI();
    setFixedSize(880, 700);
}

ActivatorWindow::~ActivatorWindow()
{

}

void ActivatorWindow::onActiveStateChanged(const LicenseModel &model)
{
    Q_D(ActivatorWindow);
//    qDebug() << model.system.version << model.license.actived;
    Q_EMIT updateView(model);

    if (model.license.actived) {
        if (centralWidget() == d->unactiveView) {
            d->pushToRootView(d->activeView);
        } else {
            d->replaceRootView(d->activeView);
        }
    } else  {
        if (centralWidget() == d-> activeView) {
            d->pushToRootView(d->unactiveView);
        } else {
            d->replaceRootView(d->unactiveView);
        }
    }

    update();
}

void ActivatorWindow::onLicenseImported(quint32 success, const LicenseModel &model)
{
    Q_D(ActivatorWindow);
//    qDebug() << model.system.version << model.license.actived;
    Q_EMIT updateView(model);

    auto successView = model.license.actived ? d->activeView : d->unactiveView;
    if (0 == success) {
        d->pushToRootView(successView);
    } else {
        d->pushView(d->activeFailedView);
    }

    update();
}

void ActivatorWindow::onInformationExported(bool success)
{
    Q_EMIT exportInformation(success);
}

void ActivatorWindow::onLogLinkActivated(const QString &link)
{
    if (link == "https://www.deepin.com") {
        QDesktopServices::openUrl(QUrl(link));
    }
}

void ActivatorWindow::paintEvent(QPaintEvent *)
{
    Q_D(ActivatorWindow);
    QPainter p(this);
    p.drawPixmap(rect(), d->backgroundPixmap);
}

void ActivatorWindowPrivate::initUI()
{
    Q_Q(ActivatorWindow);

    backBt = new QPushButton(q);
    backBt->setObjectName("BackButton");
    backBt->setFixedSize(25, 26);

    auto flags = q->windowFlags() & ~Qt::WindowMaximizeButtonHint;
    flags &= ~Qt::WindowSystemMenuHint;
    q->overrideWindowFlags(flags);
    q->titlebar()->setBackgroundTransparent(true);
    q->titlebar()->setCustomWidget(backBt, Qt::AlignLeft, false);

    q->connect(backBt, &QPushButton::clicked, q, [ = ]() {
        popToRootView();
    });

    unactiveView = createUnactiveView();
    activeView = createActiveView();
    inputSerialView = createInputSerialView();
    importFileView = createImportFileView();
    activeFailedView = createActiveFailedView();
    updateLicenseView = createUpdateLicenseView();
    generateCodeView = createGenerateCodeView();
    generateSuccessView = createGenerateSuccessView();

    setBackground(DHiDPIHelper::loadNxPixmap(":/view/resources/bg.svg"));
    pushView(unactiveView);
}

void ActivatorWindowPrivate::setBackground(const QPixmap &pixmap)
{
    backgroundPixmap = pixmap;
}

QWidget *ActivatorWindowPrivate::wrapLayout(QLayout *layout)
{
    auto wrapWidget = new QWidget;
    wrapWidget->setLayout(layout);
    return wrapWidget;
}

QWidget *ActivatorWindowPrivate::createCompanyInfo()
{
    Q_Q(ActivatorWindow);

    auto companyInfo = new QWidget;
    companyInfo->setFixedHeight(45);
    QLabel *website = new QLabel(q);
    website->setStyleSheet("font-size:14px; color: red;");
    website->setOpenExternalLinks(false);
    website->setText("<a href='https://www.deepin.com' style='font-size:14px; text-decoration: none; color: #2e70ff;'>www.deepin.com</a>");
    website->connect(website, SIGNAL(linkActivated(QString)),
                     q, SLOT(onLogLinkActivated(QString)));
    QLabel *copyright = new QLabel(ActivatorWindow::tr("Copyright © 2011-%1 Wuhan Deepin Technology Co., Ltd.").arg(QDate::currentDate().year()));
    copyright->setStyleSheet("font-size:12px;");

    auto activeHitscompanyLayout = new DThinVBoxLayout(companyInfo);
    activeHitscompanyLayout->addWidget(website);
    activeHitscompanyLayout->setAlignment(website, Qt::AlignCenter);
    activeHitscompanyLayout->addStretch();
    activeHitscompanyLayout->addWidget(copyright);
    activeHitscompanyLayout->setAlignment(copyright, Qt::AlignCenter);

    return companyInfo;
}

QWidget *ActivatorWindowPrivate::createLicenseAction()
{
    Q_Q(ActivatorWindow);
    auto layout = new QVBoxLayout;
    auto inputSerialBt = new QPushButton(ActivatorWindow::tr("Input the serial number"));
    inputSerialBt->setObjectName("WhiteButton");
    inputSerialBt->connect(inputSerialBt, &DBaseButton::clicked, q, [ = ]() {
        pushView(inputSerialView);
        key1->setFocus();
        key1->selectAll();
    });

    auto importLicenseBt = new DBaseButton(ActivatorWindow::tr("Import the authrization file"));
    inputSerialBt->connect(importLicenseBt, &DBaseButton::clicked, q, [ = ]() {
        pushView(importFileView);
    });

    auto generateMachineCodeBt = new QPushButton(ActivatorWindow::tr("Generate a machine code"));
    generateMachineCodeBt->setObjectName("WhiteButton");
    generateMachineCodeBt->connect(generateMachineCodeBt, &DBaseButton::clicked, q, [ = ]() {
        pushView(generateCodeView);
    });

    auto activeBt = new DBaseButton(ActivatorWindow::tr("Activate Now"));
    activeBt->connect(activeBt, &DBaseButton::clicked, q, [ = ]() {
        pushView(importFileView);
    });

    auto serverAction = createActions({generateMachineCodeBt, activeBt});
    auto desktopAction = createActions({ inputSerialBt, importLicenseBt});

    q->connect(q, &ActivatorWindow::updateView, [ = ](const LicenseModel & model) {
        switch (model.system.systemType) {
        case Desktop:
            desktopAction->show();
            serverAction->hide();
            break;
        //    case Server:
        default:
            serverAction->show();
            desktopAction->hide();
        }
    });

    layout->addWidget(serverAction);
    layout->addWidget(desktopAction);

    return wrapLayout(layout);
}

DThinVBoxLayout *ActivatorWindowPrivate::initHeader(const QString &titleText)
{
    auto layout = new DThinVBoxLayout;
    auto title = new QLabel(titleText);
    title->setObjectName("Title");

    QLabel *logo = new QLabel;
    logo->setObjectName("Logo");
    logo->setFixedSize(QPixmap(":/view/resources/logo.svg").size());
    logo->setPixmap(DHiDPIHelper::loadNxPixmap(":/view/resources/logo.svg"));

    layout->addSpacing(48);
    layout->addWidget(title, 0, Qt::AlignCenter);
    layout->addSpacing(96);
    layout->addWidget(logo, 0, Qt::AlignCenter);
    layout->addSpacing(20);
    return layout;
}

QWidget *ActivatorWindowPrivate::createActions(QList<QWidget *> buttons)
{
    auto actionWidget = new QWidget;
    actionWidget->setFixedHeight(90);
    auto actionLayout = new DThinHBoxLayout(actionWidget);

    actionLayout->addSpacing(40);
    for (auto button : buttons) {
        button->setFixedSize(180, 36);
        actionLayout->addWidget(button);
        actionLayout->setAlignment(button, Qt::AlignHCenter | Qt::AlignTop);
        actionLayout->addSpacing(40);
    }
    actionLayout->addStretch();

    actionWidget->setTabOrder(buttons.last(), buttons.first());
    return actionWidget;
}

QWidget *ActivatorWindowPrivate::createAuthorizeInfo()
{
    Q_Q(ActivatorWindow);
    auto authorizeInfo = new QWidget;
    authorizeInfo->setFixedHeight(108);
    auto authorizeInfoLayout = new QGridLayout(authorizeInfo);
    authorizeInfoLayout->setMargin(0);
    authorizeInfoLayout->setHorizontalSpacing(10);
    authorizeInfoLayout->setVerticalSpacing(0);

    auto addInfoKey = [ = ](const QString & text, int row, int column) ->QWidget* {
        auto keyInfo = new QLabel(text);
        keyInfo->setFixedWidth(q->width() / 2 - 32 - 16);
        keyInfo->setObjectName("InfoKey");
        keyInfo->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
        keyInfo->setFixedHeight(16);
        authorizeInfoLayout->addWidget(keyInfo, row, column);
        authorizeInfoLayout->setRowMinimumHeight(row, 16);
        return keyInfo;
    };

    auto addInfoValue = [ = ](const QString & text, int row, int column) -> QLabel* {
        QLabel *valueInfo = new QLabel(text);
        valueInfo->setFixedWidth(q->width() / 2 - 32 - 16);
        valueInfo->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
        valueInfo->setObjectName("InfoValue");
        valueInfo->setFixedHeight(16);
        authorizeInfoLayout->addWidget(valueInfo, row, column);
        return valueInfo;
    };

    addInfoKey(ActivatorWindow::tr("Product Name:"), 0, 0);
    addInfoKey(ActivatorWindow::tr("Edition:"), 1, 0);
    addInfoKey(ActivatorWindow::tr("Authorization State:"), 2, 0);
    auto ownerKey = addInfoKey(ActivatorWindow::tr("Authorized User:"), 3, 0);

    auto productValue = addInfoValue("", 0, 1);
    auto editionValue = addInfoValue("", 1, 1);
    auto stateValue = addInfoValue("", 2, 1);
    auto ownerValue = addInfoValue("", 3, 1);

    q->connect(q, &ActivatorWindow::updateView, [ = ](const LicenseModel & model) {
        productValue->setText(model.system.localeEdition);
        editionValue->setText(model.system.version);
        if (model.license.actived) {
            stateValue->setText(ActivatorWindow::tr("Authorized"));
        } else {
            stateValue->setText(ActivatorWindow::tr("Free trial"));
        }

        if (model.license.organization.isEmpty() || !model.license.actived) {
            ownerKey->hide();
            ownerValue->hide();
        } else {
            ownerKey->show();
            ownerValue->show();
            ownerValue->setText(model.license.organization);
        }
    });
    return authorizeInfo;
}


void ActivatorWindowPrivate::replaceCentralWidget(QWidget *view)
{
    Q_Q(ActivatorWindow);
    if (!view) {
        return;
    }

    if (q->centralWidget()) {
        if (q->centralWidget() == view) {
            return;
        }
        q->centralWidget()->hide();
        q->takeCentralWidget();
    }
    q->setCentralWidget(view);
    view->show();
}

void ActivatorWindowPrivate::replaceRootView(QWidget *view)
{
    if (viewStack.size() < 1) {
        return;
    }

    viewStack.replace(0, view);
}

void ActivatorWindowPrivate::pushView(QWidget *view)
{
    viewStack.push(view);
    backBt->setVisible(viewStack.size() > 1);
    replaceCentralWidget(view);
}

void ActivatorWindowPrivate::pushToRootView(QWidget *view)
{
    viewStack.clear();
    pushView(view);
}

void ActivatorWindowPrivate::popView()
{
    if (viewStack.size() <= 1) {
        return;
    }

    viewStack.pop();
    backBt->setVisible(viewStack.size() > 1);

    auto view = viewStack.top();
    replaceCentralWidget(view);
}

void ActivatorWindowPrivate::popToRootView()
{
    while (viewStack.size() > 1) {
        viewStack.pop();
    }
    backBt->setVisible(viewStack.size() > 1);
    if (viewStack.size()) {
        auto view = viewStack.top();
        replaceCentralWidget(view);
    }
}

QWidget *ActivatorWindowPrivate::createGenerateCodeView()
{
    Q_Q(ActivatorWindow);
    auto centralLayout = initHeader(ActivatorWindow::tr("Generate a machine code"));

    QLabel *titleFailedHint = new QLabel(ActivatorWindow::tr("Your machine code is:"));
    titleFailedHint->setObjectName("HelpHint");

    QLabel *machineCode = new QLabel();
    machineCode->setObjectName("MachineCode");
    machineCode->setFixedHeight(36);

    QLabel *helpHint = new QLabel(ActivatorWindow::tr("You can export the machine code by copying or clicking on the \"Export\" button, and then send it to your sales representative or support specialist."));
    helpHint->setObjectName("HelpHint");
    helpHint->setFixedSize(600, 50);
    helpHint->setWordWrap(true);

    auto importBt = new DBaseButton(ActivatorWindow::tr("Export"));
    importBt->connect(importBt, &DBaseButton::clicked, q, [ = ]() {
        importBt->setDisabled(true);

        QString code =  machineCode->text();
        QDir desktopDir(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first());
        QString infoFilename = desktopDir.absoluteFilePath(code + ".info");

        QFileDialog fileDlg(q);
        fileDlg.setViewMode(QFileDialog::Detail);
        fileDlg.setAcceptMode(QFileDialog::AcceptSave);
        fileDlg.setDirectory(desktopDir.path());
        fileDlg.setNameFilter("INFO (*.info)");
        fileDlg.setLabelText(QFileDialog::Reject,  ActivatorWindow::tr("Cancel"));
        fileDlg.selectFile(infoFilename);
        if (QFileDialog::Accepted != fileDlg.exec()) {
            importBt->setDisabled(false);
            return;
        }

        infoFilename = fileDlg.selectedUrls().value(0).toLocalFile();

        Q_EMIT q->requestExportInformation(infoFilename);
    });

    q->connect(q, &ActivatorWindow::exportInformation, [ = ](bool success) {
        importBt->setDisabled(false);

        if (success) {
            pushView(generateSuccessView);
        } else {
            DDialog dialog(ActivatorWindow::tr("Export Computer Infornamtion Failed!"),
                           ActivatorWindow::tr("Can not get machine code"),
                           q);
            dialog.setIconPixmap(QIcon(":/view/resources/deepin-activator.svg").pixmap(48, 48));
            dialog.exec();
        }
    });

    q->connect(q, &ActivatorWindow::updateView, [ = ](const LicenseModel & model) {
        machineCode->setText(model.system.machineCode);
    });

    centralLayout->addStretch();
    centralLayout->addWidget(titleFailedHint, 0, Qt::AlignCenter);
    centralLayout->addSpacing(16);
    centralLayout->addWidget(machineCode, 0, Qt::AlignCenter);
    centralLayout->addWidget(helpHint, 0, Qt::AlignCenter);
    centralLayout->addStretch();
    centralLayout->addWidget(createActions({importBt}), 0, Qt::AlignCenter);

    return wrapLayout(centralLayout);
}

QWidget *ActivatorWindowPrivate::createGenerateSuccessView()
{
    Q_Q(ActivatorWindow);
    auto centralLayout = initHeader(ActivatorWindow::tr("Generate a machine code"));

    QLabel *titleFailedHint = new QLabel(ActivatorWindow::tr("Machine code successfully exported"));
    titleFailedHint->setObjectName("ExportTitle");
    titleFailedHint->setFixedHeight(55);

    QLabel *helpHint = new QLabel(ActivatorWindow::tr("Please send the machine code to your sales representative or support specialist, we will provide an activation file according to the machine code to help you activate your computer."));
    helpHint->setObjectName("HelpHint");
    helpHint->setWordWrap(true);
    helpHint->setFixedSize(600, 60);

    auto finishBt = new DBaseButton(ActivatorWindow::tr("Finish"));
    finishBt->connect(finishBt, &DBaseButton::clicked, q, [ = ]() {
        popToRootView();
    });

    centralLayout->addStretch();
    centralLayout->addWidget(titleFailedHint, 0, Qt::AlignCenter);
    centralLayout->addSpacing(16);
    centralLayout->addWidget(helpHint, 0, Qt::AlignCenter);
    centralLayout->addStretch();
    centralLayout->addStretch();
    centralLayout->addWidget(createActions({finishBt}), 0, Qt::AlignCenter);

    return wrapLayout(centralLayout);
}

QWidget *ActivatorWindowPrivate::createUnactiveView()
{
//    Q_Q(ActivatorWindow);
    auto centralLayout = initHeader(ActivatorWindow::tr("Welcome to use"));

    auto stateHint = new QLabel(ActivatorWindow::tr("Not authorized"));
    stateHint->setObjectName("StateHint");

    centralLayout->addWidget(stateHint, 0, Qt::AlignCenter);
    centralLayout->addStretch();
    centralLayout->addWidget(createAuthorizeInfo(), 0, Qt::AlignCenter);
    centralLayout->addStretch();
    centralLayout->addWidget(createCompanyInfo(), 0, Qt::AlignCenter);
    centralLayout->addSpacing(30);
    centralLayout->addWidget(createLicenseAction(), 0, Qt::AlignCenter);

    return  wrapLayout(centralLayout);
}

QWidget *ActivatorWindowPrivate::createInputSerialView()
{
    Q_Q(ActivatorWindow);
    auto centralLayout = initHeader(ActivatorWindow::tr("Activate"));

    QLabel *inputHint = new QLabel(ActivatorWindow::tr("Please input the serial number:"));
    inputHint->setObjectName("SerialInputHint");
    inputHint->setFixedSize(470, 30);

    QString helpHintStr = ActivatorWindow::tr("You can authorize the system by inputting the serial number obtained from service providers or agents.");
//    helpHintStr.append(ActivatorWindow::tr("Welcome to call <font color=#004EE5>400-077-9127</font> if problems occurred in activation."));
    helpHintStr.append(ActivatorWindow::tr("Please contact your local distributor if problems occurred in authorization."));

    QLabel *helpHint = new QLabel(helpHintStr);
    helpHint->setObjectName("SerialHelpHint");
    helpHint->setFixedSize(470, 50);
    helpHint->setWordWrap(true);

    auto authorizeBt = new DBaseButton(ActivatorWindow::tr("Authorize"));
    authorizeBt->setDisabled(true);
    authorizeBt->connect(authorizeBt, &DBaseButton::clicked, q, [ = ]() {
        QString fullkey = key1->text() + key2->text() + key3->text() + key4->text();
        Q_EMIT q->importSerialKey(fullkey.toUpper());
    });

    auto validKey = [ = ](const QString & key, DLineEdit * nextKey) {
        int pos = 0;
        QString fullkey = key1->text() + key2->text() + key3->text() + key4->text();
        QRegExpValidator keyValidator(QRegExp("[A-Za-z0-9]{20}"));
        bool keyValid = !((keyValidator.validate(fullkey, pos) != QValidator::Acceptable));
        authorizeBt->setEnabled(keyValid);
        if (nextKey && key.length() >= 5) {
            nextKey->setFocus();
            nextKey->selectAll();
        }
    };

    auto v = new UpcaseValidator(q);

    auto addKey = [ = ](DLineEdit * nextKey) -> DLineEdit* {
        const int editWidth = 110;
        const int editHeight = 35;
        auto keyEdit = new DLineEdit;
        keyEdit->setAlignment(Qt::AlignCenter);
        keyEdit->setMaxLength(5);
        keyEdit->setValidator(v);
        keyEdit->setFixedSize(editWidth, editHeight);
        keyEdit->connect(keyEdit, &DLineEdit::textChanged,
        keyEdit, [ = ](const QString & keyText)
        {
            validKey(keyText, nextKey);
        });
        return keyEdit;
    };

    auto keyEditLayout = new DThinHBoxLayout;
    keyEditLayout->setSpacing(10);

    auto addKeys = [ = ]() {
        keyEditLayout->addWidget(key1);
        keyEditLayout->addWidget(new QLabel("-"));
        keyEditLayout->addWidget(key2);
        keyEditLayout->addWidget(new QLabel("-"));
        keyEditLayout->addWidget(key3);
        keyEditLayout->addWidget(new QLabel("-"));
        keyEditLayout->addWidget(key4);
    };

    key4 = addKey(Q_NULLPTR);
    key3 = addKey(key4);
    key2 = addKey(key3);
    key1 = addKey(key2);

    keyEditLayout->addStretch();
    addKeys();
    keyEditLayout->addStretch();

    centralLayout->addStretch();
    centralLayout->addWidget(inputHint, 0, Qt::AlignCenter);
    centralLayout->addSpacing(20);
    centralLayout->addLayout(keyEditLayout);
    centralLayout->addSpacing(20);
    centralLayout->addWidget(helpHint, 0, Qt::AlignCenter);
    centralLayout->addStretch();
    centralLayout->addWidget(createActions({authorizeBt}), 0, Qt::AlignCenter);

    return  wrapLayout(centralLayout);
}

QWidget *ActivatorWindowPrivate::createImportFileView()
{
    Q_Q(ActivatorWindow);
    auto centralLayout = initHeader(ActivatorWindow::tr("Activate"));

    QString helpHits = ActivatorWindow::tr("You can authorize the system by importing the authorization file obtained from service providers or agents.");
    helpHits.append("<br><br>XXXX-XXXX-XXXX-XXXX.key<br><br>");
//    helpHits.append(ActivatorWindow::tr("Welcome to call <font color=#004EE5>400-077-9127</font> if problems occurred in activation."));
    helpHits.append(ActivatorWindow::tr("Please contact your local distributor if problems occurred in authorization."));

    auto helpLabel = new QLabel(helpHits);
    helpLabel->setMinimumSize(550, 99);
    helpLabel->setObjectName("HelpHint");

    auto importBt = new DBaseButton(ActivatorWindow::tr("Import the authrization file"));
    importBt->connect(importBt, &DBaseButton::clicked, q, [ = ]() {
        QFileDialog fileDlg(q);
        fileDlg.setViewMode(QFileDialog::Detail);
        fileDlg.setFileMode(QFileDialog::ExistingFile);
        fileDlg.setNameFilter("KEY (*.key)");
        fileDlg.setLabelText(QFileDialog::Reject, ActivatorWindow::tr("Cancel"));
        if (QFileDialog::Accepted == fileDlg.exec()) {
            QString filepath = fileDlg.selectedFiles().first();
            QTimer::singleShot(5, [ = ] {
                Q_EMIT q->importLicenseFile(filepath);
            });
        }
    });

    centralLayout->addStretch();
    centralLayout->addWidget(helpLabel, 0, Qt::AlignCenter);
    centralLayout->addStretch();
    centralLayout->addWidget(createActions({importBt}), 0, Qt::AlignCenter);

    return wrapLayout(centralLayout);
}

QWidget *ActivatorWindowPrivate::createActiveFailedView()
{
    Q_Q(ActivatorWindow);
    auto centralLayout = initHeader(ActivatorWindow::tr("Activate"));

    QLabel *titleFailedHint = new QLabel(ActivatorWindow::tr("Invalid activation file"));
    titleFailedHint->setObjectName("FailedTitleHint");
    titleFailedHint->setFixedHeight(55);

    QLabel *helpHint = new QLabel(ActivatorWindow::tr("Please contact your sales representative or support specialist."));
    helpHint->setObjectName("SerialHelpHint");
    helpHint->setFixedSize(470, 50);
    helpHint->setWordWrap(true);

    auto importBt = new DBaseButton(ActivatorWindow::tr("Reimport"));
    importBt->connect(importBt, &DBaseButton::clicked, q, [ = ]() {
        popToRootView();
    });

    centralLayout->addStretch();
    centralLayout->addWidget(titleFailedHint, 0, Qt::AlignCenter);
    centralLayout->addWidget(helpHint, 0, Qt::AlignCenter);
    centralLayout->addStretch();
    centralLayout->addWidget(createActions({importBt}), 0, Qt::AlignCenter);

    return wrapLayout(centralLayout);
}

QWidget *ActivatorWindowPrivate::createActiveView()
{
    Q_Q(ActivatorWindow);

    auto centralLayout = initHeader(ActivatorWindow::tr("Welcome to use"));

    auto stateHint = new QLabel(ActivatorWindow::tr("Activated"));
    stateHint->setObjectName("SuccessStateHint");

    auto showLicense = new Label(ActivatorWindow::tr("Show License"));
    showLicense->connect(showLicense, &Label::clicked, [ = ]() {
        if (law) {
            law->show();
            law->move(0, 0);
            Dtk::Widget::moveToCenter(law);
        }
    });

    q->connect(q, &ActivatorWindow::updateView, [ = ](const LicenseModel & model) {
        if (!law)
            law = new LicenseWindow(QLocale::system().name(),
                                    model.system.localeCopyright,
                                    q);
    });

    auto deleteLicense = new Label(ActivatorWindow::tr("Delete Authorization"));
    deleteLicense->connect(deleteLicense, &Label::clicked, [ = ]() {
        DDialog deleteConfirm(ActivatorWindow::tr("Are you sure to delete the authorization?"),
                              (""), q);
        deleteConfirm.setIconPixmap(QIcon(":/view/resources/deepin-activator.svg").pixmap(48, 48));
        deleteConfirm.addButtons(QStringList() << ActivatorWindow::tr("Cancel") << ActivatorWindow::tr("Delete"));
        deleteConfirm.setDefaultButton(0);
        deleteConfirm.setMaximumWidth(400);
        auto actionIndex = deleteConfirm.exec();
        if (1 == actionIndex) {
            Q_EMIT q->deactive();
        }
    });

    auto *updateLicense = new Label(ActivatorWindow::tr("Update Authorization"));
    updateLicense->connect(updateLicense, &Label::clicked, [ = ]() {
        QTimer::singleShot(5, [ = ] {
            pushView(updateLicenseView);
        });
    });

    auto actionLayout = new DThinHBoxLayout;
    actionLayout->setSpacing(20);
    actionLayout->addWidget(deleteLicense, 0, Qt::AlignVCenter | Qt::AlignRight);
    actionLayout->addWidget(updateLicense, 0, Qt::AlignVCenter | Qt::AlignLeft);

    centralLayout->addWidget(stateHint, 0, Qt::AlignCenter);
    centralLayout->addSpacing(32);
    centralLayout->addWidget(createAuthorizeInfo(), 0, Qt::AlignCenter);
    centralLayout->addSpacing(16);
    centralLayout->addWidget(showLicense, 0, Qt::AlignCenter);
    centralLayout->addSpacing(16);
    centralLayout->addLayout(actionLayout);
    centralLayout->addStretch();
    centralLayout->addWidget(createCompanyInfo(), 0, Qt::AlignCenter);
    centralLayout->addSpacing(50);

    return  wrapLayout(centralLayout);
}

QWidget *ActivatorWindowPrivate::createUpdateLicenseView()
{
    auto centralLayout = initHeader(ActivatorWindow::tr("Welcome to use"));

    auto stateHint = new QLabel(ActivatorWindow::tr("Activated"));
    stateHint->setObjectName("SuccessStateHint");

    centralLayout->addWidget(stateHint, 0, Qt::AlignCenter);
    centralLayout->addStretch();
    centralLayout->addWidget(createAuthorizeInfo(), 0, Qt::AlignCenter);
    centralLayout->addStretch();
    centralLayout->addWidget(createCompanyInfo(), 0, Qt::AlignCenter);
    centralLayout->addSpacing(30);
    centralLayout->addWidget(createLicenseAction(), 0, Qt::AlignCenter);

    return  wrapLayout(centralLayout);
}
