package data;

import objects.SoccerMatch;
import objects.TeamResults;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MatchStatSql extends GuiMysql {

    private final Logger LOG = Logger.getLogger(this.getClass().getName());

    public List<SoccerMatch> getAllMatchesForLeague(int leagueId) {
        return getAllMatchesForLeague(leagueId, "DATE(NOW())");
    }

    public List<SoccerMatch> getAllMatchesForLeague(int leagueId, String stopDate) {
        List<SoccerMatch> result = new ArrayList<>();

        String sql = "SELECT * FROM SoccerResults sr " +
                "JOIN Team ht ON ht.id = sr.homeTeamId " +
                "JOIN Team awt ON awt.id = sr.awayTeamId " +
                "JOIN League l ON l.id = sr.leagueId " +
                "WHERE sr.leagueId = ? AND DATE(gameDate) < "+stopDate+" ORDER BY gameDate ASC";
        try (PreparedStatement stat = getConnection().prepareStatement(sql)) {
            stat.setInt(1, leagueId);

            ResultSet rs = stat.executeQuery();
            while (rs.next()) {
                result.add(new SoccerMatch(rs));
            }

        } catch (SQLException e) {
            System.out.println(String.format("Something wrong with sql %n%s", sql));
            e.printStackTrace();
            LOG.log(Level.ALL, String.format("Something wrong with sql %n%s", sql), e);
        }
        return result;
    }

    public int goalsScoredLastXGames(int teamId, boolean homeTeam, int limit) {
        return goalsScoredLastXGames(teamId, homeTeam, "DATE(NOW())", limit);
    }

    public int goalsScoredLastXGames(int teamId, boolean homeTeam, String gameDate, int limit) {
        int result = 0;
        String sql = "SELECT sum(hs." + (homeTeam ? "home" : "away") + "Score) res FROM " +
                "(SELECT " + (homeTeam ? "home" : "away") + "Score FROM SoccerResults sr " +
                "WHERE sr." + (homeTeam ? "home" : "away") + "TeamId = ? AND " +
                "DATE(gameDate) < ? " +
                "ORDER BY gameDate DESC " +
                "LIMIT ?) hs;";

        try (PreparedStatement stat = getConnection().prepareStatement(sql)) {
            stat.setInt(1, teamId);
            stat.setString(2, gameDate);
            stat.setInt(3, limit);
            ResultSet rs = stat.executeQuery();
            while (rs.next()) {
                result = rs.getInt("res");
            }
        } catch (SQLException e) {
            LOG.log(Level.ALL, String.format("Something wrong with sql %n%s", sql), e);
        }
        return result;
    }

    public int goalsScoreLastXGamesHomeANDAway(int teamId, int limit) {
        return goalsScoreLastXGamesHomeANDAway(teamId, "DATE(NOW())", limit);
    }

    public int goalsScoreLastXGamesHomeANDAway(int teamId, String gameDate, int limit) {
        int result = 0;
        String sql = "SELECT sum(score) res FROM " +
                "(SELECT IF (sr.homeTeamId = ?, sr.homeScore, sr.awayScore) score " +
                "FROM SoccerResults sr " +
                "WHERE (sr.homeTeamId = ? OR " +
                "sr.awayTeamId = ?) AND " +
                "DATE(gameDate) < ? " +
                "ORDER BY gameDate DESC " +
                "LIMIT ?) hs;";
        try (PreparedStatement stat = getConnection().prepareStatement(sql)) {
            stat.setInt(1, teamId);
            stat.setInt(2, teamId);
            stat.setInt(3, teamId);
            stat.setString(4, gameDate);
            stat.setInt(5, limit);

            ResultSet rs = stat.executeQuery();

            while (rs.next()) {
                result = rs.getInt("res");
            }
        } catch (SQLException e) {
            LOG.log(Level.ALL, String.format("Something wrong with sql %n%s", sql), e);
        }
        return result;
    }

    public TeamResults formLastXGames(int teamId, int limit) {
        return formLastXGames(teamId, "DATE(NOW())", limit);
    }

    public TeamResults formLastXGames(int teamId, String gameDate, int limit) {
        TeamResults result = new TeamResults();

        String sql = "SELECT sum(win) as wins, sum(draw) as draws, sum(loss) as losses FROM " +
                "(SELECT CASE WHEN homeTeamId = ? AND " +
                "homeScore > awayScore THEN 1 ELSE 0 end win," +
                "CASE WHEN homeTeamId = ? AND homeScore = awayScore THEN 1 ELSE 0 end draw," +
                "CASE WHEN homeTeamId = ? AND homeScore < awayScore THEN 1 ELSE 0  end loss" +
                "FROM SoccerResults sr " +
                "WHERE sr.homeTeamId = ? AND " +
                "DATE(gameDate) < ? " +
                "ORDER BY gameDate DESC " +
                "LIMIT ?) h;";

        try (PreparedStatement stat = getConnection().prepareStatement(sql)) {
            stat.setInt(1,teamId);
            stat.setInt(2,teamId);
            stat.setInt(3,teamId);
            stat.setInt(4,teamId);

            stat.setString(5, gameDate);
            stat.setInt(6, limit);

            ResultSet rs = stat.executeQuery();
            while (rs.next()) {
                result.setWins(rs.getInt("wins"));
                result.setDraws(rs.getInt("draws"));
                result.setLosses(rs.getInt("losses"));
                result.setCount(limit);
            }
        } catch (SQLException e) {
            LOG.log(Level.ALL, String.format("Something wrong with sql %n%s", sql), e);
        }

        return result;
    }

    public TeamResults formLastXGamesHomeANDAway(int teamId, int limit) {
        return formLastXGamesHomeANDAway(teamId, "DATE(NOW())", limit);
    }

    public TeamResults formLastXGamesHomeANDAway(int teamId, String gameDate, int limit) {
        TeamResults result = new TeamResults();
        String sql = "SELECT sum(win) as wins, sum(draw) as draws, sum(loss) as losses FROM " +
                "(SELECT CASE WHEN homeTeamId = ? AND homeScore > awayScore THEN 1 " +
                    "WHEN awayTeamId = ? AND awayScore > homeScore THEN 1 " +
                    "ELSE 0 END win," +
                "CASE WHEN (homeTeamId = ? OR awayTeamId = ?) AND homeScore = awayScore THEN 1 " +
                    "ELSE 0 END draw," +
                "CASE WHEN homeTeamId = ? AND homeScore < awayScore THEN 1 " +
                    "WHEN awayTeamId = ? AND awayScore < homeScore THEN 1 " +
                    "ELSE 0 END loss" +
                "FROM SoccerResults sr " +
                "WHERE (sr.homeTeamId = ? OR sr.awayTeamId = ?) AND " +
                "DATE(gameDate) < ? " +
                "ORDER BY gameDate DESC " +
                "LIMIT ?) h;";

        try (PreparedStatement stat = getConnection().prepareStatement(sql)) {
            stat.setInt(1, teamId);
            stat.setInt(2, teamId);
            stat.setInt(3, teamId);
            stat.setInt(4, teamId);
            stat.setInt(5, teamId);
            stat.setInt(6, teamId);
            stat.setInt(7, teamId);
            stat.setInt(8, teamId);
            stat.setString(9, gameDate);
            stat.setInt(10, limit);

            ResultSet rs = stat.executeQuery();

            while (rs.next()) {
                result.setWins(rs.getInt("wins"));
                result.setDraws(rs.getInt("draws"));
                result.setLosses(rs.getInt("losses"));
            }

        } catch (SQLException e) {
            LOG.log(Level.ALL, String.format("Something wrong with sql %n%s", sql), e);
        }
        return result;
    }

    public int totalGoalResult(int teamId, boolean home, int limit) {
        return totalGoalResult(teamId, "DATE(NOW())", home, limit);
    }
    public int totalGoalResult(int teamId, String gameDate, boolean home, int limit) {
        int result = 0;

        String sql = "SELECT " + (home?"sum(homeScore - awayScore)":"sum(awayScore - homeScore)") + " res FROM " +
                "(SELECT homeScore, awayScore " +
                "FROM SoccerResults sr " +
                "WHERE sr."+ (home?"home":"away") + "TeamId = ? AND " +
                "DATE(gameDate) < ? " +
                "ORDER BY gameDate DESC " +
                "LIMIT ?) h;";

        try (PreparedStatement stat = getConnection().prepareStatement(sql)) {
            stat.setInt(1, teamId);
            stat.setString(2, gameDate);
            stat.setInt(3, limit);

            ResultSet rs = stat.executeQuery();
            while (rs.next()) {
                result = rs.getInt("res");
            }
        } catch (SQLException e) {
            LOG.log(Level.ALL, String.format("Something wrong with sql %n%s", sql), e);
        }
        return result;
    }


    public int totalGoalResultHomeANDAway(int teamId, int limit) {
        return totalGoalResultHomeANDAway(teamId, "DATE(NOW())", limit);
    }
    public int totalGoalResultHomeANDAway(int teamId, String gameDate, int limit) {
        int result = 0;

        String sql = "SELECT SUM(hScore + aScore) res FROM (" +
                "SELECT CASE " +
                "WHEN homeTeamId = ? THEN homeScore - awayScore ELSE 0 END hScore, " +
                "CASE WHEN awayTeamId = ? THEN awayScore - homeScore ELSE 0 END aScore " +
                "FROM SoccerResults sr " +
                "WHERE (sr.homeTeamId = ? OR awayTeamId = ?) AND " +
                "DATE(gameDate) < ? " +
                "ORDER BY gameDate DESC " +
                "LIMIT ?) h;";

        try (PreparedStatement stat = getConnection().prepareStatement(sql)) {
            stat.setInt(1, teamId);
            stat.setInt(2, teamId);
            stat.setInt(3, teamId);
            stat.setInt(4, teamId);
            stat.setString(5, gameDate);
            stat.setInt(6, limit);

            ResultSet rs = stat.executeQuery();
            while (rs.next()) {
                result = rs.getInt("res");
            }
        } catch (SQLException e) {
            LOG.log(Level.ALL, String.format("Something wrong with sql %n%s", sql), e);
        }
        return result;
    }
}

