/*******************************************************************************
***  This file is part of Dux Rei Nummariae.                                 ***
***                                                                          ***
***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
***                                                                          ***
***  This program is free software: you can redistribute it and/or modify it ***
***  under the terms of the GNU Affero General Public License as published   ***
***  by the Free Software Foundation, either version 3 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 Affero General Public License for more details.             ***
***                                                                          ***
***  You should have received a copy of the GNU Affero General Public License***
***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
*******************************************************************************/
#include "BudgetItemsDueWidget.h"
using ::QWidget;
using std::vector;
using drn::desktop_ui::internal::BudgetItemsDueWidget;
using drn::foundation::Days;

#include <QBrush>
using ::QBrush;
#include <QDate>
using ::QDate;
#include <QDateTime>
using ::QDateTime;
#include <QString>
using ::QString;
#include <QtDebug>
// using qDebug
#include <QTableWidget>
using ::QTableWidget;
#include <QTableWidgetItem>
using ::QTableWidgetItem;

#include <chrono>
using std::chrono::duration_cast;
using std::chrono::system_clock;
#include <memory>
using std::make_unique;

#include <budgeting/Budget.h>
using drn::budgeting::Budget;
#include <budgeting/BudgetItemDue.h>
using drn::budgeting::BudgetItemDue;
#include <budgeting/BudgetedMoney.h>
using drn::budgeting::BudgetedMoney;
#include <budgeting/BudgetSource.h>
using drn::budgeting::BudgetSource;
#include <foundation/ObserverPtr.hpp>
using drn::foundation::ObserverPtr;


namespace
{

const auto budgetSourceNameColumn{0};
const auto dueDateColumn{1};

bool addBudgetItem(
	const qint32 rowIndex,
	const BudgetSource& source,
	const QDateTime& itemDueOn,
	QTableWidget* tableWidget,
	const Days& within,
	const QDateTime& today,
	const qint64& nearlyDue,
	const qint64& veryNearlyDue
)
{
	const auto daysTo{today.daysTo(itemDueOn)};
	qDebug() << "The budget item " << source.name() << " is due within " << daysTo << " days.";

	if (daysTo > within.count())
		return false;
	const auto& normalColour{tableWidget->palette().color(tableWidget->backgroundRole())};
	const QBrush backgroundColour{
		[&daysTo, &nearlyDue, &normalColour, &veryNearlyDue]()
		{
			if (daysTo > veryNearlyDue && daysTo <= nearlyDue)
				return QBrush{QColor{Qt::green}};

			if (daysTo > 0 && daysTo <= veryNearlyDue)
				return QBrush{QColor{Qt::yellow}};

			if (daysTo == 0)
				return QBrush{QColor{Qt::red}};

			if (daysTo < 0)
				return QBrush{QColor{Qt::darkRed}};
			return QBrush{normalColour};
		}()
	};
	auto sourceName{make_unique<QTableWidgetItem>(source.name())};
	sourceName->setBackground(backgroundColour);

	if (backgroundColour != normalColour)
		sourceName->setForeground(Qt::black);
	tableWidget->setItem(rowIndex, budgetSourceNameColumn, sourceName.release());
	auto dueOn{make_unique<QTableWidgetItem>(itemDueOn.date().toString())};
	dueOn->setBackground(backgroundColour);

	if (backgroundColour != normalColour)
		dueOn->setForeground(Qt::black);
	tableWidget->setItem(rowIndex, dueDateColumn, dueOn.release());
	return true;
}

}

BudgetItemsDueWidget::BudgetItemsDueWidget(const ObserverPtr<QWidget>& parent) :
	QWidget{parent.observed()}
{
	this->setupUi(this);
}

void BudgetItemsDueWidget::updateDue(const vector<BudgetItemDue>& itemsDue, const Days& within)
{
	qDebug() << "Updating the budget items due";
	this->budgetItemsDueTblwdgt->setRowCount(static_cast<qint32>(itemsDue.size()));
	const auto today{QDateTime::currentDateTime()};
	const auto nearlyDue{within / 2};
	const auto veryNearlyDue{within / 4};
	qint32 rowIndex{0};

	for (const auto& itemDue : itemsDue)
	{
		addBudgetItem(
			rowIndex,
			itemDue.id_.source_,
			QDateTime{
				QDate{
					static_cast<qint32>(itemDue.dueOn_.year()),
					static_cast<qint32>(static_cast<unsigned>(itemDue.dueOn_.month())),
					static_cast<qint32>(static_cast<unsigned>(itemDue.dueOn_.day()))
				},
				{}
			},
			this->budgetItemsDueTblwdgt,
			within,
			today,
			nearlyDue.count(),
			veryNearlyDue.count()
		);
		++rowIndex;
	}
	// TODO: Should show a total of everything going out in that timeframe, e.g. Going out next 14 days: 2000 PLN
}

void BudgetItemsDueWidget::resizeEvent(QResizeEvent* event)
{
	this->budgetItemsDueTblwdgt->setColumnWidth(budgetSourceNameColumn, 2 * this->width() / 3);
	this->budgetItemsDueTblwdgt->setColumnWidth(dueDateColumn, this->width() / 3);
	QWidget::resizeEvent(event);
}

