#include "core/anime_season.h"
#include "core/session.h"

namespace Anime {

static bool WinterStartsInDecember() {
	switch (session.config.service) {
	case Service::MyAnimeList:
		return false;
	default:
		return true;
	}
}

static Season::Name GetSeasonForMonth(Date::Month month) {
	if (WinterStartsInDecember()) {
		switch (month) {
			case Date::Month::Dec: case Date::Month::Jan: case Date::Month::Feb:
				return Season::Name::Winter;
			case Date::Month::Mar: case Date::Month::Apr: case Date::Month::May:
				return Season::Name::Spring;
			case Date::Month::Jun: case Date::Month::Jul: case Date::Month::Aug:
				return Season::Name::Summer;
			case Date::Month::Sep: case Date::Month::Oct: case Date::Month::Nov:
				return Season::Name::Autumn;
			default: return Season::Name::Unknown;
		}
	} else {
		switch (month) {
			case Date::Month::Jan: case Date::Month::Feb: case Date::Month::Mar:
				return Season::Name::Winter;
			case Date::Month::Apr: case Date::Month::May: case Date::Month::Jun:
				return Season::Name::Spring;
			case Date::Month::Jul: case Date::Month::Aug: case Date::Month::Sep:
				return Season::Name::Summer;
			case Date::Month::Oct: case Date::Month::Nov: case Date::Month::Dec:
				return Season::Name::Autumn;
			default: return Season::Name::Unknown;
		}
	}
}

Season::Season(Season::Name s, Date::Year y) {
	season = s;
	year = y;
}

Season::Season(const Date& date) {
	std::optional<Date::Month> month = date.GetMonth();
	if (month)
		season = GetSeasonForMonth(month.value());

	std::optional<Date::Year> y = date.GetYear();
	if (y)
		year = y.value();
}

bool Season::operator==(const Season& o) const {
	return (season == o.season && year == o.year);
}

bool Season::operator!=(const Season& o) const {
	return !(*this == o);
}

bool Season::operator<(const Season& o) const {
	return std::tie(season, year) < std::tie(o.season, o.year);
}

bool Season::operator>(const Season& o) const {
	return (o < *this);
}

bool Season::operator<=(const Season& o) const {
	return !(o > *this);
}

bool Season::operator>=(const Season& o) const {
	return !(*this < o);
}

Season& Season::operator++() {
	switch (season) {
		case Season::Name::Winter: season = Season::Name::Spring; break;
		case Season::Name::Spring: season = Season::Name::Summer; break;
		case Season::Name::Summer: season = Season::Name::Autumn; break;
		case Season::Name::Autumn: season = Season::Name::Winter; year++; break;
		default: season = Season::Name::Unknown; break;
	}

	return *this;
}

Season& Season::operator--() {
	switch (season) {
		case Season::Name::Winter: season = Season::Name::Autumn; year--; break;
		case Season::Name::Spring: season = Season::Name::Winter; break;
		case Season::Name::Summer: season = Season::Name::Spring; break;
		case Season::Name::Autumn: season = Season::Name::Summer; break;
		default: season = Season::Name::Unknown; break;
	}

	return *this;
}

}
