/***************************************************************************
 * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr
 * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr
 * SPDX-License-Identifier: GPL-3.0-or-later
 ***************************************************************************/
/** @file
 * This file is Skrooge plugin for unit management.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgunitplugin.h"

#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kservicetypetrader.h>

#include <qaction.h>
#include <qinputdialog.h>
#include <qprocess.h>

#include "skgdocumentbank.h"
#include "skghtmlboardwidget.h"
#include "skgmainpanel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgunit_settings.h"
#include "skgunitboardwidget.h"
#include "skgunitpluginwidget.h"
#include "skgunitvalueobject.h"

/**
 * This plugin factory.
 */
K_PLUGIN_FACTORY(SKGUnitPluginFactory, registerPlugin<SKGUnitPlugin>();)

SKGUnitPlugin::SKGUnitPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/)
    : SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr)
{
    Q_UNUSED(iWidget)
    SKGTRACEINFUNC(10)
}

SKGUnitPlugin::~SKGUnitPlugin()
{
    SKGTRACEINFUNC(10)
    m_currentBankDocument = nullptr;
}

bool SKGUnitPlugin::setupActions(SKGDocument* iDocument)
{
    SKGTRACEINFUNC(10)

    m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
    if (m_currentBankDocument == nullptr) {
        return false;
    }

    setComponentName(QStringLiteral("skrooge_unit"), title());
    setXMLFile(QStringLiteral("skrooge_unit.rc"));

    // Menu
    auto actSplitShare = new QAction(SKGServices::fromTheme(QStringLiteral("format-text-strikethrough")), i18nc("Verb", "Split share..."), this);
    connect(actSplitShare, &QAction::triggered, this, &SKGUnitPlugin::onSplitShare);
    actionCollection()->setDefaultShortcut(actSplitShare, Qt::ALT + Qt::Key_Slash);
    registerGlobalAction(QStringLiteral("edit_split_stock"), actSplitShare, QStringList() << QStringLiteral("unit"), 1, 1, 310);  // TODO(Stephane MANKOWSKI): must be a share

    // -----------
    auto act = new QAction(SKGServices::fromTheme(icon()), i18nc("Verb", "Delete unused units"), this);
    connect(act, &QAction::triggered, this, &SKGUnitPlugin::deleteUnusedUnits);
    registerGlobalAction(QStringLiteral("clean_delete_unused_units"), act);
    return true;
}

int SKGUnitPlugin::getNbDashboardWidgets()
{
    return 2;
}

QString SKGUnitPlugin::getDashboardWidgetTitle(int iIndex)
{
    if (iIndex == 0) {
        return i18nc("Noun, the title of a section", "Quotes");
    }
    return i18nc("Noun, the title of a section", "Stock portfolio");
}

SKGBoardWidget* SKGUnitPlugin::getDashboardWidget(int iIndex)
{
    if (iIndex == 0) {
        return new SKGUnitBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
    }
    // Get QML mode for dashboard
    KConfigSkeleton* skl = SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Dashboard plugin"))->getPreferenceSkeleton();
    KConfigSkeletonItem* sklItem = skl->findItem(QStringLiteral("qmlmode"));
    bool qml = sklItem->property().toBool();

    auto listForFilter = QStringList() << QStringLiteral("t_name")
                         << QStringLiteral("t_symbol")
                         << QStringLiteral("t_country")
                         << QStringLiteral("t_type")
                         << QStringLiteral("t_internet_code")
                         << QStringLiteral("t_source")
                         << QStringLiteral("t_bookmarked");

    return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
                                  getDashboardWidgetTitle(iIndex),
                                  QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/portfolio.") % (qml ?  QStringLiteral("qml") :  QStringLiteral("html"))),
                                  QStringList() << QStringLiteral("v_operation_display"),
                                  SKGSimplePeriodEdit::NONE,
                                  listForFilter);
}

