/***************************************************************************
 *   Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr  *
 *                                                                         *
 *   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.  If not, see <http://www.gnu.org/licenses/>  *
 ***************************************************************************/
/** @file
 * This file is Skrooge plugin for bank management.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgalarmboardwidget.h"

#include <qaction.h>

#include <qdom.h>

#include "skgaccountobject.h"
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgprogressbar.h"
#include "skgruleobject.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgunitobject.h"

SKGAlarmBoardWidget::SKGAlarmBoardWidget(QWidget* iParent, SKGDocument* iDocument)
    : SKGBoardWidget(iParent, iDocument, i18nc("Dashboard widget title", "Alarms"))
{
    SKGTRACEINFUNC(10);

    // Create widget
    m_frame = new QFrame();
    m_layout = new QVBoxLayout(m_frame);
    m_layout->setSpacing(2);
    m_layout->setContentsMargins(0, 0, 0, 0);
    setMainWidget(m_frame);

    // Create menu
    setContextMenuPolicy(Qt::ActionsContextMenu);

    auto open = new QAction(SKGServices::fromTheme(QStringLiteral("quickopen")), i18nc("Verb, open a page", "Open..."), this);
    open->setData(QStringLiteral("skg://skrooge_search_plugin"));
    connect(open, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
        SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
    });
    addAction(open);

    m_menuFavorite = new QAction(SKGServices::fromTheme(QStringLiteral("bookmarks")), i18nc("Noun, an option in contextual menu", "Highlighted only"), this);
    m_menuFavorite->setCheckable(true);
    m_menuFavorite->setChecked(false);
    connect(m_menuFavorite, &QAction::triggered, this, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuFavorite);

    // Refresh
    connect(getDocument(), &SKGDocument::tableModified, this, &SKGAlarmBoardWidget::dataModified, Qt::QueuedConnection);
}

SKGAlarmBoardWidget::~SKGAlarmBoardWidget()
{
    SKGTRACEINFUNC(10);

    m_menuFavorite = nullptr;
}

QString SKGAlarmBoardWidget::getState()
{
    QDomDocument doc(QStringLiteral("SKGML"));
    doc.setContent(SKGBoardWidget::getState());
    QDomElement root = doc.documentElement();

    root.setAttribute(QStringLiteral("menuFavorite"), (m_menuFavorite != nullptr) && m_menuFavorite->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
    return doc.toString();
}

void SKGAlarmBoardWidget::setState(const QString& iState)
{
    SKGBoardWidget::setState(iState);

    QDomDocument doc(QStringLiteral("SKGML"));
    doc.setContent(iState);
    QDomElement root = doc.documentElement();

    if (m_menuFavorite != nullptr) {
        m_menuFavorite->setChecked(root.attribute(QStringLiteral("menuFavorite")) == QStringLiteral("Y"));
    }

    dataModified(QLatin1String(""), 0);
}

void SKGAlarmBoardWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
    SKGTRACEINFUNC(10);
    Q_UNUSED(iIdTransaction);

    if (iTableName == QStringLiteral("operation") || iTableName == QStringLiteral("rule") || iTableName.isEmpty()) {
        // Remove all item of the layout
        while (m_layout->count() != 0) {
            QLayoutItem* child = m_layout->takeAt(0);
            if (child != nullptr) {
                QWidget* w = child->widget();
                delete w;
                delete child;
            }
        }

        // Fill layout
        auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
        if (doc != nullptr) {
            SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
            SKGServices::SKGUnitInfo secondary = doc->getSecondaryUnit();

            // Build where clause
            QString wc = QStringLiteral("t_action_type='A'");
            if ((m_menuFavorite != nullptr) && m_menuFavorite->isChecked()) {
                wc = "t_bookmarked='Y' AND (" % wc % ')';
            }

            SKGObjectBase::SKGListSKGObjectBase rules;
            SKGError err = doc->getObjects(QStringLiteral("v_rule"), wc % " ORDER BY i_ORDER", rules);
            int nb = rules.count();
            if (nb != 0) {
                for (int i = 0; !err && i < nb; ++i) {
                    SKGRuleObject rule(rules.at(i));
                    SKGRuleObject::SKGAlarmInfo alarm = rule.getAlarmInfo();

                    // Create progress bar
                    auto progressBar = new SKGProgressBar(m_frame);
                    progressBar->setObjectName(QStringLiteral("progressBar"));
                    progressBar->setMaximum(qMax(alarm.Amount, alarm.Limit));
                    progressBar->setValue(alarm.Amount);

                    QSizePolicy newSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
                    newSizePolicy.setHorizontalStretch(0);
                    newSizePolicy.setVerticalStretch(0);
                    newSizePolicy.setHeightForWidth(progressBar->sizePolicy().hasHeightForWidth());
                    progressBar->setSizePolicy(newSizePolicy);

                    // Set tooltip
                    QString msg = alarm.Message;
                    // Build the message
                    if (alarm.Message.contains(QLatin1String("%3"))) {
                        msg = alarm.Message.arg(doc->formatMoney(alarm.Amount, primary, false), doc->formatMoney(alarm.Limit, primary, false), doc->formatMoney(alarm.Amount - alarm.Limit, primary, false));
                    } else if (alarm.Message.contains(QLatin1String("%2"))) {
                        msg = alarm.Message.arg(doc->formatMoney(alarm.Amount, primary, false), doc->formatMoney(alarm.Limit, primary, false));
                    } else if (alarm.Message.contains(QLatin1String("%1"))) {
                        msg = alarm.Message.arg(doc->formatMoney(alarm.Amount, primary, false));
                    }

                    QString txt = msg % "<br>";
                    txt += doc->formatMoney(alarm.Amount, primary, false) % " / " % doc->formatMoney(alarm.Limit, primary, false);
                    if (!secondary.Symbol.isEmpty() && (secondary.Value != 0.0)) {
                        txt += "<br>" % doc->formatMoney(alarm.Amount, secondary, false) % " / " % doc->formatMoney(alarm.Limit, secondary, false);
                    }
                    progressBar->setToolTip(txt);

                    // Change color
                    progressBar->setLimits(qMax(alarm.Amount, alarm.Limit), 0.9 * alarm.Limit, 0.7 * alarm.Limit);

                    // Add progress bar
                    m_layout->addWidget(progressBar);
                }
            } else {
                auto lab = new QLabel(m_frame);
                lab->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByMouse);
                lab->setText(i18nc("Message", R"(No alarm defined<br>on the <a href="%1">"Search and process"</a> page.)", "skg://Skrooge_search_plugin"));
                connect(lab, &QLabel::linkActivated, this, [ = ](const QString & val) {
                    SKGMainPanel::getMainPanel()->openPage(val);
                });

                // Add progress bar
                m_layout->addWidget(lab);
            }

            // No widget if no account
            bool exist = false;
            getDocument()->existObjects(QStringLiteral("account"), QLatin1String(""), exist);
            if (parentWidget() != nullptr) {
                setVisible(exist);
            }
        }
    }
}


