package facade;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Scanner;

import domain.Player;

public class YahtzeeGame {

    private int playerCount;
    private ArrayList<Player> players = new ArrayList<>();
    private String savedGamemode;

    public void setPlayercount(int playerCount) {
        this.playerCount = playerCount;

    }

    public int getPlayercount(){
        return this.playerCount;

    }

    public void setPlayerNames(String... names) {
        for (int i = 0; i < this.playerCount; i++) {

            this.players.add(new Player(names[i], this.savedGamemode));

        }

    }

    public String getPlayerName(int player) {
        return players.get(player).getPlayername();
    }

    public void setGamemode(String gamemode) {
        this.savedGamemode = gamemode;

    }

    public void rollDices(int player) {

        players.get(player).rollDices();

    }

    public ArrayList<Integer> getAllDiceNumbers(int player) {

        return players.get(player).getAllDiceNumbers();

    }

    public ArrayList<Integer> getFreeDiceNumbers(int player) {

        return players.get(player).getFreeDiceNumbers();

    }

    public ArrayList<Integer> getLockedInDiceNumbers(int player) {

        return players.get(player).getLockedInDiceNumbers();

    }

    public int getLockedInDiceAmount(int player) {

        return players.get(player).getLockedInDiceAmount();
    }

    public void lockInDices(int player, String... dices) {

        if (dices[0].equalsIgnoreCase("none"))
            return;
        players.get(player).lockInDices(dices);

    }

    public boolean autoLockInDices(int player) {

        return players.get(player).autoLockInDices();

    }

    public boolean allDicesLockedIn(int player) {

        return players.get(player).getLockedInDiceAmount() == 5;

    }

    public int getLeftRolls(int player) {

        return players.get(player).getLeftRolls();

    }

    public boolean noMoreRolls(int player) {

        return 0 == getLeftRolls(player);

    }

    public void evaluateAllOptions(int player) {

        players.get(player).evaluateAllOptions();

    }

    public ArrayList<String> getAllOptions(int player) {

        return players.get(player).getAllOptions();

    }

    public void selectOption(int player, String selectedOption) {

        players.get(player).selectOption(selectedOption);
        players.get(player).resetOptions();
        players.get(player).getNewHand();
        players.get(player).updateBonus();
        players.get(player).updateUpperBoxScore();
        players.get(player).updateLowerBoxScore();
        players.get(player).updateTotalScore();

    }

    public String optionsPrinted(int player) {

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < getAllOptions(player).size(); i++) {

            sb.append(getAllOptions(player).get(i) + "\n");

        }

