#include "localmodelitem.h"
#include "localmodelserver.h"
#include "dbwrapper.h"

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QtConcurrent>
#include <QResizeEvent>

#include <DFontSizeManager>

static constexpr int TIMERBEGIN = 720;//5秒轮询安装和更新状态60分钟

LocalModelItem::LocalModelItem(DWidget *parent)
    : DWidget(parent)
    , m_pProcess(new QProcess)
{
    m_timer = new QTimer(this);
    m_timer->setInterval(5000);
    initUI();
    initConnect();
}

LocalModelItem::~LocalModelItem()
{
    if (m_pProcess) {
        m_pProcess->terminate();
        m_pProcess->deleteLater();
    }
    m_timer->stop();
}

void LocalModelItem::initUI()
{
    m_pLabelTheme = new DLabel;
    DFontSizeManager::instance()->bind(m_pLabelTheme, DFontSizeManager::T6, QFont::Medium);
    m_pLabelSummary = new DLabel;
    DFontSizeManager::instance()->bind(m_pLabelSummary, DFontSizeManager::T8, QFont::Normal);
    m_pLabelSummary->setElideMode(Qt::ElideRight);

    QVBoxLayout *textLayout = new QVBoxLayout;
    textLayout->setContentsMargins(0, 0, 0, 0);
    textLayout->setSpacing(2);
    textLayout->addWidget(m_pLabelTheme, 0, Qt::AlignLeft);
    textLayout->addWidget(m_pLabelSummary, 0, Qt::AlignLeft);

    m_pBtnInstall = new DSuggestButton(tr("Install"));
    m_pBtnInstall->setFixedHeight(30);
    m_pBtnInstall->setMinimumWidth(70);
    m_pBtnInstall->setMaximumWidth(80);

    m_pBtnUpdate = new DSuggestButton(tr("Update"));
    m_pBtnUpdate->setFixedHeight(30);
    m_pBtnUpdate->setMinimumWidth(70);
    m_pBtnUpdate->setMaximumWidth(90);
    m_pBtnUpdate->hide();

    m_pBtnUninstall = new DPushButton(tr("Uninstall"));
    m_pBtnUninstall->setFixedHeight(30);
    m_pBtnUninstall->setMinimumWidth(70);
    m_pBtnUninstall->setMaximumWidth(100);
    m_pBtnUninstall->hide();

    QHBoxLayout *mainLayout = new QHBoxLayout(this);
    mainLayout->setContentsMargins(10, 10, 10, 10);
    mainLayout->addLayout(textLayout);
    mainLayout->addStretch();
    mainLayout->addWidget(m_pBtnInstall, 0, Qt::AlignVCenter);
    mainLayout->addWidget(m_pBtnUpdate, 0, Qt::AlignVCenter);
    mainLayout->addWidget(m_pBtnUninstall, 0, Qt::AlignVCenter);

    setLayout(mainLayout);
}

void LocalModelItem::initConnect()
{
    connect(m_pBtnInstall, &DSuggestButton::clicked, this, &LocalModelItem::onInstall);
    connect(m_pBtnUpdate, &DSuggestButton::clicked, this, &LocalModelItem::onUpdate);
    connect(m_pBtnUninstall, &DSuggestButton::clicked, this, &LocalModelItem::onUninstall);
    connect(this,&LocalModelItem::changeUpdateStatus, this,&LocalModelItem::onChangeUpdateStatus);
    connect(m_timer, &QTimer::timeout, this, &LocalModelItem::checkStatusOntime);
    connect(&LocalModelServer::getInstance(), &LocalModelServer::sigToLaunchTimer, this, &LocalModelItem::beginTimer);
}

void LocalModelItem::setText(const QString &theme, const QString &summary)
{
    m_pLabelTheme->setText(theme);
    m_pLabelSummary->setText(summary);
    m_pLabelSummary->setToolTip(summary);
}

void LocalModelItem::setAppName(const QString &appName)
{
    m_appName = appName;
}

