/*
 * Copyright (C) 2023 Uniontech Software Technology Co., Ltd.
 *
 * Author:     liuzhangjian<liuzhangjian@uniontech.com>
 *
 * Maintainer: zhengyouge<zhengyouge@uniontech.com>
 *             liuzhangjian<liuzhangjian@uniontech.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
 * 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 "dpcprogresswidget.h"
#include "dpcdefine.h"
#include "dfmglobal.h"

#include <DLabel>
#include <DWaterProgress>
#include <DFontSizeManager>

#include <QVBoxLayout>
#include <QTimer>
#include <QDBusInterface>
#include <QDBusConnection>
#include <QDBusPendingCall>

DWIDGET_USE_NAMESPACE

DPCProgressWidget::DPCProgressWidget(QWidget *parent)
    : DWidget(parent)
{
    accessControlInter.reset(new QDBusInterface(DPCDefine::InterfaceService,
                                                DPCDefine::InterfacePath,
                                                DPCDefine::InterfaceInterface,
                                                QDBusConnection::systemBus(),
                                                this));
    initUI();
    initConnect();
}

void DPCProgressWidget::initUI()
{
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->setMargin(0);
    setLayout(mainLayout);

    progressTimer = new QTimer(this);
    progressTimer->setInterval(1000);

    titleLabel = new DLabel(tr("Changing disk password..."), this);
    titleLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
    titleLabel->setAlignment(Qt::AlignCenter);
    titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    DFontSizeManager *fontManager = DFontSizeManager::instance();
    fontManager->bind(titleLabel, DFontSizeManager::T5, QFont::Medium);

    msgLabel = new DLabel(this);
    msgLabel->setWordWrap(true);
    msgLabel->setAlignment(Qt::AlignHCenter);
    msgLabel->setMinimumHeight(50);
    if (DFMGlobal::isWayLand()) {
        msgLabel->setText(tr("Please do not close the window during the modification process"));
    } else {
        msgLabel->setText(tr("The window cannot be closed during the process"));
    }

    changeProgress = new DWaterProgress(this);
    changeProgress->setFixedSize(98, 98);
    changeProgress->setValue(1);

    mainLayout->addWidget(titleLabel, 0, Qt::AlignHCenter);
    mainLayout->addSpacing(25);
    mainLayout->addWidget(changeProgress, 0, Qt::AlignHCenter);
    mainLayout->addSpacing(20);
    mainLayout->addWidget(msgLabel, 0, Qt::AlignHCenter);
}

void DPCProgressWidget::initConnect()
{
    Q_ASSERT(accessControlInter);

    connect(progressTimer, &QTimer::timeout, this, &DPCProgressWidget::changeProgressValue);

    accessControlInter->connection().connect(accessControlInter->service(),
                                             accessControlInter->path(),
                                             accessControlInter->interface(),
                                             DPCDefine::SigPwdChanged,
                                             this,
                                             SLOT(onDiskPwdChanged(int)));
}

void DPCProgressWidget::start()
{
    progressTimer->start();
    changeProgress->start();
}

void DPCProgressWidget::changeProgressValue()
{
    int value = changeProgress->value();
    if (value + 5 < 95) {
        changeProgress->setValue(value + 5);
    } else {
        progressTimer->stop();
    }
}

void DPCProgressWidget::onDiskPwdChanged(int result)
{
    switch (result) {
    case DPCDefine::NoError:
        if (progressTimer->isActive())
            progressTimer->stop();

        changeProgress->setValue(100);
        QTimer::singleShot(500, [this] {
            emit sigCompleted(true, "");
        });

        break;
    case DPCDefine::PasswordInconsistent:
        emit sigCompleted(false, tr("Passwords of disks are different"));
        break;
    case DPCDefine::AccessDiskFailed:
        emit sigCompleted(false, tr("Unable to get the encrypted disk list"));
        break;
    default:
        emit sigCompleted(false, tr("Initialization failed"));
        break;
    }
}