void SKGUnitPlugin::refresh()
{
    SKGTRACEINFUNC(10)
    if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
        // Automatic download
        QString doc_id = m_currentBankDocument->getUniqueIdentifier();
        if (m_docUniqueIdentifier != doc_id) {
            m_docUniqueIdentifier = doc_id;
            // Check if current unit is existing
            bool exist = false;
            SKGError err = m_currentBankDocument->existObjects(QStringLiteral("unit"), QLatin1String(""), exist);
            IFOK(err) {
                if (!exist) {
                    SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Create default unit"), err)
                    IFOK(err) {
                        // Create default unit
                        SKGUnitObject unit;
                        QString unitS = QLocale().currencySymbol(QLocale::CurrencyIsoCode);
                        if (!unitS.isEmpty()) {
                            err = SKGUnitObject::createCurrencyUnit(m_currentBankDocument, unitS, unit);
                        }

                        // The file is considered has not modified
                        m_currentBankDocument->setFileNotModified();
                    }
                } else if (skgunit_settings::download_on_open()) {
                    // Check frequency
                    QString lastAutomaticDownload = m_currentBankDocument->getParameter(QStringLiteral("SKG_LAST_UNIT_AUTOMATIC_DOWNLOAD"));
                    if (lastAutomaticDownload.isEmpty()) {
                        lastAutomaticDownload = QStringLiteral("1970-01-01");
                    }
                    QDate lastAutomaticDownloadDate = QDate::fromString(lastAutomaticDownload, QStringLiteral("yyyy-MM-dd"));
                    if ((lastAutomaticDownloadDate.daysTo(QDate::currentDate()) >= 1 && skgunit_settings::download_frequency() == 0) ||
                        (lastAutomaticDownloadDate.daysTo(QDate::currentDate()) >= 7 && skgunit_settings::download_frequency() == 1) ||
                        (lastAutomaticDownloadDate.daysTo(QDate::currentDate()) >= 30 && skgunit_settings::download_frequency() == 2))

                    {
                        // Download all units
                        SKGObjectBase::SKGListSKGObjectBase selection;
                        err = m_currentBankDocument->getObjects(QStringLiteral("unit"), QLatin1String(""), selection);
                        int nb = selection.count();
                        SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Automatic download of units"), err, nb)
                        for (int i = 0; !err && i < nb; ++i) {
                            SKGUnitObject unit(selection.at(i));
                            err = SKGUnitPluginWidget::downloadUnitValue(unit, SKGUnitPluginWidget::getDownloadModeFromSettings());

                            // Send message
                            IFOKDO(err, m_currentBankDocument->sendMessage(i18nc("An information to the user", "The unit '%1' has been downloaded", unit.getDisplayName()), SKGDocument::Hidden))

                            IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
                        }

                        // Memorize the last download date
                        IFOKDO(err, m_currentBankDocument->setParameter(QStringLiteral("SKG_LAST_UNIT_AUTOMATIC_DOWNLOAD"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd"))))
                    }
                }
            }

            // Display error
            SKGMainPanel::displayErrorMessage(err);
        }
    }
}

SKGTabPage* SKGUnitPlugin::getWidget()
{
    SKGTRACEINFUNC(10)
    return new SKGUnitPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}

QWidget* SKGUnitPlugin::getPreferenceWidget()
{
    SKGTRACEINFUNC(10)
    auto w = new QWidget();
    ui.setupUi(w);

    // Get sources from.desktop file
    QStringList sources;
    const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source"));
    for (const auto& service : list2) {
        auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString();
        auto keyAPI = service->property(QStringLiteral("X-SKROOGE-keyAPI"), QVariant::Bool).toBool();
        if (!sources.contains(name) && keyAPI) {
            sources.push_back(name);
        }
    }
    sources.sort();

    auto nb = sources.count();
    auto lwidgets = new QHash<QString, QLineEdit*>();
    for (auto i = 0; i < nb; ++i) {
        // Get Current value
        auto ln = new QLineEdit(w);
        ln->setText(m_currentBankDocument->getParameter("KEYAPI_" + sources[i]));
        lwidgets->insert(sources.value(i), ln);

        ui.kAPIKeyLayout->addWidget(new QLabel(sources[i] + ':', w), i, 0);
        ui.kAPIKeyLayout->addWidget(ln, i, 1);
    }

    connect(ui.kcfg_download_on_open, &QCheckBox::toggled, ui.kcfg_download_frequency, &KComboBox::setEnabled);
    connect(ui.kSave, &QPushButton::clicked, this, [ = ]() {
        SKGError err;
        {
            SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Save API keys"), err)
            auto keys = lwidgets->keys();
            for (const auto& k : qAsConst(keys)) {
                m_currentBankDocument->setParameter("KEYAPI_" + k, lwidgets->value(k)->text());
            }
        }
        // Display error
        SKGMainPanel::displayErrorMessage(err);
    });

    return w;
}

KConfigSkeleton* SKGUnitPlugin::getPreferenceSkeleton()
{
    return skgunit_settings::self();
}

QString SKGUnitPlugin::title() const
{
    return i18nc("Noun, units for operations, usually currencies or a shares", "Units");
}

QString SKGUnitPlugin::icon() const
{
    return QStringLiteral("taxes-finances");
}

QString SKGUnitPlugin::toolTip() const
{
    return i18nc("A tool tip", "Unit management");
}

QStringList SKGUnitPlugin::tips() const
{
    QStringList output;
    output.push_back(i18nc("Description of a tips", "<p>... you can download <a href=\"skg://skrooge_unit_plugin\">units</a>.</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... <a href=\"skg://skrooge_unit_plugin\">units</a> can be downloaded <a href=\"skg://tab_configure?page=Skrooge Unit Plugin\">automatically</a> when a document is opened.</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... you can split a <a href=\"skg://skrooge_unit_plugin\">share</a>.</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... <a href=\"skg://skrooge_unit_plugin\">units</a> can be merged by drag & drop.</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... you can download more <a href=\"skg://skrooge_unit_plugin\">sources</a> of quote.</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... you can create and share your own source of quote.</p>"));

    return output;
}

int SKGUnitPlugin::getOrder() const
{
    return 60;
}

bool SKGUnitPlugin::isInPagesChooser() const
{
    return true;
}

void SKGUnitPlugin::onSplitShare()
{
    SKGError err;
    SKGTRACEINFUNCRC(10, err)

    // Get Selection
    if (SKGMainPanel::getMainPanel() != nullptr) {
        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
        int nb = selection.count();
        if (nb == 1) {
            bool ok = false;
            double ratio = QInputDialog::getDouble(SKGMainPanel::getMainPanel(), i18nc("Question", "Split share"),
                                                   i18nc("Question", "Ratio (2 means 2-for-1, 0.5 means 1-for-2):"), 2.0,
                                                   0, std::numeric_limits<double>::max(), 8, &ok);
            if (ok) {
                SKGUnitObject unit(selection.at(0));
                SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Split stock '%1' by '%2'", unit.getName(), ratio), err)
                IFOKDO(err, unit.split(ratio))
            }
        }

        // status
        IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Stock split.")))
        else {
            err.addError(ERR_FAIL, i18nc("Error message", "Splitting stock failed."));
        }

        // Display error
        SKGMainPanel::displayErrorMessage(err);
    }
}

SKGAdviceList SKGUnitPlugin::advice(const QStringList& iIgnoredAdvice)
{
    SKGTRACEINFUNC(10)
    SKGAdviceList output;
    output.reserve(20);

    // Get all currencies
    SKGStringListList result;
    m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT (SELECT count(1) FROM operation WHERE operation.rc_unit_id=unit.id), unit.t_name FROM unit WHERE t_type='C' GROUP BY t_name ORDER BY count(1) DESC"), result);
    int nb = result.count();

    // Check primary unit
    if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_primaryunit"))) {
        if (m_currentBankDocument->getPrimaryUnit().Name.isEmpty() && nb > 1) {
            // Get unit
            QString unit = result.at(1).at(1);

            SKGAdvice ad;
            ad.setUUID("skgunitplugin_primaryunit|" % unit);
            ad.setPriority(8);
            ad.setShortMessage(i18nc("Advice on making the best (short)", "Define a primary currency"));
            ad.setLongMessage(i18nc("Advice on making the best (long)", "To avoid misunderstanding and conflicts between units at conversion time, you should define a primary currency. It is the currency against which all other will be converted"));
            SKGAdvice::SKGAdviceActionList autoCorrections;
            {
                SKGAdvice::SKGAdviceAction a;
                a.Title = i18nc("Advice on making the best (action)", "Set '%1' as primary currency", unit);
                a.IconName = icon();
                a.IsRecommended = true;
                autoCorrections.push_back(a);
            }
            {
                SKGAdvice::SKGAdviceAction a;
                a.Title = i18nc("Advice on making the best (action)", "Edit units");
                a.IconName = icon();
                a.IsRecommended = false;
                autoCorrections.push_back(a);
            }
            ad.setAutoCorrections(autoCorrections);
            output.push_back(ad);

            --nb;
        }
    }

    // Check secondary unit
    if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_secondaryunit"))) {
        if (m_currentBankDocument->getSecondaryUnit().Name.isEmpty() && nb > 1) {
            // Get unit
            QString unit = result.at(1).at(1);

            SKGAdvice ad;
            ad.setUUID("skgunitplugin_secondaryunit|" % unit);
            ad.setPriority(2);
            ad.setShortMessage(i18nc("Advice on making the best (short)", "Define a secondary currency"));
            ad.setLongMessage(i18nc("Advice on making the best (long)", "When a secondary unit is defined, Skrooge will display it as an additional amount information."));
            SKGAdvice::SKGAdviceActionList autoCorrections;
            {
                SKGAdvice::SKGAdviceAction a;
                a.Title = i18nc("Advice on making the best (action)", "Set '%1' as secondary currency", unit);
                a.IconName = icon();
                a.IsRecommended = true;
                autoCorrections.push_back(a);
            }
            {
                SKGAdvice::SKGAdviceAction a;
                a.Title = i18nc("Advice on making the best (action)", "Edit units");
                a.IconName = icon();
                a.IsRecommended = false;
                autoCorrections.push_back(a);
            }
            ad.setAutoCorrections(autoCorrections);
            output.push_back(ad);
        }
    }

    // Shares not downloaded
    if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_notdownloaded"))) {
        m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name, t_internet_code from unit WHERE t_internet_code<>'' AND (julianday('now', 'localtime')-(SELECT MAX(julianday(d_date)) FROM unitvalue WHERE rd_unit_id=unit.id ))>30 OR NOT EXISTS (SELECT 1 FROM unitvalue WHERE unitvalue.rd_unit_id=unit.id)"), result);
        nb = result.count();
        SKGAdvice::SKGAdviceActionList autoCorrections;
        autoCorrections.reserve(nb);
        for (int i = 1; i < nb; ++i) {  // Ignore header
            // Get parameters
            const QStringList& line = result.at(i);
            const QString& unit = line.at(0);
            const QString& internet_code = line.at(1);

            SKGAdvice ad;
            ad.setUUID("skgunitplugin_notdownloaded|" % unit);
            ad.setPriority(5);
            ad.setShortMessage(i18nc("Advice on making the best (short)", "Unit '%1' has not been downloaded for more than a month", unit));
            ad.setLongMessage(i18nc("Advice on making the best (long)", "Do not forget download units to have a better view of your accounts"));
            autoCorrections.resize(0);
            {
                SKGAdvice::SKGAdviceAction a;
                a.Title = i18nc("Advice on making the best (action)", "Edit units");
                a.IconName = icon();
                a.IsRecommended = false;
                autoCorrections.push_back(a);
            }
            if (!internet_code.isEmpty()) {
                SKGAdvice::SKGAdviceAction a;
                a.Title = i18nc("Advice on making the best (action)", "Download '%1'", unit);
                a.IconName = QStringLiteral("download");
                a.IsRecommended = true;
                autoCorrections.push_back(a);
            }
            ad.setAutoCorrections(autoCorrections);
            output.push_back(ad);
        }
    }

    // Check unused units
    if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_unused"))) {
        bool exist = false;
        m_currentBankDocument->existObjects(QStringLiteral("unit"), QStringLiteral("t_type NOT IN ('I', '1', '2') AND NOT EXISTS (SELECT 1 FROM operation WHERE operation.rc_unit_id=unit.id) AND NOT EXISTS (SELECT 1 FROM unit as unit2 WHERE unit2.rd_unit_id=unit.id)"), exist);
        if (exist) {
            SKGAdvice ad;
            ad.setUUID(QStringLiteral("skgunitplugin_unused"));
            ad.setPriority(5);
            ad.setShortMessage(i18nc("Advice on making the best (short)", "Many unused units"));
            ad.setLongMessage(i18nc("Advice on making the best (long)", "You can improve performances by removing units for which no operation is registered."));
            QStringList autoCorrections;
            autoCorrections.push_back(QStringLiteral("skg://clean_delete_unused_units"));
            ad.setAutoCorrections(autoCorrections);
            output.push_back(ad);
        }
    }

    // Check unit too complex
    if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_amountnotdefined"))) {
        m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name FROM v_unit WHERE t_type IN ('2','C') AND f_CURRENTAMOUNT=1"), result);
        nb = result.count();
        SKGAdvice::SKGAdviceActionList autoCorrections;
        autoCorrections.reserve(nb);
        for (int i = 1; i < nb; ++i) {  // Ignore header
            // Get parameters
            const QStringList& line = result.at(i);
            const QString& unit = line.at(0);

            SKGAdvice ad;
            ad.setUUID("skgunitplugin_amountnotdefined|" % unit);
            ad.setPriority(9);
            ad.setShortMessage(i18nc("Advice on making the best (short)", "The amount of the unit '%1' is not defined", unit));
            ad.setLongMessage(i18nc("Advice on making the best (long)", "'%1' has an amount defined at 1. Most of the time this is not normal and causes wrong computation. Check if this is normal.", unit));
            autoCorrections.resize(0);
            {
                SKGAdvice::SKGAdviceAction a;
                a.Title = i18nc("Advice on making the best (action)", "Edit units");
                a.IconName = icon();
                a.IsRecommended = false;
                autoCorrections.push_back(a);
            }
            ad.setAutoCorrections(autoCorrections);
            output.push_back(ad);
        }
    }

    // Check unit too complex
    if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_toocomplex"))) {
        m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT A.t_name FROM unit A, unit B, unit C, unit D WHERE A.rd_unit_id=B.id AND B.rd_unit_id=C.id AND C.rd_unit_id=D.id"), result);
        nb = result.count();
        SKGAdvice::SKGAdviceActionList autoCorrections;
        autoCorrections.reserve(nb);
        for (int i = 1; i < nb; ++i) {  // Ignore header
            // Get parameters
            const QStringList& line = result.at(i);
            const QString& unit = line.at(0);

            SKGAdvice ad;
            ad.setUUID(QStringLiteral("skgunitplugin_toocomplex"));
            ad.setPriority(9);
            ad.setShortMessage(i18nc("Advice on making the best (short)", "The definition of the unit '%1' is too complex", unit));
            ad.setLongMessage(i18nc("Advice on making the best (long)", "'%1' is defined relatively to another unit defined relatively to a third one. This is too complex and not supported by Skrooge.", unit));
            autoCorrections.resize(0);
            {
                SKGAdvice::SKGAdviceAction a;
                a.Title = i18nc("Advice on making the best (action)", "Edit units");
                a.IconName = icon();
                a.IsRecommended = false;
                autoCorrections.push_back(a);
            }
            ad.setAutoCorrections(autoCorrections);
            output.push_back(ad);
        }
    }

    // Unit with very old values
    if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_veryold"))) {
        m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name from unit WHERE (SELECT COUNT(*) FROM unitvalue WHERE unitvalue.rd_unit_id=unit.id)>1 AND EXISTS (SELECT 1 FROM unitvalue WHERE unitvalue.rd_unit_id=unit.id AND unitvalue.d_date<=(SELECT date('now', 'localtime', '-50 year')))"), result);
        nb = result.count();
        SKGAdvice::SKGAdviceActionList autoCorrections;
        autoCorrections.reserve(nb);
        for (int i = 1; i < nb; ++i) {  // Ignore header
            // Get parameters
            const QStringList& line = result.at(i);
            const QString& unit = line.at(0);

            SKGAdvice ad;
            ad.setUUID("skgunitplugin_veryold|" % unit);
            ad.setPriority(3);
            ad.setShortMessage(i18nc("Advice on making the best (short)", "Unit '%1' has very old values", unit));
            ad.setLongMessage(i18nc("Advice on making the best (long)", "Unit '%1' has very old values. Check if this is normal.", unit));
            autoCorrections.resize(0);
            {
                SKGAdvice::SKGAdviceAction a;
                a.Title = i18nc("Advice on making the best (action)", "Edit units");
                a.IconName = icon();
                a.IsRecommended = false;
                autoCorrections.push_back(a);
            }
            ad.setAutoCorrections(autoCorrections);
            output.push_back(ad);
        }
    }

    // No decimal settings
    if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_decimalsymbol")) && QLocale().decimalPoint().isNull()) {
        SKGAdvice ad;
        ad.setUUID(QStringLiteral("skgunitplugin_decimalsymbol"));
        ad.setPriority(9);
        ad.setShortMessage(i18nc("Advice on making the best (short)", "No decimal symbol defined"));
        ad.setLongMessage(i18nc("Advice on making the best (long)", "In KDE localization settings, there is no decimal symbol defined for currencies. This could be confusing."));
        SKGAdvice::SKGAdviceActionList autoCorrections;
        {
            SKGAdvice::SKGAdviceAction a;
            a.Title = i18nc("Advice on making the best (action)", "Edit KDE settings");
            a.IconName = QStringLiteral("configure");
            a.IsRecommended = false;
            autoCorrections.push_back(a);
        }
        ad.setAutoCorrections(autoCorrections);
        output.push_back(ad);
    }

    return output;
}

