package controllers;

import controllers.strategytest.FibonacciStrategy;
import data.DTO.FibonacciDTO.FibonacciDTO;
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.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import objects.MatchViewDTO;
import objects.SoccerMatch;
import objects.visual.FibonacciBets;

import java.net.URL;
import java.time.LocalDateTime;
import java.util.List;
import java.util.ResourceBundle;

public class CommingMatches implements Initializable {

    @FXML
    public TableView<MatchViewDTO> todaysMatchesTableView;
    @FXML
    public TableView<MatchViewDTO> tomorrowsMatchesTableView;
    public VBox betsPanel;
    public VBox actionsPanel;
    public VBox betsContentPanel;
    Label errorLabel = new Label();


    TableColumn<MatchViewDTO, String> homeTeamColumn = new TableColumn<>("Home Team");
    TableColumn<MatchViewDTO, String> awayTeamColumn = new TableColumn<>("Away Team");
    TableColumn<MatchViewDTO, String> leagueColumn = new TableColumn<>("Country");
    TableColumn<MatchViewDTO, String> countryColumn = new TableColumn<>("League");
    TableColumn<MatchViewDTO, Float> odds1Column = new TableColumn<>("Odds 1");
    TableColumn<MatchViewDTO, Float> oddsXColumn = new TableColumn<>("Odds X");
    TableColumn<MatchViewDTO, Float> odds2Column = new TableColumn<>("Odds 2");

    TableColumn<MatchViewDTO, Float> calculatedOdds1Column = new TableColumn<>("Calculated Odds 1");
    TableColumn<MatchViewDTO, Float> calculatedOddsXColumn = new TableColumn<>("Calculated Odds X");
    TableColumn<MatchViewDTO, Float> calculatedOdds2Column = new TableColumn<>("Calculated Odds 2");

    TableColumn<MatchViewDTO, Float> calculatedOddsOneXColumn = new TableColumn<>("Calculated Odds 1X");
    TableColumn<MatchViewDTO, Float> calculatedOddsX2Column = new TableColumn<>("Calculated Odds X2");
    TableColumn<MatchViewDTO, Float> calculatedOdds12Column = new TableColumn<>("Calculated Odds 12");

    TableColumn<MatchViewDTO, Float> calculatedHomeWinColumn = new TableColumn<>("Calculated Home Win");
    TableColumn<MatchViewDTO, Float> calculatedDrawColumn = new TableColumn<>("Calculated Draw");
    TableColumn<MatchViewDTO, Float> calculatedAwayWinColumn = new TableColumn<>("Calculated Away Win");

    TableColumn<MatchViewDTO, String> tomorrowHomeTeamColumn = new TableColumn<>("Home Team");
    TableColumn<MatchViewDTO, String> tomorrowAwayTeamColumn = new TableColumn<>("Away Team");
    TableColumn<MatchViewDTO, String> tomorrowLeagueColumn = new TableColumn<>("Country");
    TableColumn<MatchViewDTO, String> tomorrowCountryColumn = new TableColumn<>("League");
    TableColumn<MatchViewDTO, Float> tomorrowOdds1Column = new TableColumn<>("Odds 1");
    TableColumn<MatchViewDTO, Float> tomorrowOddsXColumn = new TableColumn<>("Odds X");
    TableColumn<MatchViewDTO, Float> tomorrowOdds2Column = new TableColumn<>("Odds 2");

    TableColumn<MatchViewDTO, Float> tomorrowCalculatedOdds1Column = new TableColumn<>("Calculated Odds 1");
    TableColumn<MatchViewDTO, Float> tomorrowCalculatedOddsXColumn = new TableColumn<>("Calculated Odds X");
    TableColumn<MatchViewDTO, Float> tomorrowCalculatedOdds2Column = new TableColumn<>("Calculated Odds 2");

    TableColumn<MatchViewDTO, Float> tomorrowCalculatedOddsOneXColumn = new TableColumn<>("Calculated Odds 1X");
    TableColumn<MatchViewDTO, Float> tomorrowCalculatedOddsX2Column = new TableColumn<>("Calculated Odds X2");
    TableColumn<MatchViewDTO, Float> tomorrowCalculatedOdds12Column = new TableColumn<>("Calculated Odds 12");

    TableColumn<MatchViewDTO, Float> tomorrowCalculatedHomeWinColumn = new TableColumn<>("Calculated Home Win");
    TableColumn<MatchViewDTO, Float> tomorrowCalculatedDrawColumn = new TableColumn<>("Calculated Draw");
    TableColumn<MatchViewDTO, Float> tomorrowCalculatedAwayWinColumn = new TableColumn<>("Calculated Away Win");
    private MatchViewDTO selectedMatch;

    FibonacciBets fibonacciBets = new FibonacciBets();
    private FibonacciDTO currentActiveFibonacciSequence;

    Button addBetButton = new Button("Add Bet");


