/*
   Copyright (C) 2013-2017 Montel Laurent <montel@kde.org>

   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 2 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; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "shorturlwidgetng.h"
#include "shorturlengineplugin/shorturlengineplugin.h"
#include "shorturlengineplugin/shorturlengineinterface.h"
#include "shorturlconfiguredialog.h"
#include "Libkdepim/ProgressIndicatorLabel"
#include "shorturlengineplugin/shorturlenginepluginmanager.h"
#include <PimCommon/NetworkManager>
#include <KLineEdit>
#include <KLocalizedString>
#include <KMessageBox>
#include <KToggleAction>
#include <KSharedConfig>
#include <KRun>
#include <QIcon>
#include <QNetworkConfigurationManager>

#include <QLabel>
#include <QGridLayout>
#include <QPushButton>
#include <QApplication>
#include <QClipboard>
#include <QToolButton>
#include <QPointer>
#include <KActionCollection>
#include <KConfigGroup>

ShortUrlWidgetNg::ShortUrlWidgetNg(QWidget *parent)
    : QWidget(parent)
    , mShorturlServiceName(nullptr)
    , mCurrentEngine(nullptr)
{
    QGridLayout *grid = new QGridLayout(this);
    grid->setMargin(2);

    QToolButton *closeBtn = new QToolButton(this);
    closeBtn->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close")));
    closeBtn->setIconSize(QSize(16, 16));
    closeBtn->setToolTip(i18n("Close"));
#ifndef QT_NO_ACCESSIBILITY
    closeBtn->setAccessibleName(i18n("Close"));
#endif
    closeBtn->setAutoRaise(true);
    connect(closeBtn, &QToolButton::clicked, this, &ShortUrlWidgetNg::slotCloseWidget);

    grid->addWidget(closeBtn, 0, 0);

    mIndicatorLabel = new KPIM::ProgressIndicatorLabel(i18n("Generating short URL..."), this);
    grid->addWidget(mIndicatorLabel, 0, 1);

    QPushButton *configure = new QPushButton(i18n("Configure..."), this);
    connect(configure, &QPushButton::clicked, this, &ShortUrlWidgetNg::slotConfigure);
    grid->addWidget(configure, 0, 2);

    mShorturlServiceName = new QLabel(/*mEngine->shortUrlName()*/ this);
    grid->addWidget(mShorturlServiceName, 1, 1);

    mConvertButton = new QPushButton(i18n("Convert"));
    grid->addWidget(mConvertButton, 1, 2);
    connect(mConvertButton, &QPushButton::clicked, this, &ShortUrlWidgetNg::slotConvertUrl);

    mInsertShortUrl = new QPushButton(i18n("Insert Short URL"));
    connect(mInsertShortUrl, &QPushButton::clicked, this, &ShortUrlWidgetNg::slotInsertShortUrl);
    grid->addWidget(mInsertShortUrl, 2, 2);

    QLabel *lab = new QLabel(i18n("Original URL:"), this);
    grid->addWidget(lab, 3, 0);

    mOriginalUrl = new KLineEdit(this);
    mOriginalUrl->setClearButtonEnabled(true);
    mOriginalUrl->setTrapReturnKey(true);
    connect(mOriginalUrl, &KLineEdit::textChanged, this, &ShortUrlWidgetNg::slotOriginalUrlChanged);
    connect(mOriginalUrl, &KLineEdit::returnPressed, this, &ShortUrlWidgetNg::slotConvertUrl);
    grid->addWidget(mOriginalUrl, 3, 1);

    mCopyToClipboard = new QPushButton(i18n("Copy to clipboard"), this);
    connect(mCopyToClipboard, &QPushButton::clicked, this, &ShortUrlWidgetNg::slotPasteToClipboard);
    grid->addWidget(mCopyToClipboard, 3, 2);

    lab = new QLabel(i18n("Short URL:"), this);
    grid->addWidget(lab, 4, 0);

    mShortUrl = new QLineEdit(this);
    connect(mShortUrl, &QLineEdit::textChanged, this, &ShortUrlWidgetNg::slotShortUrlChanged);
    mShortUrl->setReadOnly(true);
    grid->addWidget(mShortUrl, 4, 1);

    mOpenShortUrl = new QPushButton(i18n("Open Short URL"), this);
    connect(mOpenShortUrl, &QPushButton::clicked, this, &ShortUrlWidgetNg::slotOpenShortUrl);
    grid->addWidget(mOpenShortUrl, 4, 2);

    grid->setRowStretch(5, 1);
    mConvertButton->setEnabled(false);
    mCopyToClipboard->setEnabled(false);
    mInsertShortUrl->setEnabled(false);
    mOpenShortUrl->setEnabled(false);

    initializePlugins();
    loadEngine();
}