void LocalModelItem::onInstall()
{
    if (m_appName.isEmpty())
        return;
//    m_pBtnInstall->setText(tr("Installing"));
    LocalModelServer::getInstance().openInstallWidget(m_appName);
    beginTimer(TIMERBEGIN);
}

void LocalModelItem::onUpdate()
{
    if (m_appName.isEmpty())
        return;
//    m_pBtnUpdate->setText(tr("Updating"));
    LocalModelServer::getInstance().openInstallWidget(m_appName);
    beginTimer(TIMERBEGIN);
}

void LocalModelItem::onUninstall()
{
    if (m_appName.isEmpty())
        return;
//    m_pBtnUninstall->setText(tr("Uninstalling"));
    LocalModelServer::getInstance().openManagerWidget();
    beginTimer(TIMERBEGIN);
}

void LocalModelItem::checkInstallStatus()
{
    if (!m_pProcess->atEnd()) return;
    if (m_pProcess->state() == QProcess::Running)
        m_pProcess->waitForFinished();

    m_pProcess->start("dpkg-query", QStringList() << "-W" << QString("-f='${db:Status-Status}\n'") << m_appName);

    m_pProcess->waitForFinished();
    QByteArray reply = m_pProcess->readAllStandardOutput();

    m_isInstall = reply == "'installed\n'" ? true : false;
    changeInstallStatus();

}

void LocalModelItem::checkUpdateStatus()
{
    QFuture<void> future = QtConcurrent::run([=]() {
        if (!m_isInstall) {
            emit changeUpdateStatus(false);
            return;
        }
        QProcess process;
        process.start("apt", QStringList() << "list" << "--upgradable");
        process.waitForFinished();
        QByteArray reply = process.readAllStandardOutput();
        bool tempUpdateStatus = reply.contains(m_appName.toStdString().c_str());

        emit changeUpdateStatus(tempUpdateStatus);

        process.deleteLater();
    });
}

void LocalModelItem::changeInstallStatus()
{
    if (m_appName.isEmpty()) return;

    LocalModelServer::getInstance().localModelStatusChanged(m_appName, m_isInstall);

    if (m_isInstall) {
        m_pBtnInstall->hide();
        m_pBtnUninstall->show();
    } else {
        m_pBtnUninstall->hide();
        m_pBtnInstall->show();
    }
    adjustSummaryLabelWidth();
}

void LocalModelItem::onChangeUpdateStatus(bool isExistUpdate)
{
    if (isExistUpdate)
        m_pBtnUpdate->show();
    else
        m_pBtnUpdate->hide();
    adjustSummaryLabelWidth();
}

void LocalModelItem::checkStatusOntime()
{
//    qInfo() << "checking LocalModel status, Time remaining " << m_timerCount * 3;
    if (m_timerCount > 0) {
        checkInstallStatus();
        checkUpdateStatus();
        --m_timerCount;
    } else {
        m_timerCount = 0;
        m_timer->stop();
    }
}

void LocalModelItem::beginTimer(const int &time)
{
    m_timerCount = time;
    m_timer->start();
}

void LocalModelItem::stopTimer()
{
    m_timerCount = 0;
    m_timer->stop();
}

void LocalModelItem::addLocalLlM()
{
    //DbWrapper::appAssistant(); initAssistant();
    //DbWrapper::appendLlm();
}

bool LocalModelItem::getInstallStatus()
{
    return m_isInstall;
}

void LocalModelItem::resizeEvent(QResizeEvent *event)
{
    DWidget::resizeEvent(event);
    adjustSummaryLabelWidth();
}

void LocalModelItem::adjustSummaryLabelWidth()
{
    m_pBtnInstall->adjustSize();
    m_pBtnUpdate->adjustSize();
    m_pBtnUninstall->adjustSize();
    int maxWidth = this->size().width() - 40;
    if (m_isInstall)
        maxWidth -= m_pBtnUninstall->width();
    else
        maxWidth -= m_pBtnInstall->width();

    if (m_pBtnUpdate->isVisible())
        maxWidth -= m_pBtnUpdate->width();

    m_pLabelSummary->setMaximumWidth(maxWidth < 0 ? 0 : maxWidth);
}