        return sb.toString();

    }

    public boolean onlyOneOption(int player) {

        return players.get(player).onlyOneOption();

    }

    public String selectedOptionsPrinted(int player) {

        return players.get(player).selectedOptionsPrinted();
    }

    public boolean gameOver(int player) {

        return players.get(player).gameOver();

    }

    public boolean gameOverAll() {
        int counter = 0;

        for (int i = 0; i < playerCount; i++) {
            if (players.get(i).gameOver())
                counter++;
        }

        return counter == playerCount;
    }

    public int returnTotalPoints(int player) {

        if (players.get(player).gameOver())
            return players.get(player).returnTotalPoints();
        else
            return 0;
    }

    private String[][] refreshHighscoreList() throws FileNotFoundException {

        String highscores[][] = new String[10][3];
        String mem[] = new String[3];
        String source;
        
        if(savedGamemode.equalsIgnoreCase("Special8"))
            source = "src/csv/highscoresSpecial8.csv";
        else
            source = "src/csv/highscores.csv";
            
        Scanner sc = new Scanner(new File(source));


        for (int i = 0; i < 10; i++) {

            if (sc.hasNextLine()) {

                mem = sc.nextLine().split(" ");
                highscores[i][0] = mem[0];
                highscores[i][1] = mem[1];
                highscores[i][2] = mem[2];

            } else {
                highscores[i][0] = "___";
                highscores[i][1] = "___";
                highscores[i][2] = "0";
            }

        }

        sc.close();
        return highscores;
    }

    public void setScoreToHighscores(int player, String highscores[][]) throws IOException {

        String highscoreMem1 = "";
        String highscoreMem2 = "";

        try {
            if (returnTotalPoints(player) < Integer.parseInt(highscores[9][2])) {

                return;

            }
        } catch (Exception e) {
        }

        try {

            if (returnTotalPoints(player) >= Integer.parseInt(highscores[0][2])) {

                for (int i = 2; i >= 0; i--) {
                    highscoreMem1 = highscores[0][i];
                    if (i == 2)
                        highscores[0][i] = "" + returnTotalPoints(player);
                    else if (i == 1)
                        highscores[0][i] = "" + players.get(player).getPlayername();
                    else if (i == 0)
                        highscores[0][i] = "" + LocalDate.now();
                    highscoreMem2 = highscores[1][i];
                    highscores[1][i] = highscoreMem1;
                    highscoreMem1 = highscores[2][i];
                    highscores[2][i] = highscoreMem2;
                    highscoreMem2 = highscores[3][i];
                    highscores[3][i] = highscoreMem1;
                    highscoreMem1 = highscores[4][i];
                    highscores[4][i] = highscoreMem2;
                    highscoreMem2 = highscores[5][i];
                    highscores[5][i] = highscoreMem1;
                    highscoreMem1 = highscores[6][i];
                    highscores[6][i] = highscoreMem2;
                    highscoreMem2 = highscores[7][i];
                    highscores[7][i] = highscoreMem1;
                    highscoreMem1 = highscores[8][i];
                    highscores[8][i] = highscoreMem2;
                    highscores[9][i] = highscoreMem1;
                }

            } else if (returnTotalPoints(player) >= Integer.parseInt(highscores[1][2])) {

                for (int i = 2; i >= 0; i--) {
                    highscoreMem2 = highscores[1][i];
                    if (i == 2)
                        highscores[1][i] = "" + returnTotalPoints(player);
                    else if (i == 1)
                        highscores[1][i] = "" + players.get(player).getPlayername();
                    else if (i == 0)
                        highscores[1][i] = "" + LocalDate.now();
                    highscoreMem1 = highscores[2][i];
                    highscores[2][i] = highscoreMem2;
                    highscoreMem2 = highscores[3][i];
                    highscores[3][i] = highscoreMem1;
                    highscoreMem1 = highscores[4][i];
                    highscores[4][i] = highscoreMem2;
                    highscoreMem2 = highscores[5][i];
                    highscores[5][i] = highscoreMem1;
                    highscoreMem1 = highscores[6][i];
                    highscores[6][i] = highscoreMem2;
                    highscoreMem2 = highscores[7][i];
                    highscores[7][i] = highscoreMem1;
                    highscoreMem1 = highscores[8][i];
                    highscores[8][i] = highscoreMem2;
                    highscores[9][i] = highscoreMem1;
                }
            } else if (returnTotalPoints(player) >= Integer.parseInt(highscores[2][2])) {

                for (int i = 2; i >= 0; i--) {
                    highscoreMem1 = highscores[2][i];
                    if (i == 2)
                        highscores[2][i] = "" + returnTotalPoints(player);
                    else if (i == 1)
                        highscores[2][i] = "" + players.get(player).getPlayername();
                    else if (i == 0)
                        highscores[2][i] = "" + LocalDate.now();
                    highscoreMem2 = highscores[3][i];
                    highscores[3][i] = highscoreMem1;
                    highscoreMem1 = highscores[4][i];
                    highscores[4][i] = highscoreMem2;
                    highscoreMem2 = highscores[5][i];
                    highscores[5][i] = highscoreMem1;
                    highscoreMem1 = highscores[6][i];
                    highscores[6][i] = highscoreMem2;
                    highscoreMem2 = highscores[7][i];
                    highscores[7][i] = highscoreMem1;
                    highscoreMem1 = highscores[8][i];
                    highscores[8][i] = highscoreMem2;
                    highscores[9][i] = highscoreMem1;
                }
            } else if (returnTotalPoints(player) >= Integer.parseInt(highscores[3][2])) {

                for (int i = 2; i >= 0; i--) {
                    highscoreMem2 = highscores[3][i];
                    if (i == 2)
                        highscores[3][i] = "" + returnTotalPoints(player);
                    else if (i == 1)
                        highscores[3][i] = "" + players.get(player).getPlayername();
                    else if (i == 0)
                        highscores[3][i] = "" + LocalDate.now();
                    highscoreMem1 = highscores[4][i];
                    highscores[4][i] = highscoreMem2;
                    highscoreMem2 = highscores[5][i];
                    highscores[5][i] = highscoreMem1;
                    highscoreMem1 = highscores[6][i];
                    highscores[6][i] = highscoreMem2;
                    highscoreMem2 = highscores[7][i];
                    highscores[7][i] = highscoreMem1;
                    highscoreMem1 = highscores[8][i];
                    highscores[8][i] = highscoreMem2;
                    highscores[9][i] = highscoreMem1;
                }
            } else if (returnTotalPoints(player) >= Integer.parseInt(highscores[4][2])) {

                for (int i = 2; i >= 0; i--) {
                    highscoreMem1 = highscores[4][i];
                    if (i == 2)
                        highscores[4][i] = "" + returnTotalPoints(player);
                    else if (i == 1)
                        highscores[4][i] = "" + players.get(player).getPlayername();
                    else if (i == 0)
                        highscores[4][i] = "" + LocalDate.now();
                    highscoreMem2 = highscores[5][i];
                    highscores[5][i] = highscoreMem1;
                    highscoreMem1 = highscores[6][i];
                    highscores[6][i] = highscoreMem2;
                    highscoreMem2 = highscores[7][i];
                    highscores[7][i] = highscoreMem1;
                    highscoreMem1 = highscores[8][i];
                    highscores[8][i] = highscoreMem2;
                    highscores[9][i] = highscoreMem1;
                }
            } else if (returnTotalPoints(player) >= Integer.parseInt(highscores[5][2])) {

                for (int i = 2; i >= 0; i--) {
                    highscoreMem2 = highscores[5][i];
                    if (i == 2)
                        highscores[5][i] = "" + returnTotalPoints(player);
                    else if (i == 1)
                        highscores[5][i] = "" + players.get(player).getPlayername();
                    else if (i == 0)
                        highscores[5][i] = "" + LocalDate.now();
                    highscoreMem1 = highscores[6][i];
                    highscores[6][i] = highscoreMem2;
                    highscoreMem2 = highscores[7][i];
                    highscores[7][i] = highscoreMem1;
                    highscoreMem1 = highscores[8][i];
                    highscores[8][i] = highscoreMem2;
                    highscores[9][i] = highscoreMem1;
                }
            } else if (returnTotalPoints(player) >= Integer.parseInt(highscores[6][2])) {

                for (int i = 2; i >= 0; i--) {
                    highscoreMem1 = highscores[6][i];
                    if (i == 2)
                        highscores[6][i] = "" + returnTotalPoints(player);
                    else if (i == 1)
                        highscores[6][i] = "" + players.get(player).getPlayername();
                    else if (i == 0)
                        highscores[6][i] = "" + LocalDate.now();
                    highscoreMem2 = highscores[7][i];
                    highscores[7][i] = highscoreMem1;
                    highscoreMem1 = highscores[8][i];
                    highscores[8][i] = highscoreMem2;
                    highscores[9][i] = highscoreMem1;
                }
            } else if (returnTotalPoints(player) >= Integer.parseInt(highscores[7][2])) {

                for (int i = 2; i >= 0; i--) {
                    highscoreMem2 = highscores[7][i];
                    if (i == 2)
                        highscores[7][i] = "" + returnTotalPoints(player);
                    else if (i == 1)
                        highscores[7][i] = "" + players.get(player).getPlayername();
                    else if (i == 0)
                        highscores[7][i] = "" + LocalDate.now();
                    highscoreMem1 = highscores[8][i];
                    highscores[8][i] = highscoreMem2;
                    highscores[9][i] = highscoreMem1;
                }
            } else if (returnTotalPoints(player) >= Integer.parseInt(highscores[8][2])) {

                for (int i = 2; i >= 0; i--) {
                    highscoreMem1 = highscores[8][i];
                    if (i == 2)
                        highscores[8][i] = "" + returnTotalPoints(player);
                    else if (i == 1)
                        highscores[8][i] = "" + players.get(player).getPlayername();
                    else if (i == 0)
                        highscores[8][i] = "" + LocalDate.now();
                    highscores[9][i] = highscoreMem1;
                }
            } else if (returnTotalPoints(player) >= Integer.parseInt(highscores[9][2])) {

                for (int i = 2; i >= 0; i--) {
                    if (i == 2)
                        highscores[9][i] = "" + returnTotalPoints(player);
                    else if (i == 1)
                        highscores[9][i] = "" + players.get(player).getPlayername();
                    else if (i == 0)
                        highscores[9][i] = "" + LocalDate.now();
                }
            }

            String source;
        
            if(savedGamemode.equalsIgnoreCase("Special8"))
                source = "src/csv/highscoresSpecial8.csv";
            else
                source = "src/csv/highscores.csv";
                
            PrintWriter out = new PrintWriter(new FileWriter(source));

            
            for (int i = 0; i < 10; i++) {

                out.print(highscores[i][0] + " " + highscores[i][1] + " "
                        + highscores[i][2]);

                out.println();
            }

            out.close();
        } catch (Exception e) {
        }

    }

    public void saveAllPlayersHighscores() throws IOException {

        for (int i = 0; i < playerCount; i++) {
            setScoreToHighscores(i, refreshHighscoreList());
        }

    }

    public String showHighscores(String gamemode) throws FileNotFoundException {

        StringBuilder sb = new StringBuilder();
        this.savedGamemode = gamemode;

        for (int i = 0; i < 10; i++) {

            sb.append((i + 1) + ": " + refreshHighscoreList()[i][0]);
            sb.append(": " + refreshHighscoreList()[i][1]);
            sb.append(": " + refreshHighscoreList()[i][2] + "\n");

        }

        return sb.toString();

    }

    public void deleteHighscores() throws IOException {

        String source;
        
        if(savedGamemode.equalsIgnoreCase("Special8"))
            source = "src/csv/highscoresSpecial8.csv";
        else
            source = "src/csv/highscores.csv";
            
        PrintWriter out = new PrintWriter(new FileWriter(source));
        
        out.print("");

        out.close();

    }

    public String getWinnerMessage() {

        int winnerScore = returnTotalPoints(0);
        String winnerName = getPlayerName(0);

        for (int i = 0; i < this.playerCount; i++) {
            if (winnerScore < returnTotalPoints(i)) {
                winnerScore = returnTotalPoints(i);
                winnerName = getPlayerName(i);
            }
        }

        return winnerName + " is the winner, with a total score of: " + winnerScore;

    }
}