SKGError SKGUnitPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
    if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_primaryunit|"))) {
        if (iSolution == 1) {
            SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
        } else {
            // Get parameters
            QString unit = iAdviceIdentifier.right(iAdviceIdentifier.length() - 26);

            SKGError err;
            {
                SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Define primary currency"), err)
                SKGUnitObject unitObj(m_currentBankDocument);
                err = unitObj.setName(unit);
                IFOKDO(err, unitObj.load())
                IFOKDO(err, unitObj.setType(SKGUnitObject::PRIMARY))
                IFOKDO(err, unitObj.save())

                // Send message
                IFOKDO(err, unitObj.getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' is now the primary unit", unitObj.getDisplayName()), SKGDocument::Hidden))
            }

            // status bar
            IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Primary currency defined.")))
            else {
                err.addError(ERR_FAIL, i18nc("Error message", "Primary currency definition failed"));
            }

            // Display error
            SKGMainPanel::displayErrorMessage(err);
        }

        return SKGError();
    }
    if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_secondaryunit|"))) {
        if (iSolution == 1) {
            SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
        } else {
            // Get parameters
            QString unit = iAdviceIdentifier.right(iAdviceIdentifier.length() - 28);

            SKGError err;
            {
                SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Define secondary currency"), err)
                SKGUnitObject unitObj(m_currentBankDocument);
                err = unitObj.setName(unit);
                IFOKDO(err, unitObj.load())
                IFOKDO(err, unitObj.setType(SKGUnitObject::SECONDARY))
                IFOKDO(err, unitObj.save())

                // Send message
                IFOKDO(err, unitObj.getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' is now the secondary unit", unitObj.getDisplayName()), SKGDocument::Hidden))
            }

            // status bar
            IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Secondary currency defined.")))
            else {
                err.addError(ERR_FAIL, i18nc("Error message", "Secondary currency definition failed"));
            }

            // Display error
            SKGMainPanel::displayErrorMessage(err);
        }

        return SKGError();
    }
    if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_notdownloaded|"))) {
        if (iSolution == 0) {
            SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
        } else {
            // Get parameters
            QString unit = iAdviceIdentifier.right(iAdviceIdentifier.length() - 28);

            SKGError err;
            SKGUnitObject unitObj(m_currentBankDocument);
            err = unitObj.setName(unit);
            IFOKDO(err, unitObj.load())
            IFOKDO(err, SKGUnitPluginWidget::downloadUnitValue(unitObj, SKGUnitPluginWidget::getDownloadModeFromSettings()))

            // Display error
            SKGMainPanel::displayErrorMessage(err);
        }

        return SKGError();
    }
    if ((m_currentBankDocument != nullptr) && (iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_veryold|")) ||
            iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_toocomplex")) ||
            iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_amountnotdefined|")))
       ) {
        SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
        return SKGError();
    }
    if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_decimalsymbol"))) {
        QProcess::execute(QStringLiteral("kcmshell5"), QStringList() << QStringLiteral("formats"));
        return SKGError();
    }
    return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}

void SKGUnitPlugin::deleteUnusedUnits() const
{
    SKGError err;
    _SKGTRACEINFUNCRC(10, err)
    if (m_currentBankDocument != nullptr) {
        SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Delete unused units"), err)

        // Modification of payee object
        QString sql = QStringLiteral("DELETE FROM unit WHERE t_type NOT IN ('I', '1', '2') AND NOT EXISTS (SELECT 1 FROM operation WHERE operation.rc_unit_id=unit.id) AND NOT EXISTS (SELECT 1 FROM unit as unit2 WHERE unit2.rd_unit_id=unit.id)");
        err = m_currentBankDocument->executeSqliteOrder(sql);
    }

    // status bar
    IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Unused units deleted")))
    else {
        err.addError(ERR_FAIL, i18nc("Error message", "Unused units deletion failed"));
    }

    // Display error
    SKGMainPanel::displayErrorMessage(err);
}

#include <skgunitplugin.moc>
