package tests;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import objects.SoccerMatch;

public class recalcTest extends TestClass {

	float prevHomeBank = -1;
	float prevDrawBank = -1;
	float prevAwayBank = -1;

	@Override
	public void runTest() {

		final int daysInPast = 360;
		final int recalcDays = 14;

		final ArrayList<SoccerMatch> matches = getMatches();

		final LocalDateTime startDate = matches.get(0).getGameDate();
		LocalDateTime endDate = startDate.plusYears(1);

		CalculateLookback(leagueId, startDate, daysInPast);
		LocalDateTime recalcDate = startDate.plusDays(recalcDays);

		float bank = startingBank;
		final float betLevel = this.bettingLevel / 100f;
		float betAmount = bank * betLevel;

		int betHomeCount = 0;
		int betDrawCount = 0;
		int betAwayCount = 0;

		int winHome = 0;
		int winDraw = 0;
		int winAway = 0;


		for (final SoccerMatch soccerMatch : matches) {
			if (soccerMatch.getGameDate().isAfter(endDate)) {
				System.out.println("End date reached " + endDate.format(DateTimeFormatter.ISO_DATE) + " with bank: " + bank +
						" Betted on: " + betHomeCount + "," + betDrawCount + "," + betAwayCount +
						" winPercent " + (betHomeCount>0?winHome/Float.valueOf(betHomeCount):0) + "," +
						(betDrawCount>0?winDraw/Float.valueOf(betDrawCount):0) + "," +
						(betAwayCount>0?winAway/Float.valueOf(betAwayCount):0));
				bank = startingBank;
				endDate = soccerMatch.getGameDate().plusYears(1);

				betHomeCount = 0;
				betDrawCount = 0;
				betAwayCount = 0;

				winHome = 0;
				winDraw = 0;
				winAway = 0;
			}
			if (recalcDate.isBefore(soccerMatch.getGameDate())) {
				final int prevBestLookbackHome = this.bestHomeLookback;
				final int prevBestLookbackDraw = this.bestDrawLookback;
				final int prevBestLookbackAway = this.bestAwayLookback;

				final int prevBestMarginHome = this.bestHomeMargin;
				final int prevBestMarginDraw = this.bestDrawMargin;
				final int prevBestMarginAway = this.bestAwayMargin;

				CalculateLookback(leagueId, soccerMatch.getGameDate(), daysInPast);

				recalcDate = soccerMatch.getGameDate().plusDays(recalcDays);
			}

			final List<SoccerMatch> homeMatches = matches.stream().filter(p -> p.getGameDate().isBefore(soccerMatch.getGameDate()) && p.getHomeTeam().getTeamId() == soccerMatch.getHomeTeam().getTeamId()).limit(bestHomeLookback).collect(Collectors.toList());
			final List<SoccerMatch> awayMatches = matches.stream().filter(p -> p.getGameDate().isBefore(soccerMatch.getGameDate()) && p.getAwayTeam().getTeamId() == soccerMatch.getAwayTeam().getTeamId()).limit(bestAwayLookback).collect(Collectors.toList());

			final long homeWins = homeMatches.stream().filter(p -> p.getHomeScore() > p.getAwayScore()).count();
			final long homeLosses = homeMatches.stream().filter(p -> p.getHomeScore() < p.getAwayScore()).count(); // borde det vara <=??
			final long homeDraws = homeMatches.stream().filter(p -> p.getHomeScore() == p.getAwayScore()).count();

			final long awayWins = awayMatches.stream().filter(p -> p.getHomeScore() < p.getAwayScore()).count();
			final long awayLosses = awayMatches.stream().filter(p -> p.getHomeScore() > p.getAwayScore()).count();
			final long awayDraws = awayMatches.stream().filter(p -> p.getHomeScore() == p.getAwayScore()).count();

			final float hemmaPercent = (homeWins + awayLosses) / Float.valueOf(homeMatches.size() + awayMatches.size()) * 100f;
			final float bortaPercent = (awayWins + homeLosses) / Float.valueOf(homeMatches.size() + awayMatches.size()) * 100f;
			final float likaPercent = (homeDraws + awayDraws) / Float.valueOf(homeMatches.size() + awayMatches.size()) * 100f;

			final float homeOdds = 100 / hemmaPercent;
			final float drawOdds = 100 / likaPercent;
			final float awayOdds = 100 / bortaPercent;

			betAmount = bank * betLevel;

			if (this.bestHomeMargin > 0 && homeOdds * (1 + (this.bestHomeMargin / 100f)) <= soccerMatch.getOdds1()) {
				bank -= betAmount;
				betHomeCount++;
				if (soccerMatch.getHomeScore() > soccerMatch.getAwayScore()) {
					winHome++;
					bank += betAmount * soccerMatch.getOdds1();
				}
			}
			if (this.bestDrawMargin > 0 && drawOdds * (1 + (this.bestDrawMargin / 100f)) <= soccerMatch.getOddsX()) {
				bank -= betAmount;
				betDrawCount++;
				if (soccerMatch.getHomeScore() == soccerMatch.getAwayScore()) {
					winDraw++;
					bank += betAmount * soccerMatch.getOddsX();
				}
			}
			if (this.bestAwayMargin > 0 && awayOdds * (1 + (this.bestAwayMargin / 100f)) <= soccerMatch.getOdds2()) {
				bank -= betAmount;
				betAwayCount++;
				if (soccerMatch.getHomeScore() < soccerMatch.getAwayScore()) {
					winAway++;
					bank += betAmount * soccerMatch.getOdds2();
				}
			}
		}

		System.out.println("End of test reached with bank: " + bank +
				" Betted on: " + betHomeCount + "," + betDrawCount + "," + betAwayCount +
				" winPercent " + (betHomeCount>0?winHome/Float.valueOf(betHomeCount):0) + "," +
				(betDrawCount>0?winDraw/Float.valueOf(betDrawCount):0) + "," +
				(betAwayCount>0?winAway/Float.valueOf(betAwayCount):0));

		System.out.println("Ending Margins " + this.bestHomeMargin + ", " + this.bestDrawMargin + ", " + this.bestAwayMargin + System.lineSeparator() + "Best Lookback " + this.bestHomeLookback + ", " + this.bestDrawLookback  + ", " + this.bestAwayLookback);
	}


	private ArrayList<SoccerMatch> getMatches() {
		final ArrayList<SoccerMatch> result = new ArrayList<>();

		final String sql = "SELECT res.*, "
				+ "hTeam.name as homeTeamName, aTeam.name as awayTeamName "
				+ "FROM SoccerResults as res "
				+ "Join Team as hTeam ON res.homeTeam = hTeam.id "
				+ "Join Team as aTeam ON res.awayTeam = aTeam.id "
				+ "WHERE "
				+ "res.leagueId = ? "
				+ "ORDER BY gameDate ASC";

		try {
			final PreparedStatement stmt = getConnection().prepareStatement(sql);
			stmt.setInt(1, leagueId);

			result.addAll(super.getMatches(stmt));
		} catch (final SQLException e) {
			e.printStackTrace();
		}

		return result;
	}
}
