package controllers;

import java.math.RoundingMode;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;

import data.GuiMysql;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.MapValueFactory;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.Callback;
import javafx.util.converter.FloatStringConverter;
import objects.League;
import objects.SoccerMatch;
import objects.SoccerMatchAnalysis;
import objects.bets.Bet;
import objects.bets.Bet.Status;

@SuppressWarnings("rawtypes")
public class AnalysisTestController implements Initializable {

    public static final String STATS_LEAGUE_NAME = "statsLeagueName";
    public static final String STATS_HOME_WIN = "statHomeWin";
    public static final String STATS_HOME_LOSS = "statsHomeLoss";
    public static final String STATS_AWAY_WIN = "statsAwayWin";
    public static final String STATS_AWAY_LOSS = "statsAwayLoss";
    public static final String STATS_HOME_PERCENT = "statsHomePercent";
    public static final String STATS_AWAY_PERCENT = "statsAwayPercent";
    public static final String STATS_TOTAL_PERCENT = "statsTotalPercent";
    private static final float MIN_COVER_ODDS = 1.25f;
    private static final float MAX_COVER_ODDS = 2.25f;
    private static final DecimalFormat FLOAT_FORMATTER = new DecimalFormat("0.00");
    TableColumn<SoccerMatch, String> homeTeamNameColumn = new TableColumn<>("Home Team");
    TableColumn<SoccerMatch, String> awayTeamNameColumn = new TableColumn<>("Away Team");
    TableColumn<SoccerMatch, Float> odds1Column = new TableColumn<>("1");
    TableColumn<SoccerMatch, Float> oddsXColumn = new TableColumn<>("X");
    TableColumn<SoccerMatch, Float> odds2Column = new TableColumn<>("2");
    TableColumn<SoccerMatch, String> leagueNameColumn = new TableColumn<>("Country");

    TableColumn<SoccerMatch, String> countryNameColumn = new TableColumn<>("League");

    TableColumn<SoccerMatch, String> analyzeValueColumn = new TableColumn<>("Value");
    TableColumn<SoccerMatch, Float> matchBetAmountColumn = new TableColumn<>("Bet Amount");
    TableColumn<SoccerMatch, Void> addBetColumn = new TableColumn<>("Add Bet");
    TableColumn<Bet, String> matchupColumn = new TableColumn<>("Matchup");
    TableColumn<Bet, Float> oddsColumn = new TableColumn<>("Odds");
    TableColumn<Bet, Float> betAmountColumn = new TableColumn<>("BetAmount");
    TableColumn<Bet, Bet.Status> statusColumn = new TableColumn<>("Status");
    TableColumn<Bet, Integer> homeScoreColumn = new TableColumn<>("Home Score");
    TableColumn<Bet, Integer> awayScoreColumn = new TableColumn<>("Away Score");
    TableColumn<Bet, Integer> betCoveredNumberColumn = new TableColumn<>("Bet Covered Number");

    @FXML
    TableView<Bet> activeBetsTable;
    @FXML
    TableView<SoccerMatch> gameViewTable;
    @FXML
    TableView<Map<String, Object>> leagueBetStatsTable;
    @FXML
    TableColumn<Map, String> statsLeagueNameColumn = new TableColumn<>("League");
    @FXML
    TableColumn<Map, Integer> statsHomeWinColumn = new TableColumn<>("Home Win");
    @FXML
    TableColumn<Map, Integer> statsHomeLossColumn = new TableColumn<>("Home Loss");
    @FXML
    TableColumn<Map, Float> statsHomePercentColumn = new TableColumn<>("Home Percent");
    @FXML
    TableColumn<Map, Integer> statsAwayWinColumn = new TableColumn<>("Away Win");
    @FXML
    TableColumn<Map, Integer> statsAwayLossColumn = new TableColumn<>("Away Loss");
    @FXML
    TableColumn<Map, Float> statsAwayPercentColumn = new TableColumn<>("Away Percent");
    @FXML
    TableColumn<Map, Float> statsTotalPercentColumn = new TableColumn<>("Total Percent");
    @FXML
    Button checkBetsButton;
    @FXML
    Button getMatchesButton;
    @FXML
    DatePicker date;
    @FXML
    TextField bankTextField;
    @FXML
    TextField bettingPercentTextField;

