/***************************************************************************
 *   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 "skgaccountboardwidget.h"

#include <qaction.h>

#include <QDomDocument>

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

SKGAccountBoardWidget::SKGAccountBoardWidget(SKGDocument* iDocument)
    : SKGBoardWidget(iDocument, i18nc("Title of a dashboard widget", "Accounts")), m_refreshNeeded(true)
{
    SKGTRACEINFUNC(10);

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

    // menu
    m_menuFavorite = new QAction(QIcon::fromTheme("bookmarks"), i18nc("Display only favorite accounts", "Highlighted only"), this);
    m_menuFavorite->setCheckable(true);
    m_menuFavorite->setChecked(false);
    connect(m_menuFavorite, &QAction::triggered, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuFavorite);

    m_menuPastOperations = new QAction(i18nc("Noun, a type of account", "Only past operations"), this);
    m_menuPastOperations->setCheckable(true);
    m_menuPastOperations->setChecked(false);
    connect(m_menuPastOperations, &QAction::triggered, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuPastOperations);

    {
        QAction* sep = new QAction(this);
        sep->setSeparator(true);
        addAction(sep);
    }

    m_menuAssets = new QAction(i18nc("Noun, a type of account", "Assets"), this);
    m_menuAssets->setCheckable(true);
    m_menuAssets->setChecked(true);
    connect(m_menuAssets, &QAction::triggered, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuAssets);

    m_menuCurrent = new QAction(i18nc("Noun, a type of account", "Current"), this);
    m_menuCurrent->setCheckable(true);
    m_menuCurrent->setChecked(true);
    connect(m_menuCurrent, &QAction::triggered, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuCurrent);

    m_menuCreditCard = new QAction(i18nc("Noun, a type of account", "Credit card"), this);
    m_menuCreditCard->setCheckable(true);
    m_menuCreditCard->setChecked(true);
    connect(m_menuCreditCard, &QAction::triggered, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuCreditCard);

    m_menuSaving = new QAction(i18nc("Noun, a type of account", "Saving"), this);
    m_menuSaving->setCheckable(true);
    m_menuSaving->setChecked(true);
    connect(m_menuSaving, &QAction::triggered, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuSaving);

    m_menuInvestment = new QAction(i18nc("Noun, a type of account", "Investment"), this);
    m_menuInvestment->setCheckable(true);
    m_menuInvestment->setChecked(true);
    connect(m_menuInvestment, &QAction::triggered, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuInvestment);

    m_menuWallet = new QAction(i18nc("Noun, a type of account", "Wallet"), this);
    m_menuWallet->setCheckable(true);
    m_menuWallet->setChecked(true);
    connect(m_menuWallet, &QAction::triggered, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuWallet);

    m_menuLoan = new QAction(i18nc("Noun, a type of account", "Loan"), this);
    m_menuLoan->setCheckable(true);
    m_menuLoan->setChecked(true);
    connect(m_menuLoan, &QAction::triggered, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuLoan);

    m_menuOther = new QAction(i18nc("Noun, a type of account", "Other"), this);
    m_menuOther->setCheckable(true);
    m_menuOther->setChecked(true);
    connect(m_menuOther, &QAction::triggered, [ = ]() {
        this->dataModified();
    });
    addAction(m_menuOther);

    m_label = new QLabel();
    setMainWidget(m_label);

    // Refresh
    connect(getDocument(), &SKGDocument::tableModified, this, &SKGAccountBoardWidget::dataModified, Qt::QueuedConnection);
    connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::currentPageChanged, this, &SKGAccountBoardWidget::pageChanged, Qt::QueuedConnection);
    connect(m_label, &QLabel::linkActivated, [ = ](const QString & val) {
        SKGMainPanel::getMainPanel()->openPage(val);
    });
}

SKGAccountBoardWidget::~SKGAccountBoardWidget()
{
    SKGTRACEINFUNC(10);
    m_menuAssets = NULL;
    m_menuCurrent = NULL;
    m_menuCreditCard = NULL;
    m_menuSaving = NULL;
    m_menuInvestment = NULL;
    m_menuWallet = NULL;
    m_menuLoan = NULL;
    m_menuOther = NULL;
    m_menuFavorite = NULL;
    m_menuPastOperations = NULL;
}

QString SKGAccountBoardWidget::getState()
{
    QDomDocument doc("SKGML");
    QDomElement root = doc.createElement("parameters");
    doc.appendChild(root);

    root.setAttribute("menuFavorite", m_menuFavorite && m_menuFavorite->isChecked() ? "Y" : "N");
    root.setAttribute("menuAssets", m_menuAssets && m_menuAssets->isChecked() ? "Y" : "N");
    root.setAttribute("menuCurrent", m_menuCurrent && m_menuCurrent->isChecked() ? "Y" : "N");
    root.setAttribute("menuCreditCard", m_menuCreditCard && m_menuCreditCard->isChecked() ? "Y" : "N");
    root.setAttribute("menuSaving", m_menuSaving && m_menuSaving->isChecked() ? "Y" : "N");
    root.setAttribute("menuInvestment", m_menuInvestment && m_menuInvestment->isChecked() ? "Y" : "N");
    root.setAttribute("menuWallet", m_menuWallet && m_menuWallet->isChecked() ? "Y" : "N");
    root.setAttribute("m_menuLoan", m_menuLoan && m_menuLoan->isChecked() ? "Y" : "N");
    root.setAttribute("menuOther", m_menuOther && m_menuOther->isChecked() ? "Y" : "N");
    root.setAttribute("menuPastOperations", m_menuPastOperations && m_menuPastOperations->isChecked() ? "Y" : "N");

    return doc.toString();
}

void SKGAccountBoardWidget::setState(const QString& iState)
{
    QDomDocument doc("SKGML");
    doc.setContent(iState);
    QDomElement root = doc.documentElement();

    if (m_menuFavorite) {
        m_menuFavorite->setChecked(root.attribute("menuFavorite") == "Y");
    }
    if (m_menuAssets) {
        m_menuAssets->setChecked(root.attribute("menuAssets") != "N");
    }
    if (m_menuCurrent) {
        m_menuCurrent->setChecked(root.attribute("menuCurrent") != "N");
    }
    if (m_menuCreditCard) {
        m_menuCreditCard->setChecked(root.attribute("menuCreditCard") != "N");
    }
    if (m_menuSaving) {
        m_menuSaving->setChecked(root.attribute("menuSaving") != "N");
    }
    if (m_menuInvestment) {
        m_menuInvestment->setChecked(root.attribute("menuInvestment") != "N");
    }
    if (m_menuWallet) {
        m_menuWallet->setChecked(root.attribute("menuWallet") != "N");
    }
    if (m_menuLoan) {
        m_menuLoan->setChecked(root.attribute("m_menuLoan") != "N");
    }
    if (m_menuOther) {
        m_menuOther->setChecked(root.attribute("menuOther") != "N");
    }
    if (m_menuPastOperations) {
        m_menuPastOperations->setChecked(root.attribute("menuPastOperations") == "Y");
    }

    dataModified("", 0);
}

void SKGAccountBoardWidget::pageChanged()
{
    if (m_refreshNeeded) {
        dataModified("", 0);
    }
}

void SKGAccountBoardWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
    Q_UNUSED(iIdTransaction);

    if (iTableName == "v_account_display" || iTableName.isEmpty()) {
        SKGTRACEINFUNC(10);
        SKGTabPage* page = SKGTabPage::parentTabPage(this);
        if (page != NULL && page != SKGMainPanel::getMainPanel()->currentPage()) {
            m_refreshNeeded = true;
            return;
        }

        m_refreshNeeded = false;
        SKGDocumentBank* doc = qobject_cast<SKGDocumentBank*>(getDocument());
        if (doc) {
            SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
            bool exist = false;
            SKGError err = doc->existObjects("account", "", exist);
            IFOK(err) {
                QString html;
                if (!exist) {
                    html = "<html><body>" % i18nc("Message, do not translate URL", "First, you have to create at least one account<br>from <a href=\"%1\">\"Bank and Account\"</a> page or <a href=\"%2\">import</a> operations.", "skg://Skrooge_bank_plugin", "skg://import_operation") % "</body></html>";
                } else {
                    // Build where clause
                    QString wc;
                    if (m_menuAssets && m_menuAssets->isChecked()) {
                        wc = "t_type='A'";
                    }
                    if (m_menuCurrent && m_menuCurrent->isChecked()) {
                        if (!wc.isEmpty()) {
                            wc += " OR ";
                        }
                        wc += "t_type='C'";
                    }
                    if (m_menuCreditCard && m_menuCreditCard->isChecked()) {
                        if (!wc.isEmpty()) {
                            wc += " OR ";
                        }
                        wc += "t_type='D'";
                    }
                    if (m_menuSaving && m_menuSaving->isChecked()) {
                        if (!wc.isEmpty()) {
                            wc += " OR ";
                        }
                        wc += "t_type='S'";
                    }
                    if (m_menuInvestment && m_menuInvestment->isChecked()) {
                        if (!wc.isEmpty()) {
                            wc += " OR ";
                        }
                        wc += "t_type='I'";
                    }
                    if (m_menuWallet && m_menuWallet->isChecked()) {
                        if (!wc.isEmpty()) {
                            wc += " OR ";
                        }
                        wc += "t_type='W'";
                    }
                    if (m_menuLoan && m_menuLoan->isChecked()) {
                        if (!wc.isEmpty()) {
                            wc += " OR ";
                        }
                        wc += "t_type='L'";
                    }
                    if (m_menuOther && m_menuOther->isChecked()) {
                        if (!wc.isEmpty()) {
                            wc += " OR ";
                        }
                        wc += "t_type='O'";
                    }

                    if (wc.isEmpty()) {
                        wc = "1=0";
                    } else if (m_menuFavorite && m_menuFavorite->isChecked()) {
                        wc = "t_bookmarked='Y' AND (" % wc % ')';
                    }

                    // Build display
                    SKGStringListList listTmp;
                    err = doc->executeSelectSqliteOrder(
                              QString("SELECT t_name, t_TYPENLS, t_UNIT, ") % (m_menuPastOperations && m_menuPastOperations->isChecked() ? "f_TODAYAMOUNT" : "f_CURRENTAMOUNT") % ", t_close  from v_account_display WHERE (" % wc % ") ORDER BY t_TYPENLS, t_name",
                              listTmp);
                    IFOK(err) {
                        html += "<html><body><table>";
                        double sumTypeV1 = 0;
                        double sumV1 = 0;
                        QString currentType;
                        int nb = listTmp.count();
                        for (int i = 1; i < nb; ++i) {  // Ignore header
                            QStringList r = listTmp.at(i);
                            QString name = r.at(0);
                            QString type = r.at(1);
                            QString unitAccountSymbol = r.at(2);
                            double v1 = SKGServices::stringToDouble(r.at(3));
                            bool closed = (r.at(4) == "Y");

                            if (type != currentType) {
                                if (!currentType.isEmpty()) {
                                    html += "<tr><td><b>" % SKGServices::stringToHtml(i18nc("the numerical total of a sum of values", "Total of %1", currentType)) % "</b></td>"
                                            "<td align=\"right\"><b>" % doc->formatMoney(sumTypeV1, primary) % "</b></td></tr>";
                                    sumTypeV1 = 0;
                                }
                                currentType = type;
                            }
                            if (!closed || qAbs(v1) > 0.1) {
                                html += QString("<tr><td><a href=\"skg://Skrooge_operation_plugin/?account=" % SKGServices::encodeForUrl(name) % "\">") % SKGServices::stringToHtml(name) % "</a></td>"
                                        "<td align=\"right\">";

                                if (!unitAccountSymbol.isEmpty() && primary.Symbol != unitAccountSymbol) {
                                    SKGUnitObject unitAccount(getDocument());
                                    unitAccount.setSymbol(unitAccountSymbol);
                                    unitAccount.load();

                                    double unitAccountValue = SKGServices::stringToDouble(unitAccount.getAttribute("f_CURRENTAMOUNT"));
                                    SKGServices::SKGUnitInfo u2 = primary;
                                    u2.Symbol = unitAccountSymbol;
                                    u2.NbDecimal = unitAccount.getNumberDecimal();
                                    html += doc->formatMoney(v1 / unitAccountValue, u2);
                                    html += '=';
                                }
                                html += doc->formatMoney(v1, primary);
                                html += "</td></tr>";
                            }
                            sumTypeV1 += v1;
                            sumV1 += v1;
                        }

                        if (!currentType.isEmpty()) {
                            html += "<tr><td><b>" % SKGServices::stringToHtml(i18nc("the numerical total of a sum of values", "Total of %1", currentType)) % "</b></td>"
                                    "<td align=\"right\"><b>" % doc->formatMoney(sumTypeV1, primary) % "</b></td>"
                                    "</tr>";
                        }
                        html += "<tr><td><b>" % SKGServices::stringToHtml(i18nc("Noun, the numerical total of a sum of values", "Total")) % "</b></td>"
                                "<td align=\"right\"><b>" % doc->formatMoney(sumV1, primary) % "</b></td>"
                                "</tr>";
                        html += "</table></body></html>";
                    }
                }
                m_label->setText(html);
            }
        }
    }
}

