package tests;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

import data.GuiMysql;
import objects.SoccerMatch;
import objects.SoccerMatchCalcBestValue;
import objects.TeamResults;

public class LastResultsTest extends TestClass {

	float bank;
	float betLevel;
	float betMarginDecimal;

	@Override public void runTest() {

		bank = startingBank;
		betLevel = bettingLevel / 100;
		betMarginDecimal = 1 + (betMargin / 100);
		final List<SoccerMatch> matches = getMatches(leagueId);

		final int totalMatchCount = matches.size();

		String season = matches.get(0).getSeason();
		int betOnGameCount = 0;
		final LocalDateTime currentDate = matches.get(0).getGameDate();
		LocalDate localDate = currentDate.toLocalDate();
		float betAmount = bank * betLevel;
		for (final SoccerMatch soccerMatch : matches) {
			if (soccerMatch.getHomeScore() < 0 || soccerMatch.getAwayScore() < 0) {
				continue;
			}
			if (!season.equals(soccerMatch.getSeason())) { // new season reset bank, report result
				System.out.println("season " + season + " ended with " + bank);
				bank = startingBank;
				season = soccerMatch.getSeason();
			}
			final TeamResults homeTeamResults = GuiMysql.getInstance().getTeamResults(soccerMatch.getHomeTeam().getTeamId(), lookBack, true);
			final TeamResults awayTeamResults = GuiMysql.getInstance().getTeamResults(soccerMatch.getAwayTeam().getTeamId(), lookBack, false);

			final float homeWinPercent = (homeTeamResults.getWins() + awayTeamResults.getLosses())
					/ Float.valueOf(homeTeamResults.getCount() + awayTeamResults.getCount()) * 100;
			final float drawPercent = (homeTeamResults.getDraws() + awayTeamResults.getDraws())
					/ Float.valueOf(homeTeamResults.getCount() + awayTeamResults.getCount()) * 100;
			final float awayWinPercent = (homeTeamResults.getLosses() + awayTeamResults.getWins())
					/ Float.valueOf(homeTeamResults.getCount() + awayTeamResults.getCount()) * 100;

			final float homeOdds = 100 / homeWinPercent;
			final float drawOdds = 100 / drawPercent;
			final float awayOdds = 100 / awayWinPercent;

			if (localDate.isBefore(soccerMatch.getGameDate().toLocalDate())) {
				betAmount = bank * betLevel;
				localDate = soccerMatch.getGameDate().toLocalDate();
			}
			if (homeOdds * betMarginDecimal <= soccerMatch.getOdds1()) {
				betOnGameCount++;
				// System.out.print(soccerMatch.getGameDate() + " Bet " + betAmount + " on home
				// team " + soccerMatch.getHomeTeam().getTeamName() + " - " +
				// soccerMatch.getAwayTeam().getTeamName() + " at odds " +
				// soccerMatch.getOdds1()
				// + " Result " + soccerMatch.getHomeScore() + " - " +
				// soccerMatch.getAwayScore());
				bank = bank - betAmount;
				if (soccerMatch.getHomeScore() > soccerMatch.getAwayScore()) {
					bank = bank + betAmount * soccerMatch.getOdds1();
					// System.out.println(" Win, new Bank " + bank);
				} else {
					// System.out.println(" Loss new Bank " + bank);
				}
			}
			if (awayOdds * betMarginDecimal <= soccerMatch.getOdds2()) {
				betOnGameCount++;
				// System.out.print(soccerMatch.getGameDate() + " Bet " + betAmount + " on away
				// team " + soccerMatch.getHomeTeam().getTeamName() + " - " +
				// soccerMatch.getAwayTeam().getTeamName() + " at odds " +
				// soccerMatch.getOdds2()
				// + " Result " + soccerMatch.getHomeScore() + " - " +
				// soccerMatch.getAwayScore());
				bank = bank - betAmount;
				if (soccerMatch.getAwayScore() > soccerMatch.getHomeScore()) {
					bank = bank + betAmount * soccerMatch.getOdds2();
					// System.out.println(" Win, new Bank " + bank);
				} else {
					// System.out.println(" Loss new Bank " + bank);
				}
			}

		}

		System.out.println("season " + season + " ended with " + bank);
		System.out.println("Match count " + matches.size() + " leagueId " + leagueId + " countryId " + countryId + " bet on " + betOnGameCount + "("
				+ betOnGameCount / (float) totalMatchCount + ")");
	}

