/***************************************************************************
 *   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 a generic Skrooge plugin for html reports.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skghtmlboardwidget.h"

#include <qtoolbutton.h>
#include <qwidgetaction.h>
#include <qdom.h>
#include <qfileinfo.h>
#include <qquickwidget.h>
#include <qquickitem.h>
#include <qqmlcontext.h>
#include <qtemporaryfile.h>

#include <klocalizedstring.h>

#include "skgdocument.h"
#include "skgtraces.h"
#include "skgreport.h"
#include "skgmainpanel.h"

SKGHtmlBoardWidget::SKGHtmlBoardWidget(SKGDocument* iDocument, const QString& iTitle, const QString& iTemplate, const QStringList& iTablesRefreshing, SKGSimplePeriodEdit::Modes iOptions)
    : SKGBoardWidget(iDocument, iTitle), m_Quick(nullptr), m_Text(nullptr), m_Report(iDocument->getReport()),  m_Template(iTemplate), m_TablesRefreshing(iTablesRefreshing), m_refreshNeeded(false), m_period(nullptr)
{
    SKGTRACEINFUNC(10);
    // Create menu
    if (iOptions != SKGSimplePeriodEdit::NONE) {
        setContextMenuPolicy(Qt::ActionsContextMenu);

        m_period = new SKGSimplePeriodEdit(this);
        m_period->setMode(iOptions);

        QDate date = QDate::currentDate();
        QStringList list;
        // TODO(Stephane MANKOWSKI): v_operation_display must be generic
        getDocument()->getDistinctValues(QStringLiteral("v_operation_display"), QStringLiteral("MIN(d_DATEMONTH)"), QStringLiteral("d_date<=CURRENT_DATE"), list);
        if (!list.isEmpty()) {
            if (!list[0].isEmpty()) {
                date = SKGServices::periodToDate(list[0]);
            }
        }
        m_period->setFirstDate(date);

        auto periodEditWidget = new QWidgetAction(this);
        periodEditWidget->setDefaultWidget(m_period);

        addAction(periodEditWidget);
    }

    // Create main widget
    QString ext = QFileInfo(iTemplate).suffix().toLower();
    if (ext == QStringLiteral("qml")) {
        // Mode QML
        m_Quick = new QQuickWidget(this);
        m_Quick->setResizeMode(QQuickWidget::SizeViewToRootObject);
        m_Quick->setClearColor(Qt::transparent);
        m_Quick->setAttribute(Qt::WA_AlwaysStackOnTop);
        m_Quick->setAttribute(Qt::WA_TranslucentBackground);
        m_Quick->setObjectName(QStringLiteral("m_Quick"));
        QSizePolicy newSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
        newSizePolicy.setHorizontalStretch(0);
        newSizePolicy.setVerticalStretch(0);
        m_Quick->setSizePolicy(newSizePolicy);

        // Set properties
        QVariantHash mapping = m_Report->getContextProperty();
        auto keys = mapping.keys();
        for (const auto& k : qAsConst(keys)) {
            m_Quick->rootContext()->setContextProperty(k, mapping[k]);
        }
        m_Quick->rootContext()->setContextProperty(QStringLiteral("periodWidget"), m_period);
        m_Quick->rootContext()->setContextProperty(QStringLiteral("panel"), SKGMainPanel::getMainPanel());

        setMainWidget(m_Quick);
    } else {
        // Mode template HTML
        m_Text = new QLabel(this);
        m_Text->setObjectName(QStringLiteral("m_Text"));
        m_Text->setTextFormat(Qt::RichText);
        m_Text->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop);
        m_Text->setTextInteractionFlags(Qt::TextBrowserInteraction);
        connect(m_Text, &QLabel::linkActivated, [ = ](const QString & val) {
            SKGMainPanel::getMainPanel()->openPage(val);
        });

        setMainWidget(m_Text);
    }

    // Connects
    connect(getDocument(), &SKGDocument::tableModified, this, &SKGHtmlBoardWidget::dataModified, Qt::QueuedConnection);
    if (m_period) {
        connect(m_period, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentIndexChanged), [ = ]() {
            this->dataModified();
        });
    }
    connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::currentPageChanged, this, &SKGHtmlBoardWidget::pageChanged, Qt::QueuedConnection);
}

SKGHtmlBoardWidget::~SKGHtmlBoardWidget()
{
    SKGTRACEINFUNC(10);
    m_period = nullptr;
    if (m_Report) {
        delete m_Report;
        m_Report = nullptr;
    }
}

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

    // Get state
    if (m_period) {
        root.setAttribute(QStringLiteral("period"), m_period->text());
    }

    return doc.toString();
}

void SKGHtmlBoardWidget::setState(const QString& iState)
{
    SKGTRACEINFUNC(10);
    SKGBoardWidget::setState(iState);

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

    // Set state
    if (m_period) {
        QString oldMode = root.attribute(QStringLiteral("previousMonth"));
        if (oldMode.isEmpty()) {
            QString period = root.attribute(QStringLiteral("period"));
            if (!period.isEmpty() && m_period->contains(period)) {
                m_period->setText(period);
            }
        } else {
            m_period->setText(oldMode == QStringLiteral("N") ? i18nc("The current month", "Current month") : i18nc("The month before the current month", "Last month"));
        }
    }

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

void SKGHtmlBoardWidget::pageChanged()
{
    if (m_refreshNeeded) {
        dataModified();
    }
}

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

    // Set title
    QString period = (m_period ? m_period->period() : QStringLiteral(""));
    QString title = getOriginalTitle();
    if (title.contains(QStringLiteral("%1"))) {
        setMainTitle(title.arg(period));
    }

    if (m_Report) {
        m_Report->setPeriod((m_period ? m_period->period() : SKGServices::dateToPeriod(QDate::currentDate(), QStringLiteral("M"))));
    }

    if (m_TablesRefreshing.isEmpty() || m_TablesRefreshing.contains(iTableName) || iTableName.isEmpty()) {
        // Is this the current page
        SKGTabPage* page = SKGTabPage::parentTabPage(this);
        if (page != nullptr && page != SKGMainPanel::getMainPanel()->currentPage()) {
            // No, we memorize that we have to compute later the report
            m_refreshNeeded = true;
            return;
        }

        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
        if (m_Quick != nullptr) {
            // Set the source
            if (!m_Quick->source().isValid()) {
                m_Quick->setSource(QUrl::fromLocalFile(m_Template));

                QQuickItem* root = m_Quick->rootObject();
                if (root) {
                    connect(root, &QQuickItem::widthChanged, this, [ = ]() {
                        m_Quick->setMinimumSize(QSize(root->width(), root->height()));
                    });
                    connect(root, &QQuickItem::heightChanged, this, [ = ]() {
                        m_Quick->setMinimumSize(QSize(root->width(), root->height()));
                    });
                    m_Quick->setMinimumSize(QSize(root->width(), root->height()));
                    m_Quick->setMinimumSize(QSize(root->width(), root->height()));
                }
            } else {
                // Clean the cache to trigger the modification
                m_Report->cleanCache();
            }

            m_refreshNeeded = false;
        }

        if (m_Text != nullptr) {
            // Clean the cache to trigger the modification
            m_Report->cleanCache();

            QString stream;
            SKGError err = SKGReport::getReportFromTemplate(m_Report, m_Template, stream);
            IFKO(err) stream = err.getFullMessage();
            stream = stream.remove(QRegExp(QStringLiteral("<img[^>]*/>")));
            m_Text->setText(stream);

            m_refreshNeeded = false;
        }
        QApplication::restoreOverrideCursor();
    }

    // TODO(Stephane MANKOWSKI): No widget if no account (must not be hardcoded)
    bool exist = false;
    getDocument()->existObjects(QStringLiteral("account"), QStringLiteral(""), exist);
    if (parentWidget()) {
        setVisible(exist);
    }
}
#include "skghtmlboardwidget.h"
