/*******************************************************************************
***  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 <pecunia/Codes.h>
using pecunia::currency::Iso4217Codes;
#include <pecunia/Money.h>
using pecunia::currency::Money;
#include <QDate>
using ::QDate;
#include <QObject>
using ::QObject;
// using Q_OBJECT
#include <QSignalSpy>
using ::QSignalSpy;
#include <QTest>
// using QTEST_MAIN
#include <qt-mocks/Matchers.h>
using qt_mocks::equals;
// using QVERIFY_FALSE
// using QVERIFY_THAT
// using QVERIFY_TRUE

#include <set>
using std::set;

#include <accounting/AccountCode.h>
using drn::accounting::AccountCode;
using drn::accounting::AccountNumber;
#include <banking/BankName.h>
using drn::banking::BankName;
#include <banking/BankAccount.h>
using drn::banking::BankAccount;
#include <banking/BankAccountType.h>
using drn::banking::BankAccountType;
using drn::banking::SupportedAccountTypes;
#include <budgeting/BudgetSource.h>
using drn::budgeting::BudgetSource;
#include <budgeting/EventFrequency.h>
using drn::budgeting::EventFrequency;
#include <budgeting/Debt.h>
using drn::budgeting::Debt;
using drn::budgeting::Percentage;
#include <foundation/ObserverPtr.hpp>
using drn::foundation::ObserverPtr;
#include <foundation/Optional.hpp>
using drn::foundation::Optional;
#include <foundation/PresentationText.h>
using drn::foundation::presentationText;
#include <internal/DebtEntryWidget.h>
using drn::desktop_ui::internal::DebtEntryWidget;


namespace drn
{
namespace desktop_ui
{
namespace internal
{
namespace tests
{

struct DebtEntryWidgetUT : QObject
{
	Q_OBJECT

	const Debt loan_{
		BudgetSource{"Car Loan"},
		Money{150u, 2000u, Iso4217Codes::USD},
		EventFrequency::Monthly,
		QDate::currentDate().addDays(5),
		Money{15000u, 2000u, Iso4217Codes::USD},
		Percentage{5.15}
	};
	const set<Iso4217Codes> usableCurrencies_{
		{
			Iso4217Codes::PLN,
			Iso4217Codes::EUR,
			Iso4217Codes::USD
		}
	};
	const BankName homeFederal_{"Home Federal"};
	const BankName c1st_{"Community 1st"};
	const set<BankName> banks_{
		{
			this->homeFederal_,
			this->c1st_
		}
	};
	const AccountCode loanCode_{AccountNumber{4004u}, this->loan_.source().name()};
	const Optional<BankAccount> bankAccount_{
		BankAccount{this->homeFederal_, BankAccountType{this->loanCode_, SupportedAccountTypes::Loan}}
	};

private slots:
	//{ constructor Tests

	void constructor_fullInitWithoutDebtWithoutAccount_ShouldBeValues()
	{
		const DebtEntryWidget widget{{}, {}, this->banks_, this->usableCurrencies_, nullptr};
		QVERIFY_FALSE(widget.originalSource().hasValue());
		QVERIFY_THAT(widget.banks(), equals(this->banks_));
		QVERIFY_THAT(widget.borrowedAmountEntry->currencies(), equals(this->usableCurrencies_));
		QVERIFY_THAT(widget.minimumAmount->currencies(), equals(this->usableCurrencies_));
		QVERIFY_THAT(widget.source(), equals(BudgetSource{}));
		QVERIFY_THAT(widget.borrowed(), equals(Money{}));
		QVERIFY_THAT(widget.period(), equals(EventFrequency::Unknown));
		QVERIFY_THAT(widget.minimum(), equals(Money{}));
		QVERIFY_THAT(widget.interest(), equals(Percentage{}));
		QVERIFY_THAT(widget.nextOccurOn(), equals(QDate::currentDate()));
		QVERIFY_FALSE(widget.bank().hasValue());
		QVERIFY_FALSE(widget.bankAccountType().hasValue());
		QVERIFY_FALSE(widget.shouldRemove());
		QVERIFY_FALSE(widget.isDirty());
	}

	void constructor_fullInitWithDebtWithoutAccount_ShouldBeValues()
	{
		const DebtEntryWidget widget{
			this->loan_,
			{},
			this->banks_,
			this->usableCurrencies_,
			nullptr
		};
		QVERIFY_THAT(widget.originalSource().valueOrDefault(), equals(this->loan_.source()));
		QVERIFY_THAT(widget.banks(), equals(this->banks_));
		QVERIFY_THAT(widget.borrowedAmountEntry->currencies(), equals(this->usableCurrencies_));
		QVERIFY_TRUE(widget.borrowedAmountEntry->isReadOnly());
		QVERIFY_THAT(widget.minimumAmount->currencies(), equals(this->usableCurrencies_));
		QVERIFY_THAT(widget.source(), equals(this->loan_.source()));
		QVERIFY_THAT(widget.borrowed(), equals(this->loan_.borrowed()));
		QVERIFY_THAT(widget.period(), equals(this->loan_.period()));
		QVERIFY_THAT(widget.minimum(), equals(this->loan_.amount()));
		QVERIFY_THAT(widget.interest(), equals(this->loan_.interest()));
		QVERIFY_THAT(widget.nextOccurOn(), equals(this->loan_.nextOccurOn()));
		QVERIFY_FALSE(widget.bank().hasValue());
		QVERIFY_FALSE(widget.bankAccountType().hasValue());
		QVERIFY_FALSE(widget.shouldRemove());
		QVERIFY_FALSE(widget.isDirty());
	}

	void constructor_fullInitWithDebtWithAccount_ShouldBeValues()
	{
		const DebtEntryWidget widget{
			this->loan_,
			this->bankAccount_,
			this->banks_,
			this->usableCurrencies_,
			nullptr
		};
		QVERIFY_THAT(widget.originalSource().valueOrDefault(), equals(this->loan_.source()));
		QVERIFY_THAT(widget.banks(), equals(this->banks_));
		QVERIFY_THAT(widget.borrowedAmountEntry->currencies(), equals(this->usableCurrencies_));
		QVERIFY_TRUE(widget.borrowedAmountEntry->isReadOnly());
		QVERIFY_THAT(widget.minimumAmount->currencies(), equals(this->usableCurrencies_));
		QVERIFY_THAT(widget.source(), equals(this->loan_.source()));
		QVERIFY_THAT(widget.borrowed(), equals(this->loan_.borrowed()));
		QVERIFY_THAT(widget.period(), equals(this->loan_.period()));
		QVERIFY_THAT(widget.minimum(), equals(this->loan_.amount()));
		QVERIFY_THAT(widget.interest(), equals(this->loan_.interest()));
		QVERIFY_THAT(widget.nextOccurOn(), equals(this->loan_.nextOccurOn()));
		QVERIFY_THAT(widget.bank().valueOrDefault(), equals(this->bankAccount_->bank_));
		QVERIFY_THAT(
			widget.borrowedFromCmbbx->accountCode().valueOrDefault(),
			equals(this->bankAccount_->account_.code_)
		);
		QVERIFY_THAT(
			widget.bankAccountType().valueOrDefault(),
			equals(this->bankAccount_->account_.type_)
		);
		QVERIFY_FALSE(widget.shouldRemove());
		QVERIFY_FALSE(widget.isDirty());
	}

	//}
};


}}}}

QTEST_MAIN(drn::desktop_ui::internal::tests::DebtEntryWidgetUT)
#include "DebtEntryWidget-unit-tests.moc"
