#include "core/anime.h"
#include "core/strings.h"
#include "gui/translate/anime.h"
#include <QCoreApplication>

namespace Translate {

std::string ToString(const Anime::ListStatus status) {
	switch (status) {
		case Anime::ListStatus::CURRENT: return "Currently watching";
		case Anime::ListStatus::PLANNING: return "Plan to watch";
		case Anime::ListStatus::COMPLETED: return "Completed";
		case Anime::ListStatus::DROPPED: return "Dropped";
		case Anime::ListStatus::PAUSED: return "On hold";
		default:
		case Anime::ListStatus::NOT_IN_LIST: return "Not in list";
	}
}

std::string ToString(const Anime::SeriesFormat format) {
	switch (format) {
		case Anime::SeriesFormat::TV: return "TV";
		case Anime::SeriesFormat::TV_SHORT: return "TV short";
		case Anime::SeriesFormat::OVA: return "OVA";
		case Anime::SeriesFormat::MOVIE: return "Movie";
		case Anime::SeriesFormat::SPECIAL: return "Special";
		case Anime::SeriesFormat::ONA: return "ONA";
		case Anime::SeriesFormat::MUSIC: return "Music";
		default:
		case Anime::SeriesFormat::UNKNOWN: return "Unknown";
	}
}

std::string ToString(const Anime::SeriesSeason season) {
	switch (season) {
		case Anime::SeriesSeason::WINTER: return "Winter";
		case Anime::SeriesSeason::SUMMER: return "Summer";
		case Anime::SeriesSeason::FALL: return "Fall";
		case Anime::SeriesSeason::SPRING: return "Spring";
		default:
		case Anime::SeriesSeason::UNKNOWN: return "Unknown";
	}
}

std::string ToString(const Anime::SeriesStatus status) {
	switch (status) {
		case Anime::SeriesStatus::RELEASING: return "Currently airing";
		case Anime::SeriesStatus::FINISHED: return "Finished airing";
		case Anime::SeriesStatus::NOT_YET_RELEASED: return "Not yet aired";
		case Anime::SeriesStatus::CANCELLED: return "Cancelled";
		case Anime::SeriesStatus::HIATUS: return "On hiatus";
		default:
		case Anime::SeriesStatus::UNKNOWN: return "Unknown";
	}
}

std::string ToString(const Anime::Services service) {
	switch (service) {
		case Anime::Services::ANILIST: return "AniList";
		default:
		case Anime::Services::NONE:    return "None";
	}
}

std::string ToString(const Anime::TitleLanguage language) {
	switch (language) {
		case Anime::TitleLanguage::NATIVE:  return "Native";
		case Anime::TitleLanguage::ENGLISH: return "English";
		default:
		case Anime::TitleLanguage::ROMAJI:  return "Romaji";
	}
}

std::string ToString(const Anime::ScoreFormat format) {
	switch (format) {
		case Anime::ScoreFormat::POINT_3: return "POINT_3";
		case Anime::ScoreFormat::POINT_5: return "POINT_5";
		case Anime::ScoreFormat::POINT_10: return "POINT_10";
		case Anime::ScoreFormat::POINT_10_DECIMAL: return "POINT_10_DECIMAL";
		default:
		case Anime::ScoreFormat::POINT_100: return "POINT_100";
	}
}

Anime::ListStatus ToListStatus(const std::string& str) {
	const std::unordered_map<std::string, Anime::ListStatus> map = {
	    {"Currently watching", Anime::ListStatus::CURRENT},
	    {"Plan to watch", Anime::ListStatus::PLANNING},
	    {"Completed", Anime::ListStatus::COMPLETED},
	    {"Dropped", Anime::ListStatus::DROPPED},
	    {"On hold", Anime::ListStatus::PAUSED}
	};

	if (map.find(str) == map.end())
		return Anime::ListStatus::NOT_IN_LIST;
	return map.at(str);
}

Anime::SeriesStatus ToSeriesStatus(const std::string& str) {
	const std::unordered_map<std::string, Anime::SeriesStatus> map = {
	    {"Currently airing", Anime::SeriesStatus::RELEASING},
	    {"Finished airing", Anime::SeriesStatus::FINISHED},
	    {"Not yet aired", Anime::SeriesStatus::NOT_YET_RELEASED},
	    {"Cancelled", Anime::SeriesStatus::CANCELLED},
	    {"On hiatus", Anime::SeriesStatus::HIATUS}
	};

	if (map.find(str) == map.end())
		return Anime::SeriesStatus::UNKNOWN;
	return map.at(str);
}

Anime::SeriesSeason ToSeriesSeason(const std::string& str) {
	const std::unordered_map<std::string, Anime::SeriesSeason> map = {
	    {"Winter", Anime::SeriesSeason::WINTER},
	    {"Summer", Anime::SeriesSeason::SUMMER},
	    {"Fall", Anime::SeriesSeason::FALL},
	    {"Spring", Anime::SeriesSeason::SPRING}
	};

	if (map.find(str) == map.end())
		return Anime::SeriesSeason::UNKNOWN;
	return map.at(str);
}

Anime::SeriesFormat ToSeriesFormat(const std::string& str) {
	const std::unordered_map<std::string, Anime::SeriesFormat> map = {
	    {"TV", Anime::SeriesFormat::TV},
	    {"TV short", Anime::SeriesFormat::TV_SHORT},
	    {"OVA", Anime::SeriesFormat::OVA},
	    {"Movie", Anime::SeriesFormat::MOVIE},
	    {"Special", Anime::SeriesFormat::SPECIAL},
	    {"ONA", Anime::SeriesFormat::ONA},
	    {"Music", Anime::SeriesFormat::MUSIC}
	};

	if (map.find(str) == map.end())
		return Anime::SeriesFormat::UNKNOWN;
	return map.at(str);
}

Anime::Services ToService(const std::string& str) {
	const std::unordered_map<std::string, Anime::Services> map = {
	    {"AniList", Anime::Services::ANILIST}
	};

	if (map.find(str) == map.end())
		return Anime::Services::NONE;
	return map.at(str);
}

Anime::TitleLanguage ToLanguage(const std::string& str) {
	const std::unordered_map<std::string, Anime::TitleLanguage> map = {
	    {"Romaji", Anime::TitleLanguage::ROMAJI},
	    {"Native", Anime::TitleLanguage::NATIVE},
	    {"English", Anime::TitleLanguage::ENGLISH}
	};

	if (map.find(str) == map.end())
		return Anime::TitleLanguage::ROMAJI;
	return map.at(str);
}

Anime::ScoreFormat ToScoreFormat(const std::string& str) {
	const std::unordered_map<std::string, Anime::ScoreFormat> map = {
	    {"POINT_3", Anime::ScoreFormat::POINT_3},
	    {"POINT_5", Anime::ScoreFormat::POINT_5},
	    {"POINT_10", Anime::ScoreFormat::POINT_10},
	    {"POINT_10_DECIMAL", Anime::ScoreFormat::POINT_10_DECIMAL},
	    {"POINT_100", Anime::ScoreFormat::POINT_100}
	};

	if (map.find(str) == map.end())
		return Anime::ScoreFormat::POINT_100;
	return map.at(str);
}

/* Localized versions of ToString() functions */

std::string ToLocalString(const Anime::ListStatus status) {
	switch (status) {
		case Anime::ListStatus::CURRENT: return Strings::ToUtf8String(QCoreApplication::tr("Currently watching"));
		case Anime::ListStatus::PLANNING: return Strings::ToUtf8String(QCoreApplication::tr("Plan to watch"));
		case Anime::ListStatus::COMPLETED: return Strings::ToUtf8String(QCoreApplication::tr("Completed"));
		case Anime::ListStatus::DROPPED: return Strings::ToUtf8String(QCoreApplication::tr("Dropped"));
		case Anime::ListStatus::PAUSED: return Strings::ToUtf8String(QCoreApplication::tr("On hold"));
		default:
		case Anime::ListStatus::NOT_IN_LIST: return Strings::ToUtf8String(QCoreApplication::tr("Not in list"));
	}
}

std::string ToLocalString(const Anime::SeriesFormat format) {
	switch (format) {
		case Anime::SeriesFormat::TV: return Strings::ToUtf8String(QCoreApplication::tr("TV"));
		case Anime::SeriesFormat::TV_SHORT: return Strings::ToUtf8String(QCoreApplication::tr("TV short"));
		case Anime::SeriesFormat::OVA: return Strings::ToUtf8String(QCoreApplication::tr("OVA"));
		case Anime::SeriesFormat::MOVIE: return Strings::ToUtf8String(QCoreApplication::tr("Movie"));
		case Anime::SeriesFormat::SPECIAL: return Strings::ToUtf8String(QCoreApplication::tr("Special"));
		case Anime::SeriesFormat::ONA: return Strings::ToUtf8String(QCoreApplication::tr("ONA"));
		case Anime::SeriesFormat::MUSIC: return Strings::ToUtf8String(QCoreApplication::tr("Music"));
		default:
		case Anime::SeriesFormat::UNKNOWN: return Strings::ToUtf8String(QCoreApplication::tr("Unknown"));
	}
}

std::string ToLocalString(const Anime::SeriesSeason season) {
	switch (season) {
		case Anime::SeriesSeason::WINTER: return Strings::ToUtf8String(QCoreApplication::tr("Winter"));
		case Anime::SeriesSeason::SUMMER: return Strings::ToUtf8String(QCoreApplication::tr("Summer"));
		case Anime::SeriesSeason::FALL: return Strings::ToUtf8String(QCoreApplication::tr("Fall"));
		case Anime::SeriesSeason::SPRING: return Strings::ToUtf8String(QCoreApplication::tr("Spring"));
		default:
		case Anime::SeriesSeason::UNKNOWN: return Strings::ToUtf8String(QCoreApplication::tr("Unknown"));
	}
}

std::string ToLocalString(const Anime::SeriesStatus status) {
	switch (status) {
		case Anime::SeriesStatus::RELEASING: return Strings::ToUtf8String(QCoreApplication::tr("Currently airing"));
		case Anime::SeriesStatus::FINISHED: return Strings::ToUtf8String(QCoreApplication::tr("Finished airing"));
		case Anime::SeriesStatus::NOT_YET_RELEASED: return Strings::ToUtf8String(QCoreApplication::tr("Not yet aired"));
		case Anime::SeriesStatus::CANCELLED: return Strings::ToUtf8String(QCoreApplication::tr("Cancelled"));
		case Anime::SeriesStatus::HIATUS: return Strings::ToUtf8String(QCoreApplication::tr("On hiatus"));
		default:
		case Anime::SeriesStatus::UNKNOWN: return Strings::ToUtf8String(QCoreApplication::tr("Unknown"));
	}
}

std::string ToLocalString(const Anime::Services service) {
	switch (service) {
		case Anime::Services::ANILIST: return Strings::ToUtf8String(QCoreApplication::tr("AniList"));
		default:
		case Anime::Services::NONE:    return Strings::ToUtf8String(QCoreApplication::tr("None"));
	}
}

std::string ToLocalString(const Anime::TitleLanguage language) {
	switch (language) {
		case Anime::TitleLanguage::NATIVE:  return Strings::ToUtf8String(QCoreApplication::tr("Native"));
		case Anime::TitleLanguage::ENGLISH: return Strings::ToUtf8String(QCoreApplication::tr("English"));
		default:
		case Anime::TitleLanguage::ROMAJI:  return Strings::ToUtf8String(QCoreApplication::tr("Romaji"));
	}
}

} // namespace Translate