    private float currentBetAmount = 10f;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        FLOAT_FORMATTER.setRoundingMode(RoundingMode.UP);
        DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.ENGLISH);
        dfs.setDecimalSeparator('.');
        dfs.setGroupingSeparator(',');
        FLOAT_FORMATTER.setDecimalFormatSymbols(dfs);

        bettingPercentTextField.textProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue.length() > 0) {
                checkValidBetAmount();
            }
        });

        date.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (oldValue != newValue) {
                gameViewTable.getItems().clear();
            }
        });

        gameViewTable.getSelectionModel().selectedItemProperty().addListener((obj, oldValue, newValue) -> {
            if (oldValue != null) {
                oldValue.setBetAmount(currentBetAmount);
            }

            if (newValue != null) {
                newValue.setBetAmount(getNewBetValue(newValue));
            }

            gameViewTable.refresh();
            activeBetsTable.refresh();
        });

        homeTeamNameColumn.setCellValueFactory(new PropertyValueFactory<>("homeTeamName"));
        awayTeamNameColumn.setCellValueFactory(new PropertyValueFactory<>("awayTeamName"));
        odds1Column.setCellValueFactory(new PropertyValueFactory<>("odds1"));
        oddsXColumn.setCellValueFactory(new PropertyValueFactory<>("oddsX"));
        odds2Column.setCellValueFactory(new PropertyValueFactory<>("odds2"));

        leagueNameColumn.setCellValueFactory(new PropertyValueFactory<>("leagueName"));
        countryNameColumn.setCellValueFactory(new PropertyValueFactory<>("countryName"));
        analyzeValueColumn.setCellValueFactory(new PropertyValueFactory<>("analysisValue"));

        matchBetAmountColumn.setCellValueFactory(new PropertyValueFactory<>("betAmount"));

        Callback<TableColumn<SoccerMatch, Void>, TableCell<SoccerMatch, Void>> cellFactory =
                new Callback<TableColumn<SoccerMatch, Void>, TableCell<SoccerMatch, Void>>() {
            @Override
            public TableCell<SoccerMatch, Void> call(final TableColumn<SoccerMatch, Void> param) {
                return new TableCell<SoccerMatch, Void>() {

                    private final Button btn = new Button("Submit");

                    {
                        btn.setOnAction((ActionEvent event) -> {
                            SoccerMatch data = getTableView().getItems().get(getIndex());

                            addToBets(data);
                        });
                    }

                    @Override
                    public void updateItem(Void item, boolean empty) {
                        super.updateItem(item, empty);
                        if (empty) {
                            setGraphic(null);
                        } else {
                            setGraphic(btn);
                        }
                    }

                };
            }
        };

        addBetColumn.setCellFactory(cellFactory);

        gameViewTable.getColumns().addAll(homeTeamNameColumn, awayTeamNameColumn, odds1Column, oddsXColumn, odds2Column,
                countryNameColumn, leagueNameColumn, analyzeValueColumn, matchBetAmountColumn, addBetColumn);
        gameViewTable.setEditable(true);

        odds1Column.setCellFactory(TextFieldTableCell.<SoccerMatch, Float>forTableColumn(new FloatStringConverter()));
        odds1Column.setOnEditCommit(
                e -> e.getTableView().getItems().get(e.getTablePosition().getRow()).setOdds1(e.getNewValue()));

        oddsXColumn.setCellFactory(TextFieldTableCell.<SoccerMatch, Float>forTableColumn(new FloatStringConverter()));
        oddsXColumn.setOnEditCommit(
                e -> e.getTableView().getItems().get(e.getTablePosition().getRow()).setOddsX(e.getNewValue()));
        odds2Column.setCellFactory(TextFieldTableCell.<SoccerMatch, Float>forTableColumn(new FloatStringConverter()));
        odds2Column.setOnEditCommit(
                e -> e.getTableView().getItems().get(e.getTablePosition().getRow()).setOdds2(e.getNewValue()));

        matchupColumn.setCellValueFactory(new PropertyValueFactory<>("matchup"));
        matchupColumn.setMinWidth(100d);

        oddsColumn.setCellValueFactory(new PropertyValueFactory<>("betOdds"));
        betAmountColumn.setCellValueFactory(new PropertyValueFactory<>("betAmount"));
        homeScoreColumn.setCellValueFactory(new PropertyValueFactory<>("homeScore"));
        awayScoreColumn.setCellValueFactory(new PropertyValueFactory<>("awayScore"));
        betCoveredNumberColumn.setCellValueFactory(new PropertyValueFactory<>("betCoveredNumber"));

        statusColumn.setCellValueFactory(new PropertyValueFactory<>("status"));

        activeBetsTable.getColumns().addAll(matchupColumn, oddsColumn, betAmountColumn, statusColumn, homeScoreColumn,
                awayScoreColumn, betCoveredNumberColumn);

        getActiveBets();

        statsLeagueNameColumn.setCellValueFactory(new MapValueFactory<>(STATS_LEAGUE_NAME));
        statsHomeWinColumn.setCellValueFactory(new MapValueFactory<>(STATS_HOME_WIN));
        statsHomeLossColumn.setCellValueFactory(new MapValueFactory<>(STATS_HOME_LOSS));
        statsAwayWinColumn.setCellValueFactory(new MapValueFactory<>(STATS_AWAY_WIN));
        statsAwayLossColumn.setCellValueFactory(new MapValueFactory<>(STATS_AWAY_LOSS));

        statsHomePercentColumn.setCellValueFactory(new MapValueFactory<>(STATS_HOME_PERCENT));
        statsAwayPercentColumn.setCellValueFactory(new MapValueFactory<>(STATS_AWAY_PERCENT));
        statsTotalPercentColumn.setCellValueFactory(new MapValueFactory<>(STATS_TOTAL_PERCENT));

        initializeStatsPanel();
    }

    private void addMatchesToTable(List<SoccerMatch> matches) {
        ObservableList<SoccerMatch> currentMatches = FXCollections.<SoccerMatch>observableArrayList();

        for (SoccerMatch soccerMatch : matches) {
            if (currentBetAmount > 0) {
                soccerMatch.setBetAmount(currentBetAmount);
            }
            currentMatches.add(soccerMatch);
        }
        gameViewTable.getItems().addAll(currentMatches);
    }

    private void setAnalyzisValue(SoccerMatch soccerMatch) {
        int analyzeValue = getAnalyzeValue(soccerMatch);
        soccerMatch.setAnalysisValue(analyzeValue);
    }

    private void addToBets(SoccerMatch data) {
        if (data.getAnalysisValueInt() > 0f) {
            setNewBet(data, true);
        } else if (data.getAnalysisValueInt() < 0f) {
            setNewBet(data, false);
        } else {
            System.out.println("Can't add bets with analysts value " + data.getAnalysisValueInt());
        }
    }

    private void checkBet(Bet b) {
        if (b.getHomeScore() >= 0 && b.getAwayScore() >= 0
                && (b.getBet().equals("1") && b.getHomeScore() > b.getAwayScore())
                || (b.getBet().equals("2") && b.getHomeScore() < b.getAwayScore())) { // Win
            b.setStatus(Bet.Status.DONE);
            float win = (b.getBetOdds() * b.getBetAmount());
            updateBank(win);

        } else if (b.getHomeScore() >= 0 && b.getAwayScore() >= 0) { // Loss
            b.setStatus(Bet.Status.LOST);
        }

        GuiMysql.getInstance().updateBetStatus(b.getId(), b.getStatus());
        updateStatsPanel(b);
    }

    @FXML
    private void checkBetsAction() {
        activeBetsTable.getItems().stream().filter(p -> p.getStatus() == Bet.Status.OPEN).forEach(this::checkBet);
        activeBetsTable.refresh();
        updateBetAmount();
    }

    private void checkValidBetAmount() {
        try {
            float bankValue = Float.parseFloat(bankTextField.getText().replace(",", "."));
            float betPercent = Float.parseFloat(bettingPercentTextField.getText().replace(",", "."));

            final float betAmount = Float.parseFloat(FLOAT_FORMATTER.format(bankValue * (betPercent / 100f)));
            currentBetAmount = betAmount;
            gameViewTable.getItems().forEach(i -> i.setBetAmount(betAmount));
            gameViewTable.refresh();

        } catch (NumberFormatException e) {
// Ignore
        }
    }

    private void getActiveBets() {
        List<Bet> analysisBets = GuiMysql.getInstance().getAnalysisBets();

        analysisBets.forEach(b -> b.setBetCoveredNumber(getCoveredBets(b)));

        activeBetsTable.getItems().addAll(analysisBets);
        activeBetsTable.refresh();
    }

    private int getCoveredBets(Bet b) {
        int returnValue = 0;
        if (b.getCoveredBetId() > 0) {
            returnValue += getCoveredBets(GuiMysql.getInstance().getAnalysisBet(b.getCoveredBetId()));
            returnValue++;
        }

        return returnValue;
    }

    private Integer getAnalyzeValue(SoccerMatch soccerMatch) {
        int result = 0;

        SoccerMatchAnalysis analysis = new SoccerMatchAnalysis(soccerMatch);
        League leagueInfo = GuiMysql.getInstance().getLeagueInfo(soccerMatch.getHomeTeam().getTeamLeagueId());
        if (leagueInfo != null) {
            int homeWinsCount = analysis.winLossRatio(leagueInfo.getWinLossRatio(), true);
            int awayWinsCount = analysis.winLossRatio(leagueInfo.getWinLossRatio(), false);

            int homeWinLossRatioCount = analysis.winLossRatioHomeAndAway(true,
                    leagueInfo.getWinLossRatioHomeAndAway());
            int awayWinLossRatioCount = analysis.winLossRatioHomeAndAway(false,
                    leagueInfo.getWinLossRatioHomeAndAway());

            int homeScoringTotal = analysis.scoringTotal(leagueInfo.getScoringTotal(), true);
            int awayScoringTotal = analysis.scoringTotal(leagueInfo.getScoringTotal(), false);

            int scoringDiffLastGames = analysis.getScoringDiffLastGames(leagueInfo.getScoringDiffLastGame());
            int winsCountDiff = homeWinsCount - awayWinsCount;
            int winLossRatioDiff = homeWinLossRatioCount - awayWinLossRatioCount;
            int scoringTotalDiff = homeScoringTotal - awayScoringTotal;

            if ((scoringDiffLastGames < 0 && winsCountDiff < 0 && winLossRatioDiff < 0 && scoringTotalDiff < 0) ||
                    scoringDiffLastGames > 0 && winsCountDiff > 0 && winLossRatioDiff > 0 && scoringTotalDiff > 0) {
                result = (scoringDiffLastGames + winsCountDiff + winLossRatioDiff + scoringTotalDiff) / 4;
            }
        }
        return result;
    }

    private float getBank() {
        float bank = 0;
        if (!bankTextField.getText().isEmpty()) {
            bank = Float.parseFloat(bankTextField.getText().replace(",", "."));
        }

        return bank;
    }

    @FXML
    private void getMatchesAction() {
        List<SoccerMatch> matches = GuiMysql.getInstance().getMatches(1, date.getValue().toString(), "ASC", true);
        matches.forEach(this::setAnalyzisValue);
        matches = matches.stream().filter(m -> !m.getAnalysisValue().equals("No Bet")).toList();
        addMatchesToTable(matches);
    }

    private Float getNewBetValue(SoccerMatch newValue) {
        float odds = 0f;
        float currentDebt = 0f;
        float result = currentBetAmount;

        boolean activeBet = isActiveBet(newValue);
        Optional<Bet> oBet =
                activeBetsTable.getItems().stream().filter(p -> p.getStatus() == Bet.Status.LOST).findFirst();
        if (activeBet && oBet.isPresent()) {
            Bet bet = oBet.get();

            Bet tempBet = bet;
            int betCoverNumber = 0;
            while (tempBet.getCoveredBetId() > 0) {
                tempBet = GuiMysql.getInstance().getAnalysisBet(tempBet.getCoveredBetId());
                currentDebt += tempBet.getBetAmount();
                betCoverNumber++;
            }
            bet.setBetCoveredNumber(betCoverNumber);

            if (betCoverNumber > 3 && newValue.getAnalysisValueInt() < 10 && newValue.getAnalysisValueInt() > -10) {
                return Float.parseFloat(FLOAT_FORMATTER.format(result));
            }

            currentDebt += bet.getBetAmount();
            newValue.setPreviousBet(bet);
            if (newValue.getAnalysisValueInt() > 0f) {
                odds = newValue.getOdds1();
            } else if (newValue.getAnalysisValueInt() < 0f) {
                odds = newValue.getOdds2();
            }

            if (currentDebt > 0f && odds > 0f) {
                result = currentDebt / (odds - 1f);
            } else if (newValue.getBetAmount() != null) {
                result = newValue.getBetAmount();
            }
        }

        return Float.parseFloat(FLOAT_FORMATTER.format(result));
    }

    private boolean isActiveBet(SoccerMatch newValue) {
        boolean isHomeBet = newValue.getAnalysisValueInt() > 0 && newValue.getOdds1() > MIN_COVER_ODDS
                && newValue.getOdds1() < MAX_COVER_ODDS;
        boolean isAwayBet = newValue.getAnalysisValueInt() < 0 && newValue.getOdds2() > MIN_COVER_ODDS
                && newValue.getOdds2() < MAX_COVER_ODDS;

        return isHomeBet || isAwayBet;
    }

    private void initializeStatsPanel() {
        List<Bet> bets = GuiMysql.getInstance().getAnalysisBetStatistics();
        for (Bet bet : bets) {
            updateStatsPanel(bet);
        }
    }

    @FXML
    private void removeDoneBetsAction() {
        List<Bet> doneBets = activeBetsTable.getItems().stream()
                .filter(p -> p.getStatus() == Status.DONE || p.getStatus() == Status.COVERED)
                .toList();

        for (Bet bet : doneBets) {
            if (bet.getStatus().equals(Status.COVERED)) {
                GuiMysql.getInstance().updateBetStatus(bet.getId(), Status.DONE);
            }
            activeBetsTable.getItems().remove(bet);
        }

        activeBetsTable.getItems().sort((b1, b2) -> Float.compare(b2.getBetAmount(), b1.getBetAmount()));

        activeBetsTable.refresh();

    }

    private void setNewBet(SoccerMatch data, boolean isHomeBet) {
        float odds = isHomeBet ? data.getOdds1() : data.getOdds2();
        Bet bet = new Bet(-1, data, isHomeBet ? "1" : "2", data.getBetAmount(), odds);

        boolean shouldCover = data.getPreviousBet() != null && odds > MIN_COVER_ODDS && odds < MAX_COVER_ODDS;
        if (shouldCover) {
            int betId = GuiMysql.getInstance().addAnalysisBet(bet);
            data.getPreviousBet().setStatus(Status.COVERED);
            bet.setCoveredBetId(data.getPreviousBet().getId());
            bet.setBetCoveredNumber(bet.getBetCoveredNumber() + 1);
            GuiMysql.getInstance().setBetCovered(betId, bet.getCoveredBetId());

            try {
                activeBetsTable.getItems().set(activeBetsTable.getItems().indexOf(data.getPreviousBet()),
                        data.getPreviousBet());
            } catch (IndexOutOfBoundsException e) {
                System.out.printf("Failed to update bet between %s - %s to covered %n",
                        data.getPreviousBet().getHomeTeamName(), data.getPreviousBet().getAwayTeamName());
            } finally {
                GuiMysql.getInstance().updateBetStatus(data.getPreviousBet().getId(), Status.COVERED);
            }
        } else {
            GuiMysql.getInstance().addAnalysisBet(bet);
        }
        activeBetsTable.getItems().add(bet);
        updateBank(-bet.getBetAmount());
    }

    private void updateBank(float value) {
        float bank;
        if (!bankTextField.getText().isEmpty()) {
            bank = Float.parseFloat(bankTextField.getText().replace(",", "."));
            bank += value;
            bankTextField.setText(String.valueOf(bank));
        }
    }

    private void updateBetAmount() {
        if (!bettingPercentTextField.getText().isEmpty()) {
            float betLevel = Float.parseFloat(bettingPercentTextField.getText().replace(",", "."));
            currentBetAmount = Float.parseFloat(FLOAT_FORMATTER.format(
                    getBank() * (betLevel / 100f)).replace(",", "."));
        }
    }

    private void updateStatsPanel(Bet b) {
        String leagueName = b.getMatch().getLeagueName();

        Optional<Map<String, Object>> leagueStatsRow = leagueBetStatsTable.getItems().stream()
                .filter(p -> p.get(STATS_LEAGUE_NAME) != null && leagueName.equals(p.get(STATS_LEAGUE_NAME)))
                .findFirst();

        if (leagueStatsRow.isEmpty()) {
            Map<String, Object> newItem = createNewStatRow(b, leagueName);
            ObservableList<Map<String, Object>> items = leagueBetStatsTable.getItems();

            items.add(newItem);
        } else {
            Map<String, Object> map = leagueStatsRow.get();
            boolean isHomeWin = isHomeWin(b);
            boolean isAwayWin = isAwayWin(b);
            if (b.isBetOnHomeTeam() && isHomeWin) {
                map.put(STATS_HOME_WIN, (int) map.get(STATS_HOME_WIN) + 1);
            } else if (b.isBetOnHomeTeam() && !isHomeWin) {
                map.put(STATS_HOME_LOSS, (int) map.get(STATS_HOME_LOSS) + 1);
            } else if (b.isBetOnAwayTeam() && isAwayWin) {
                map.put(STATS_AWAY_WIN, (int) map.get(STATS_AWAY_WIN) + 1);
            } else if (b.isBetOnAwayTeam() && !isAwayWin) {
                map.put(STATS_AWAY_LOSS, (int) map.get(STATS_AWAY_LOSS) + 1);
            }

            setStatWinPercents(map);

            leagueBetStatsTable.getItems().set(leagueBetStatsTable.getItems().indexOf(map), map);
        }
        leagueBetStatsTable.refresh();
    }

    private static void setStatWinPercents(Map<String, Object> map) {
        int statsHomeWin = (int) map.get(STATS_HOME_WIN);
        int statsHomeLoss = (int) map.get(STATS_HOME_LOSS);
        if (statsHomeWin > 0 || statsHomeLoss > 0) {
            map.put(STATS_HOME_PERCENT, (statsHomeWin / (float) (statsHomeWin + statsHomeLoss)) * 100);
        }
        int statsAwayWin = (int) map.get(STATS_AWAY_WIN);
        int statsAwayLoss = (int) map.get(STATS_AWAY_LOSS);
        if (statsAwayWin > 0 || statsAwayLoss > 0) {
            map.put(STATS_AWAY_PERCENT, (statsAwayWin / (float) (statsAwayWin + statsAwayLoss)) * 100);
        }
        if (statsHomeWin + statsHomeLoss + statsAwayWin + statsAwayLoss > 0) {
            map.put(STATS_TOTAL_PERCENT,
                    ((statsHomeWin + statsAwayWin)
                            / (float) (statsHomeWin + statsHomeLoss + statsAwayWin + statsAwayLoss)) * 100);
        }
    }

    private boolean isAwayWin(Bet b) {
        return b.getHomeScore() < b.getAwayScore();
    }

    private Map<String, Object> createNewStatRow(Bet b, String leagueName) {
        boolean homeWin = isHomeWin(b);
        Map<String, Object> newItem = new HashMap<>();
        newItem.put(STATS_LEAGUE_NAME, leagueName);
        newItem.put(STATS_HOME_WIN, homeWin ? 1 : 0);
        newItem.put(STATS_HOME_LOSS, !homeWin ? 1 : 0);
        int statsHomeWin = (int) newItem.get(STATS_HOME_WIN);
        int statsHomeLoss = (int) newItem.get(STATS_HOME_LOSS);
        if (statsHomeWin > 0 || statsHomeLoss > 0) {
            newItem.put(STATS_HOME_PERCENT, (statsHomeWin / (float) (statsHomeWin + statsHomeLoss)) * 100);
        }
        newItem.put(STATS_AWAY_WIN, b.isBetOnAwayTeam() && b.getHomeScore() < b.getAwayScore() ? 1 : 0);
        newItem.put(STATS_AWAY_LOSS,
                b.isBetOnAwayTeam() && (b.getHomeScore() > b.getAwayScore() || b.getHomeScore() == b.getAwayScore())
                        ? 1
                        : 0);

        int statsAwayWin = (int) newItem.get(STATS_AWAY_WIN);
        int statsAwayLoss = (int) newItem.get(STATS_AWAY_LOSS);
        if (statsAwayWin > 0 || statsAwayLoss > 0) {
            newItem.put(STATS_AWAY_PERCENT, (statsAwayWin / (float) (statsAwayWin + statsAwayLoss)) * 100);
        }
        if (statsHomeWin + statsHomeLoss + statsAwayWin + statsAwayLoss > 0) {
            newItem.put(STATS_TOTAL_PERCENT,
                    ((statsHomeWin + statsAwayWin)
                            / (float) (statsHomeWin + statsHomeLoss + statsAwayWin + statsAwayLoss)) * 100);
        }
        return newItem;
    }

    private boolean isHomeWin(Bet b) {
        return b.getHomeScore() > b.getAwayScore();
    }

}
