/*******************************************************************************
***  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 "UserPreferences.h"
using namespace std::chrono_literals;
using drn::foundation::Days;
using std::chrono::hours;
using std::set;
using drn::navigation::UserPreferences;

#include <pecunia/Codes.h>
using pecunia::currency::Iso4217Codes;
using pecunia::currency::toIso4217Code;
using pecunia::currency::toStdString;
#include <QString>
using ::QString;
#include <QStringList>
using ::QStringList;


namespace
{

const QString budgetingHoursInWeekKey{"Budgeting/hrInWeek"};
const QString budgetingDaysInWeekKey{"Budgeting/dayInWeek"};
const QString budgetingNotifyDueWithinKey{"Budgeting/notifyDueWithin"};
const QString currenciesPreferredKey{"Currencies/preferred"};
const QString currenciesUsableKey{"Currencies/usable"};

}

UserPreferences::UserPreferences() :
	settings_{}
{}

hours UserPreferences::hoursInWeek() const
{
	if ( ! this->settings_.contains(budgetingHoursInWeekKey))
		return 40h;
	const auto hrWeek{this->settings_.value(budgetingHoursInWeekKey).toInt()};
	return hours{hrWeek};
}

void UserPreferences::setHoursInWeek(const hours& value)
{
	this->settings_.setValue(budgetingHoursInWeekKey, static_cast<qint32>(value.count()));
}

Days UserPreferences::daysInWeek() const
{
	if ( ! this->settings_.contains(budgetingDaysInWeekKey))
		return Days{5};
	const auto dayWeek{this->settings_.value(budgetingDaysInWeekKey).toInt()};
	return Days{dayWeek};
}

void UserPreferences::setDaysInWeek(const Days& value)
{
	this->settings_.setValue(budgetingDaysInWeekKey, static_cast<qint32>(value.count()));
}

Days UserPreferences::notifyDueWithin() const
{
	if ( ! this->settings_.contains(budgetingNotifyDueWithinKey))
		return Days{14};
	const auto notifyDue{this->settings_.value(budgetingNotifyDueWithinKey).toInt()};
	return Days{notifyDue};
}

void UserPreferences::setNotifyDueWithin(const Days& value)
{
	this->settings_.setValue(budgetingNotifyDueWithinKey, static_cast<qint32>(value.count()));
}

Iso4217Codes UserPreferences::preferredCurrency() const
{
	if ( ! this->settings_.contains(currenciesPreferredKey))
		return Iso4217Codes::USD;
	const auto code{this->settings_.value(currenciesPreferredKey).toString()};
	return toIso4217Code(code.toStdString());
}

void UserPreferences::setPreferredCurrency(const Iso4217Codes& value)
{
	this->settings_.setValue(currenciesPreferredKey, QString::fromStdString(toStdString(value)));
}

set<Iso4217Codes> UserPreferences::usableCurrencies() const
{
	if ( ! this->settings_.contains(currenciesUsableKey))
		return {this->preferredCurrency()};
	const auto codes{this->settings_.value(currenciesUsableKey).toStringList()};
	set<Iso4217Codes> usable;

	for (const auto& code : codes)
		usable.emplace(toIso4217Code(code.toStdString()));
	return usable;
}

void UserPreferences::setUsableCurrencies(const set<Iso4217Codes>& values)
{
	QStringList currencies{};

	for (const auto& code : values)
		currencies << QString::fromStdString(toStdString(code));
	this->settings_.setValue(currenciesUsableKey, currencies);
}
