package pp.monopoly.game.server;

import java.util.LinkedList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
/**
 * A class for helping with player actions and managing thier turns
 */
public class PlayerHandler {
    private List<Player> players = new LinkedList<>();
    private Set<Player> readyPlayers = new HashSet<>();
    private ServerGameLogic logic;

    /**
     * Contructs a PlayerHandler
     * @param logic the {@link ServerGameLogic} this PlayerHandler is a part of
     */
    PlayerHandler(ServerGameLogic logic) {
        this.logic = logic;
    }

    /**
     * Contructs a PlayerHandler
     * @param logic the {@link ServerGameLogic} this PlayerHandler is a part of
     * @param p1 a Player to be added
     */
    PlayerHandler(ServerGameLogic logic, Player p1) {
        this(logic);
        players.add(p1);
    }

    /**
     * Contructs a PlayerHandler
     * @param logic the {@link ServerGameLogic} this PlayerHandler is a part of
     * @param players a Collection of Players to be added
     */
    PlayerHandler(ServerGameLogic logic, Collection<Player> players) {
        this(logic);
        players.addAll(players);
    }

    /**
     * Return the number of players
     * @return number of players in the game
     */
    public int getPlayerCount() {
        return players.size();
    }

    /**
     * Chechs if all players are ready to start the game
     * @return {@code true} if all players are ready, otherwise {@code false}
     */
    public boolean allPlayersReady() {
        if (readyPlayers.size() == players.size()) return true;
        return false;
    }

    /**
     * Sets a players Ready status
     * @param player the player to alter
     * @param ready the new Status
     */
    void setPlayerReady(Player player, boolean ready) {
        if (!players.contains(player)) {
            throw new IllegalArgumentException("Player does not belong to this PlayerHandler");
        } else {
            if (ready) {
                readyPlayers.add(player);
            } else {
                readyPlayers.remove(player);
            }
        }
    }

    /**
     * Adds a player to the Queue
     * @param player the player to be added to the queue
     */
    void addPlayer(Player player) {
        if (players.contains(player)) {
            throw new IllegalArgumentException("Player already registered");
        }
        players.add(player);
    }

    /**
     * Removes the specified Player from the Queue
     * @param player the player to be removed
     */
    void removePlayer(Player player) {
        players.remove(player);
    }

    /**
     * Gets Player based on their id in the Queue
     * @param index the index of the queue
     * @return the Player at the required index
     */
    Player getPlayerAtIndex(int index) {
        return players.get(index);
    }

    /**
     * Completes a player turn and return the next player
     * @return the next players who is active
     */
    Player nextPlayer() {
        players.addLast(players.removeFirst());
        return players.getFirst();
    }

    /**
     * Returns the {@link ServerGameLogic} of this PlayerHandler
     * @return the {@link ServerGameLogic} of this PlayerHandler
     */
    ServerGameLogic getLogic() {
        return logic;
    }

    /**
     * Gets a player based on their id
     * @param id the id to be searched for
     * @return the player with the required id
     */
    Player getPlayerById(int id) {
        for (Player player : players) {
            if (player.getId() == id) return player;
        }
        throw new NoSuchElementException("Player mit id "+id+" existiert nicht");
    }
}