	public void calcBestResults(int sportId, Integer countryId, Integer leagueId) {
		final float startingBank = 1000f;
		float bank = startingBank;
		final float betLevel = 1 / 100f;

		int bestBetMargin = 1;
		int bestLookBack = 1;
		float bestBankResult = 1000f;

		/* final List<SoccerMatch> matches = GuiMysql.getInstance().getMatches(sportId, countryId, leagueId,
				LocalDate.now().atStartOfDay().format(DateTimeFormatter.ISO_DATE), "ASC", false, false);
*/
		final List<SoccerMatchCalcBestValue> matches = GuiMysql.getInstance().getMatchesForCalcBestValues(countryId, leagueId,
				LocalDate.now().atStartOfDay().format(DateTimeFormatter.ISO_DATE));


		final LocalDateTime currentDate = matches.get(0).getGameDate();
		LocalDate localDate = currentDate.toLocalDate();
		float betAmount = bank * betLevel;

		for (int lookBack = 1; lookBack < 25; lookBack++) {
			for (int betMargin = 1; betMargin < 35; betMargin++) {
				int betOnGameCount = 0;
				int wins = 0;
				final float betMarginDecimal = 1 + (betMargin / (float) 100);
				bank = startingBank;
				for (final SoccerMatchCalcBestValue soccerMatch : matches) {
					if (soccerMatch.getHomeScore() < 0 || soccerMatch.getAwayScore() < 0) {
						continue;
					}

/*					final TeamResults homeTeamResults = GuiMysql.getInstance().getTeamResultsTest(soccerMatch.getHomeTeam().getTeamId(), lookBack,
							true, soccerMatch.getGameDate().format(DateTimeFormatter.ISO_DATE));
					final TeamResults awayTeamResults = GuiMysql.getInstance().getTeamResultsTest(soccerMatch.getAwayTeam().getTeamId(), lookBack,
							false, soccerMatch.getGameDate().format(DateTimeFormatter.ISO_DATE));
*/
					final float homeWinPercent = (soccerMatch.getHomeWins(lookBack) + soccerMatch.getAwayLosses(lookBack))
							/ Float.valueOf(lookBack * 2) * 100;
					/*final float awayWinPercent = (homeTeamResults.getLosses() + awayTeamResults.getWins())
							/ Float.valueOf(homeTeamResults.getCount() + awayTeamResults.getCount()) * 100;
					 */
					final float awayWinPercent = (soccerMatch.getHomeLosses(lookBack) + soccerMatch.getAwayWins(lookBack))
							/ Float.valueOf(lookBack * 2) * 100;

					if (homeWinPercent < 0 ||awayWinPercent < 0) {
						continue;
					}

					final float homeOdds = 100 / homeWinPercent;
					final float awayOdds = 100 / awayWinPercent;

					if (localDate.isBefore(soccerMatch.getGameDate().toLocalDate())) {
						betAmount = bank * betLevel;
						localDate = soccerMatch.getGameDate().toLocalDate();
					}
					if (homeOdds * betMarginDecimal <= soccerMatch.getOdds1()) {
						betOnGameCount++;
						bank = bank - betAmount;
						if (soccerMatch.getHomeScore() > soccerMatch.getAwayScore()) {
							wins++;
							bank = bank + betAmount * soccerMatch.getOdds1();
						}
					}
					if (awayOdds * betMarginDecimal <= soccerMatch.getOdds2()) {
						betOnGameCount++;
						bank = bank - betAmount;
						if (soccerMatch.getAwayScore() > soccerMatch.getHomeScore()) {
							wins++;
							bank = bank + betAmount * soccerMatch.getOdds2();
						}
					}
				}

				if (bestBankResult < bank) {
					System.out.println("New best bank " + bank + " with lookback " + lookBack + " and betMargin " + betMargin + " Bet on "
							+ betOnGameCount + " of " + matches.size() + "(" + betOnGameCount / (float) matches.size() + ") wins " + wins + "("
							+ wins / Float.valueOf(betOnGameCount) + ")" + " Win / game " + (bank - startingBank) / Float.valueOf(wins) + " kr");
					bestBetMargin = betMargin;
					bestLookBack = lookBack;
					bestBankResult = bank;
				}
				/*else {
					System.out.println("NOT BEST bank " + bank + " with lookback " + lookBack + " and betMargin " + betMargin + " Bet on "
							+ betOnGameCount + " of " + matches.size() + "(" + betOnGameCount / (float) matches.size() + ") wins " + wins + "("
							+ wins / Float.valueOf(betOnGameCount) + ")" + " Win / game " + (bank - startingBank) / Float.valueOf(wins) + " kr");
				}*/
			}
		}
	}

	public List<SoccerMatch> getMatches(int leagueId) {
		return GuiMysql.getInstance().getMatches(sportId, countryId, leagueId, date, "ASC", false, false);
	}
}