    @Override
    public void initialize(URL location, ResourceBundle resources) {
        prepareColumns();
        buildTodaysMatchesTableView();
        buildTomorrowsMatchesTableView();

        buildBetsPanel();

        AnchorPane.setBottomAnchor(todaysMatchesTableView, 0.0);
        AnchorPane.setTopAnchor(todaysMatchesTableView, 0.0);
        AnchorPane.setLeftAnchor(todaysMatchesTableView, 0.0);
        AnchorPane.setRightAnchor(todaysMatchesTableView, 0.0);

        AnchorPane.setBottomAnchor(tomorrowsMatchesTableView, 0.0);
        AnchorPane.setTopAnchor(tomorrowsMatchesTableView, 0.0);
        AnchorPane.setLeftAnchor(tomorrowsMatchesTableView, 0.0);
        AnchorPane.setRightAnchor(tomorrowsMatchesTableView, 0.0);

        todaysMatchesTableView.getColumns().addAll(homeTeamColumn, awayTeamColumn, leagueColumn, countryColumn,
                odds1Column, oddsXColumn, odds2Column, calculatedOdds1Column, calculatedOddsXColumn,
                calculatedOdds2Column, calculatedOddsOneXColumn, calculatedOddsX2Column, calculatedOdds12Column,
                calculatedHomeWinColumn, calculatedDrawColumn, calculatedAwayWinColumn);

        tomorrowsMatchesTableView.getColumns().addAll(tomorrowHomeTeamColumn, tomorrowAwayTeamColumn, tomorrowLeagueColumn, tomorrowCountryColumn,
                tomorrowOdds1Column, tomorrowOddsXColumn, tomorrowOdds2Column, tomorrowCalculatedOdds1Column, tomorrowCalculatedOddsXColumn,
                tomorrowCalculatedOdds2Column, tomorrowCalculatedOddsOneXColumn, tomorrowCalculatedOddsX2Column, tomorrowCalculatedOdds12Column,
                tomorrowCalculatedHomeWinColumn, tomorrowCalculatedDrawColumn, tomorrowCalculatedAwayWinColumn);


        todaysMatchesTableView.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> matchesTableSelectionChange(newValue));
        tomorrowsMatchesTableView.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> matchesTableSelectionChange(newValue));

        addBetButton.setOnAction(this::addBetAction);
        errorLabel.setStyle("fx-text-fill: red");
    }

    private void addBetAction(ActionEvent event) {
        if (selectedMatch == null) {
            errorLabel.setText("No match selected");
        } else {
            if (fibonacciBets.validBetSettings()) {
                errorLabel.setText("");
                fibonacciBets.addBet(fibonacciBets.getSequenceNumber(), fibonacciBets.getOddsFieldFloat(), selectedMatch);

                fibonacciBets = new FibonacciBets();

                updateBetsContentPanel();
            } else {
                errorLabel.setText("Bet Settings are not valid");
            }
        }
    }

    private void matchesTableSelectionChange(MatchViewDTO newValue) {
        // TODO implement
        System.out.println("Selected item: " + newValue);
        selectedMatch = newValue;

        fibonacciBets.setCurrentMatch(newValue);
    }

    private void prepareColumns() {
        homeTeamColumn.setCellValueFactory(new PropertyValueFactory<>("homeTeamName"));
        awayTeamColumn.setCellValueFactory(new PropertyValueFactory<>("awayTeamName"));
        leagueColumn.setCellValueFactory(new PropertyValueFactory<>("leagueName"));
        countryColumn.setCellValueFactory(new PropertyValueFactory<>("countryName"));
        odds1Column.setCellValueFactory(new PropertyValueFactory<>("odds1"));
        oddsXColumn.setCellValueFactory(new PropertyValueFactory<>("oddsX"));
        odds2Column.setCellValueFactory(new PropertyValueFactory<>("odds2"));
        calculatedOdds1Column.setCellValueFactory(new PropertyValueFactory<>("calculatedOdds1"));
        calculatedOddsXColumn.setCellValueFactory(new PropertyValueFactory<>("calculatedOddsX"));
        calculatedOdds2Column.setCellValueFactory(new PropertyValueFactory<>("calculatedOdds2"));
        calculatedOddsOneXColumn.setCellValueFactory(new PropertyValueFactory<>("calculatedOddsOneX"));
        calculatedOddsX2Column.setCellValueFactory(new PropertyValueFactory<>("calculatedOddsX2"));
        calculatedOdds12Column.setCellValueFactory(new PropertyValueFactory<>("calculatedOdds12"));
        calculatedHomeWinColumn.setCellValueFactory(new PropertyValueFactory<>("homeWinPercent"));
        calculatedDrawColumn.setCellValueFactory(new PropertyValueFactory<>("drawPercent"));
        calculatedAwayWinColumn.setCellValueFactory(new PropertyValueFactory<>("awayWinPercent"));

        tomorrowHomeTeamColumn.setCellValueFactory(new PropertyValueFactory<>("homeTeamName"));
        tomorrowAwayTeamColumn.setCellValueFactory(new PropertyValueFactory<>("awayTeamName"));
        tomorrowLeagueColumn.setCellValueFactory(new PropertyValueFactory<>("leagueName"));
        tomorrowCountryColumn.setCellValueFactory(new PropertyValueFactory<>("countryName"));
        tomorrowOdds1Column.setCellValueFactory(new PropertyValueFactory<>("odds1"));
        tomorrowOddsXColumn.setCellValueFactory(new PropertyValueFactory<>("oddsX"));
        tomorrowOdds2Column.setCellValueFactory(new PropertyValueFactory<>("odds2"));
        tomorrowCalculatedOdds1Column.setCellValueFactory(new PropertyValueFactory<>("calculatedOdds1"));
        tomorrowCalculatedOddsXColumn.setCellValueFactory(new PropertyValueFactory<>("calculatedOddsX"));
        tomorrowCalculatedOdds2Column.setCellValueFactory(new PropertyValueFactory<>("calculatedOdds2"));
        tomorrowCalculatedOddsOneXColumn.setCellValueFactory(new PropertyValueFactory<>("calculatedOddsOneX"));
        tomorrowCalculatedOddsX2Column.setCellValueFactory(new PropertyValueFactory<>("calculatedOddsX2"));
        tomorrowCalculatedOdds12Column.setCellValueFactory(new PropertyValueFactory<>("calculatedOdds12"));
        tomorrowCalculatedHomeWinColumn.setCellValueFactory(new PropertyValueFactory<>("homeWinPercent"));
        tomorrowCalculatedDrawColumn.setCellValueFactory(new PropertyValueFactory<>("drawPercent"));
        tomorrowCalculatedAwayWinColumn.setCellValueFactory(new PropertyValueFactory<>("awayWinPercent"));
    }

    private void buildTodaysMatchesTableView() {
        List<SoccerMatch> todaysMatches = getTodaysMatches();

        ObservableList<MatchViewDTO> todaysMatchesViewDTO = FXCollections.<MatchViewDTO>observableArrayList();

        for (SoccerMatch match : todaysMatches) {
            match.setLeagueName(match.getHomeTeam().getTeamLeague());
            match.setCountryName(match.getHomeTeam().getCountryName());

            MatchViewDTO matchViewDTO = new MatchViewDTO(match);
            todaysMatchesViewDTO.add(matchViewDTO);
        }

        todaysMatchesTableView.getItems().addAll(todaysMatchesViewDTO);
    }

    private List<SoccerMatch> getTodaysMatches() {
        return GuiMysql.getInstance().getPrioMatchesOfDate(LocalDateTime.now().toLocalDate().toString());
    }

    private void buildTomorrowsMatchesTableView() {
        List<SoccerMatch> tomorrowsMatches = getTomorrowsMatches();
        ObservableList<MatchViewDTO> tomorrowsMatchesViewDTO = FXCollections.<MatchViewDTO>observableArrayList();

        for (SoccerMatch match : tomorrowsMatches) {
            match.setLeagueName(match.getHomeTeam().getTeamLeague());
            match.setCountryName(match.getHomeTeam().getCountryName());

            MatchViewDTO matchViewDTO = new MatchViewDTO(match);
            tomorrowsMatchesViewDTO.add(matchViewDTO);
        }

        tomorrowsMatchesTableView.getItems().addAll(tomorrowsMatchesViewDTO);
    }

    private List<SoccerMatch> getTomorrowsMatches() {
        return GuiMysql.getInstance().getPrioMatchesOfDate(LocalDateTime.now().plusDays(1).toLocalDate().toString());
    }

    private void buildBetsPanel() {
        //if (selectedMatch != null) {
        actionsPanel.getChildren().clear();
        actionsPanel.getChildren().add(getBettingStrategyComboBox());

        //}
    }

    private ComboBox<String> getBettingStrategyComboBox() {
        ComboBox<String> bettingStrategyComboBox = new ComboBox<>();
        bettingStrategyComboBox.getItems().add("");
        bettingStrategyComboBox.getItems().add(FibonacciStrategy.NAME);

        bettingStrategyComboBox.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> betStrategyChangeListener(newValue));
        return bettingStrategyComboBox;
    }

    private void betStrategyChangeListener(String newValue) {

        betsPanel.getChildren().clear();
        // TODO implement
        if (FibonacciStrategy.NAME.equals(newValue)) {
            betsPanel.getChildren().add(fibonacciBets.getNewBetGui());
        }

        updateBetsContentPanel();

        betsPanel.getChildren().add(addBetButton);
        betsPanel.getChildren().add(errorLabel);
    }

    private void updateBetsContentPanel() {
        betsContentPanel.getChildren().clear();
        betsContentPanel.getChildren().add(fibonacciBets);
    }
}