ShortUrlWidgetNg::~ShortUrlWidgetNg()
{
}

void ShortUrlWidgetNg::initializePlugins()
{
    const QVector<ShortUrlEnginePlugin *> lstPlugin = ShortUrlEnginePluginManager::self()->pluginsList();
    for (ShortUrlEnginePlugin *plugin : lstPlugin) {
        ShortUrlEngineInterface *interface = plugin->createInterface(this);
        if (interface) {
            mLstInterface.insert(interface->engineName(), interface);
        }
    }
}

void ShortUrlWidgetNg::slotInsertShortUrl()
{
    const QString shortUrl = mShortUrl->text();
    if (!shortUrl.isEmpty()) {
        Q_EMIT insertText(shortUrl);
    }
}

void ShortUrlWidgetNg::slotConfigure()
{
    QPointer<ShortUrlConfigureDialog> dlg = new ShortUrlConfigureDialog(this);
    if (dlg->exec()) {
        loadEngine();
    }
    delete dlg;
}

void ShortUrlWidgetNg::settingsUpdated()
{
    loadEngine();
}

void ShortUrlWidgetNg::loadEngine()
{
    if (mCurrentEngine) {
        disconnect(mCurrentEngine, &ShortUrlEngineInterface::shortUrlGenerated, this, &ShortUrlWidgetNg::slotShortUrlDone);
        disconnect(mCurrentEngine, &ShortUrlEngineInterface::shortUrlFailed, this, &ShortUrlWidgetNg::slotShortUrlFailed);
    }

    KConfigGroup grp(KSharedConfig::openConfig(), "ShortUrl");
    const QString engineName = grp.readEntry("EngineName");
    mCurrentEngine = mLstInterface.value(engineName);
    if (!mCurrentEngine && !mLstInterface.isEmpty()) {
        mCurrentEngine = mLstInterface.cbegin().value();
    }

    if (mCurrentEngine) {
        mShorturlServiceName->setText(mCurrentEngine->pluginName());
        connect(mCurrentEngine, &ShortUrlEngineInterface::shortUrlGenerated, this, &ShortUrlWidgetNg::slotShortUrlDone);
        connect(mCurrentEngine, &ShortUrlEngineInterface::shortUrlFailed, this, &ShortUrlWidgetNg::slotShortUrlFailed);
    }
}

void ShortUrlWidgetNg::slotConvertUrl()
{
    if (!mCurrentEngine) {
        return;
    }
    if (!PimCommon::NetworkManager::self()->networkConfigureManager()->isOnline()) {
        KMessageBox::information(this, i18n("No network connection detected, we cannot shorten URL."), i18n("No network"));
        return;
    }
    if (mOriginalUrl->text().isEmpty()) {
        return;
    }
    mIndicatorLabel->start();
    mCurrentEngine->setShortUrl(mOriginalUrl->text());
    mShortUrl->clear();
    mCurrentEngine->generateShortUrl();
}

void ShortUrlWidgetNg::slotPasteToClipboard()
{
    const QString shortUrl = mShortUrl->text();
    if (!shortUrl.isEmpty()) {
        QApplication::clipboard()->setText(shortUrl);
    }
}

void ShortUrlWidgetNg::slotOriginalUrlChanged(const QString &text)
{
    mConvertButton->setEnabled(!text.isEmpty());
}

void ShortUrlWidgetNg::slotShortUrlChanged(const QString &text)
{
    const bool textIsEmpty = {!text.isEmpty()};
    mCopyToClipboard->setEnabled(textIsEmpty);
    mInsertShortUrl->setEnabled(textIsEmpty);
    mOpenShortUrl->setEnabled(textIsEmpty);
}

void ShortUrlWidgetNg::slotShortUrlDone(const QString &url)
{
    mShortUrl->setText(url);
    mIndicatorLabel->stop();
}

void ShortUrlWidgetNg::slotShortUrlFailed(const QString &errMsg)
{
    KMessageBox::error(this, i18n("An error occurred: \"%1\"", errMsg));
    mIndicatorLabel->stop();
}

void ShortUrlWidgetNg::slotCloseWidget()
{
    mOriginalUrl->clear();
    mShortUrl->clear();
    mIndicatorLabel->stop();

    Q_EMIT toolsWasClosed();
}

void ShortUrlWidgetNg::slotOpenShortUrl()
{
    const QString shortUrl = mShortUrl->text();
    if (!shortUrl.isEmpty()) {
        new KRun(QUrl(shortUrl), this);
    }
}
