/*
 * Copyright (C) 2023, KylinSoft Co., Ltd.
 *
 * 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, 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 "grubverifydialog.h"

#include <QRegExpValidator>
#include <QDebug>
#include <QDBusInterface>
#include <QDBusReply>

GrubVerify::GrubVerify(QWidget *parent) : QDialog(parent)
{
    initUI();
    setupConnect();
}


GrubVerify::~GrubVerify()
{

}

void GrubVerify::initUI()
{
    setFixedSize(QSize(480, 266));
    setWindowTitle(tr("Grub verify"));

    // 用户
    userLabel = new QLabel();
    userLabel->setFixedSize(100,36);
    setTextDynamicInPwd(userLabel, tr("User:"));
    usernameLabel = new QLabel("root");
    usernameLabel->setFixedSize(QSize(322, 36));

    userHorLayout = new QHBoxLayout;
    userHorLayout->setSpacing(8);
    userHorLayout->setContentsMargins(0, 0, 0, 0);
    userHorLayout->addWidget(userLabel);
    userHorLayout->addWidget(usernameLabel);

    //新密码
    newPwdLabel = new QLabel();
    newPwdLabel->setFixedSize(100,24);
    setTextDynamicInPwd(newPwdLabel, tr("Pwd"));
    newTipLabel = new QLabel();
    QFont ft;
    ft.setPixelSize(14);
    newTipLabel->setFont(ft);
    newTipLabel->setFixedSize(QSize(322, 24));
    newTipLabel->setStyleSheet("color:red;");
    newTipHorLayout = new QHBoxLayout;
    newTipHorLayout->setContentsMargins(110, 0, 0, 0);
    newTipHorLayout->addStretch();
    newTipHorLayout->addWidget(newTipLabel);
    newPwdLineEdit = new QLineEdit();
    QRegExp inputRegExp("^[A-Za-z0-9`~!@#$%^&*()_-+=<>,.\\\/?:;\"'|\{\}\ ]+$");
    QRegExpValidator *inputLimits = new QRegExpValidator(inputRegExp, this);
    newPwdLineEdit->setValidator(inputLimits);
    newPwdLineEdit->setFixedSize(QSize(322, 36));
    newPwdLineEdit->setEchoMode(QLineEdit::Password);
    newPwdLineEdit->setTextMargins(0,0,30,0);
    newPwdLineEdit->setContextMenuPolicy(Qt::NoContextMenu);
    newPwdLineEdit->installEventFilter(this);
    newPwdEyeBtn = new QPushButton;
    newPwdEyeBtn->setFixedSize(QSize(24, 24));
    newPwdEyeBtn->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic"));
    newPwdEyeBtn->setCursor(Qt::PointingHandCursor);
    newPwdEyeBtn->setFlat(true);
    newPwdEyeBtn->setStyleSheet("QPushButton::pressed{border:none;background-color:transparent}"
                                "QPushButton::hover::!pressed{border:none;background-color:transparent}");
    newPwdEyeBtn->setFocusPolicy(Qt::FocusPolicy::NoFocus);
    QHBoxLayout *newPwdEyeBtnHLayout = new QHBoxLayout;
    newPwdEyeBtnHLayout->addStretch();
    newPwdEyeBtnHLayout->addWidget(newPwdEyeBtn);
    newPwdEyeBtnHLayout->setContentsMargins(0,0,8,0);
    newPwdLineEdit->setLayout(newPwdEyeBtnHLayout);

    newPwdHorLayout = new QHBoxLayout;
    newPwdHorLayout->setSpacing(8);
    newPwdHorLayout->setContentsMargins(0, 0, 0, 0);
    newPwdHorLayout->addWidget(newPwdLabel);
    newPwdHorLayout->addWidget(newPwdLineEdit);

    //确认密码
    surePwdLabel = new QLabel();
    surePwdLabel->setFixedSize(100,24);
    setTextDynamicInPwd(surePwdLabel, tr("Sure Pwd"));

    surePwdLineEdit = new QLineEdit();
    surePwdLineEdit->setValidator(inputLimits);
    surePwdLineEdit->setFixedSize(QSize(322, 36));
    surePwdLineEdit->setEchoMode(QLineEdit::Password);
    surePwdLineEdit->setTextMargins(0,0,30,0);
    surePwdLineEdit->setContextMenuPolicy(Qt::NoContextMenu);
    surePwdLineEdit->installEventFilter(this);
    surePwdEyeBtn = new QPushButton;
    surePwdEyeBtn->setFixedSize(QSize(24, 24));
    surePwdEyeBtn->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic"));
    surePwdEyeBtn->setCursor(Qt::PointingHandCursor);
    surePwdEyeBtn->setFlat(true);
    surePwdEyeBtn->setStyleSheet("QPushButton::pressed{border:none;background-color:transparent}"
                                 "QPushButton::hover::!pressed{border:none;background-color:transparent}");
    surePwdEyeBtn->setFocusPolicy(Qt::FocusPolicy::NoFocus);
    QHBoxLayout *surePwdEyeBtnHLayout = new QHBoxLayout;
    surePwdEyeBtnHLayout->addStretch();
    surePwdEyeBtnHLayout->addWidget(surePwdEyeBtn);
    surePwdEyeBtnHLayout->setContentsMargins(0,0,8,0);
    surePwdLineEdit->setLayout(surePwdEyeBtnHLayout);

    surePwdHorLayout = new QHBoxLayout;
    surePwdHorLayout->setSpacing(8);
    surePwdHorLayout->setContentsMargins(0, 0, 0, 0);
    surePwdHorLayout->addWidget(surePwdLabel);
    surePwdHorLayout->addWidget(surePwdLineEdit);

    sureTipLabel = new QLabel();
    sureTipLabel->setFont(ft);
    sureTipLabel->setFixedSize(QSize(322, 30));
    sureTipLabel->setStyleSheet("color:red;");

    sureTipHorLayout = new QHBoxLayout;
    sureTipHorLayout->setSpacing(0);
    sureTipHorLayout->setContentsMargins(110, 0, 0, 0);
    sureTipHorLayout->addStretch();
    sureTipHorLayout->addWidget(sureTipLabel);

    //中部输入区域
    contentVerLayout = new QVBoxLayout;
    contentVerLayout->setSpacing(0);
    contentVerLayout->setContentsMargins(24, 0, 35, 0);
    contentVerLayout->addLayout(userHorLayout);
    contentVerLayout->addLayout(newPwdHorLayout);
    contentVerLayout->addLayout(newTipHorLayout);
    contentVerLayout->addLayout(surePwdHorLayout);
    contentVerLayout->addLayout(sureTipHorLayout);

    //底部“取消”、“确定”按钮
    cancelBtn = new QPushButton();
    cancelBtn->setMinimumWidth(96);
    cancelBtn->setText(tr("Cancel"));
    cancelBtn->setFocusPolicy(Qt::FocusPolicy::NoFocus);
    confirmBtn = new QPushButton();
    confirmBtn->setMinimumWidth(96);
    confirmBtn->setText(tr("Confirm"));
    confirmBtn->setFocusPolicy(Qt::FocusPolicy::NoFocus);

    bottomBtnsHorLayout = new QHBoxLayout;
    bottomBtnsHorLayout->setSpacing(16);
    bottomBtnsHorLayout->setContentsMargins(0, 0, 25, 0);
    bottomBtnsHorLayout->addStretch();
    bottomBtnsHorLayout->addWidget(cancelBtn);
    bottomBtnsHorLayout->addWidget(confirmBtn);

    mainVerLayout = new QVBoxLayout;
    mainVerLayout->setContentsMargins(0, 10, 0, 24);
    mainVerLayout->addLayout(contentVerLayout);
    mainVerLayout->addStretch();
    mainVerLayout->addLayout(bottomBtnsHorLayout);

    setLayout(mainVerLayout);
}

void GrubVerify::setupConnect()
{
    //通用的connect
    connect(cancelBtn, &QPushButton::clicked, this, [=]{
        close();
    });

    connect(newPwdEyeBtn, &QPushButton::clicked, this, [=](){
        if (newPwdLineEdit->echoMode() == QLineEdit::Password) {
            newPwdLineEdit->setEchoMode(QLineEdit::Normal);
            newPwdEyeBtn->setIcon(QIcon::fromTheme("ukui-eye-display-symbolic"));
        } else {
            newPwdLineEdit->setEchoMode(QLineEdit::Password);
            newPwdEyeBtn->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic"));
        }

    });

    connect(surePwdEyeBtn, &QPushButton::clicked, this, [=](){
        if (surePwdLineEdit->echoMode() == QLineEdit::Password) {
            surePwdLineEdit->setEchoMode(QLineEdit::Normal);
            surePwdEyeBtn->setIcon(QIcon::fromTheme("ukui-eye-display-symbolic"));
        } else {
            surePwdLineEdit->setEchoMode(QLineEdit::Password);
            surePwdEyeBtn->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic"));
        }

    });

    connect(newPwdLineEdit, &QLineEdit::textEdited, this, [=](){
        checkPwdLegality();
        refreshConfirmBtnStatus();
    });

    connect(surePwdLineEdit, &QLineEdit::textEdited, this, [=](QString txt){
        if (!txt.isEmpty() && txt != newPwdLineEdit->text()){
            surePwdTip = tr("Inconsistency with pwd");
        } else {
            surePwdTip = "";
        }

        updateTipLableInfo(sureTipLabel, surePwdTip);

        refreshConfirmBtnStatus();
    });

    connect(confirmBtn, &QPushButton::clicked, this, [=](){
        QDBusInterface piface("com.control.center.qt.systemdbus",
                              "/",
                              "com.control.center.interface",
                              QDBusConnection::systemBus(), this);
        if (!piface.isValid()){
            qCritical() << "Create Client Interface Failed:" << QDBusConnection::systemBus().lastError();
            close();
        }

        QDBusReply<bool> ret = piface.call("setGrupPasswd", "root", newPwdLineEdit->text(), true);
        if (ret == false) {
            close();
        } else {
            accept();
        }
    });
}

void GrubVerify::checkPwdLegality()
{
    if (newPwdLineEdit->text().isEmpty()) {
        newPwdTip = tr("pwd cannot be empty!");
    } else {
        newPwdTip = tr("");
    }

    //防止先输入确认密码，再输入密码后tipLabel无法刷新
    if (!surePwdLineEdit->text().isEmpty()){
        if (QString::compare(newPwdLineEdit->text(), surePwdLineEdit->text()) == 0){
            surePwdTip = "";
        } else {
            surePwdTip = tr("Inconsistency with pwd");
        }
    }

    //设置新密码的提示
    updateTipLableInfo(newTipLabel,newPwdTip);

    updateTipLableInfo(sureTipLabel,surePwdTip);
}

void GrubVerify::updateTipLableInfo(QLabel *Label,QString info)
{
    if (setTextDynamicInPwd(Label, info)){
        Label->setToolTip(info);
    } else {
        Label->setToolTip("");
    }
}

void GrubVerify::refreshConfirmBtnStatus()
{

    if (newPwdLineEdit->text().isEmpty() || surePwdLineEdit->text().isEmpty() || \
        !newPwdTip.isEmpty() || !surePwdTip.isEmpty()) {
        confirmBtn->setEnabled(false);
    } else {
        confirmBtn->setEnabled(true);
    }
}

bool GrubVerify::setTextDynamicInPwd(QLabel *label, QString string){

    bool isOverLength = false;
    QFontMetrics fontMetrics(label->font());
    int fontSize = fontMetrics.width(string);

    QString str = string;
    int pSize = label->width();
    if (fontSize > pSize) {
        str = fontMetrics.elidedText(string, Qt::ElideRight, pSize);
        isOverLength = true;
        label->setToolTip(string);
    } else {
        label->setToolTip("");
    }
    label->setText(str);
    return isOverLength;

}

bool GrubVerify::eventFilter(QObject *target, QEvent *event)
{
    if (target == newPwdLineEdit || target == surePwdLineEdit) {
        if (event->type() == QEvent::KeyPress)
        {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);

            if(keyEvent->matches(QKeySequence::Copy) || keyEvent->matches(QKeySequence::Cut))
            {
                qDebug() <<"Copy || Cut";
                return true;
            }
        }
    }

    if (event->type() == QEvent::FocusOut) {
       if (target == newPwdLineEdit) {
            if (newPwdLineEdit->text().isEmpty()) {
                newPwdTip = tr("pwd cannot be empty!");
                updateTipLableInfo(newTipLabel, newPwdTip);
            }
        } else if (target == surePwdLineEdit) {
            if (surePwdLineEdit->text().isEmpty()) {
                surePwdTip = tr("sure pwd cannot be empty!");
                updateTipLableInfo(sureTipLabel, surePwdTip);
            }
        }
    }

    return QWidget::eventFilter(target, event);
    //继续传递该事件到被观察者，由其本身调用相应的事件。
}

