package controllers.strategytest;


import components.FloatStatRow;
import components.MatchSummaryPanelRow;
import components.NumberStatRow;
import interfaces.strategytest.BettingStrategyInterface;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import objects.SoccerMatch;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>1X on home outsiders strategy</p>
 * <p>A betting strategy that has been successful in the past is the bet on the "double chance" 1X if an outsider plays against a favorite at home.
 * In this case, the "1X" bet brings respectable odds and very interesting profit opportunities.</p>
 *
 * <p>Home win or draw betting strategy</p>
 *
 * <p>You don't even have to choose and analyze games that contain absolute extremes and obvious class differences with this strategy.
 * So, you don't necessarily have to bet against Barcelona, Bayern or Juventus as an away team.
 * Here, we would probably move away from the value bets.
 * Even if we opt for teams that are not big outsiders, but are still outsiders according to the odds, we find highly interesting odds between 1.60 and 2.50.</p>
 *
 * <p>As with all bets, it is important to analyze in advance and not blindly going for any team.
 * You should of course take statistics into account, advance information about injuries and suspensions, as well as the current shape of the teams.
 * The home advantage of the outsider, for whom games in front of their own audience against a "bigger one" also represent a special motivation,
 * should not be underestimated as it brings another small advantage for the home team.
 * Especially when the respective favorite has recently shown itself shaky against "smaller ones",
 * you can definitely find value in such an outsider bet with double chances.</p>
 *
 * <p>If you also accept lower odds, you can of course also use this 1X strategy for games that have balanced odds.</p>
 */
public class OneXStrategy extends VBox implements BettingStrategyInterface {
    private final List<SoccerMatch> matches = new ArrayList<>();
    private NumberStatRow matchesPlayedStatRow;
    private NumberStatRow matchesWonStatRow;
    private NumberStatRow matchesLostStatRow;
    private FloatStatRow wonLossBank;
    private FloatStatRow betAmount;
    ScrollPane matchesSummaryScrollPane;

    public OneXStrategy() {
        super();
        buildSettingsGuiPanel();
        buildStatGuiPanel();
        buildMatchSummaryPanel();

        this.setStyle("-fx-background-color: orange");
    }

    public OneXStrategy(List<SoccerMatch> matches) {
        super();
        buildSettingsGuiPanel();
        buildStatGuiPanel();
        buildMatchSummaryPanel();

        setMatches(matches);
    }

    @Override
    public void buildSettingsGuiPanel() {
        betAmount = new FloatStatRow("Bet Amount", 10f);
        this.getChildren().add(betAmount);
    }

    @Override
    public void buildStatGuiPanel() {
        matchesPlayedStatRow = new NumberStatRow("Number of matches played", 0);
        matchesWonStatRow = new NumberStatRow("Number of matches won", 0);
        matchesLostStatRow = new NumberStatRow("Number of matches lost", 0);

        wonLossBank = new FloatStatRow("Amount won or lost", 0f);

        this.getChildren().add(matchesPlayedStatRow);
        this.getChildren().add(matchesWonStatRow);
        this.getChildren().add(matchesLostStatRow);
        this.getChildren().add(wonLossBank);
    }

    @Override
    public void buildMatchSummaryPanel() {
        matchesSummaryScrollPane = new ScrollPane();
        matchesSummaryScrollPane.setContent(new VBox());
        matchesSummaryScrollPane.setMaxHeight(200d);

        this.getChildren().add(matchesSummaryScrollPane);
    }

    /**
     * Sets the list of soccer matches to be used by this strategy.
     *
     * @param matches The list of soccer matches to be used.
     */
    public void setMatches(List<SoccerMatch> matches) {
        this.matches.clear();
        this.matches.addAll(matches);
    }

    /**
     * Runs the One X strategy test on the list of soccer matches.
     * For each match, it calculates the 1X odds and checks if they are between 1.60 and 2.50.
     * If the odds are in this range, it bets on the home team to win or draw.
     * It updates the match summary panel, the statistics, and the bank balance accordingly.
     */
    public void runTest() {
        for (SoccerMatch match : matches) {
            final float oneXOdds = calculate1XOdds(match);
            if ( shouldBetOn(match).equals("1X")) {
                // bet on home win or draw
                ((VBox)matchesSummaryScrollPane.getContent()).getChildren().add(new MatchSummaryPanelRow(match, wonLossBank.getValue(), oneXOdds, betAmount.getValue()));
                matchesPlayedStatRow.increaseValue();
                if (match.getHomeScore() >= match.getAwayScore()) {
                    matchesWonStatRow.increaseValue();
                    wonLossBank.increaseValue((betAmount.getValue() * oneXOdds) - betAmount.getValue());
                } else {
                    matchesLostStatRow.increaseValue();
                    wonLossBank.decreaseValue(betAmount.getValue());
                }
            }
        }
    }

    @Override
    public String shouldBetOn(SoccerMatch match) {
        return calculate1XOdds(match) > 1.60 && calculate1XOdds(match) < 2.50?"1X":"";
    }

    @Override
    public List<SoccerMatch> sortMatchesOnBetPotential(List<SoccerMatch> matches) {
        // Not used in this strategy
        return Collections.emptyList();
    }
}
