package it.polimi.ingsw.gc14.Controller;

import it.polimi.ingsw.gc14.Model.Game;
import it.polimi.ingsw.gc14.Model.Player;

/**
 * Controller class that manages interactions between the client-side logic
 * and the {@link Game} model.
 * It provides methods to add players and to perform game actions by delegating them to the model.
 */
public class GameController {

    /**
     * The game model managed by this controller.
     */
    private Game model;

    /**
     * Creates a GameController associated with the specified game model.
     *
     * @param model the game model managed by this controller.
     */
    public GameController(Game model) {
        this.model = model;
    }

    /**
     * Creates a GameController without an associated game model.
     */
    public GameController() {
    }

    /**
     * Returns the game model managed by this controller.
     *
     * @return the game model managed by this controller.
     */
    public Game getModel() {
        return model;
    }

    /**
     * Updates the game model managed by this controller.
     *
     * @param model the new game model managed by this controller.
     */
    public void setModel(Game model) {
        this.model = model;
    }

    /**
     * Attempts to add a new player with the specified username to the game model.
     *
     * @param username the username of the player to add.
     * @return {@code true} if the player is successfully added, {@code false} otherwise.
     */
    public boolean addPlayer(String username) {
        return model.addPlayer(new Player(username));
    }

    /**
     * Attempts to draw an upper tribe card for the specified player from the specified position.
     *
     * @param playerUsername the username of the player performing the action.
     * @param pos the position of the upper tribe card to draw.
     * @return {@code true} if the action succeeds, {@code false} if the player does not exist
     *         or if the draw operation fails.
     */
    public boolean drawUpperTribeCard(String playerUsername,int pos) {
        Player player= model.getPlayerByUsername(playerUsername);
        if(player==null)
            return false;
        return model.DrawUpperTribeCardByIndex(model.getPlayerByUsername(playerUsername),pos);
    }

    /**
     * Attempts to draw a lower tribe card for the specified player from the specified position.
     *
     * @param playerUsername the username of the player performing the action.
     * @param pos the position of the lower tribe card to draw.
     * @return {@code true} if the action succeeds, {@code false} if the player does not exist
     *         or if the draw operation fails.
     */
    public boolean drawLowerTribeCard(String playerUsername,int pos) {
        Player player= model.getPlayerByUsername(playerUsername);
        if(player==null)
            return false;
        return model.DrawLowerTribeCardByIndex(model.getPlayerByUsername(playerUsername), pos);
    }

    /**
     * Attempts to draw an upper building card for the specified player from the specified position.
     *
     * @param playerUsername the username of the player performing the action.
     * @param pos the position of the upper building card to draw.
     * @return {@code true} if the action succeeds, {@code false} if the player does not exist
     *         or if the draw operation fails.
     */
    public boolean drawUpperBuildingCard(String playerUsername,int pos) {
        Player player= model.getPlayerByUsername(playerUsername);
        if(player==null)
            return false;
        return model.DrawUpperBuildingCardByIndex(model.getPlayerByUsername(playerUsername), pos);
    }

    /**
     * Attempts to draw a lower building card for the specified player from the specified position.
     *
     * @param playerUsername the username of the player performing the action.
     * @param pos the position of the lower building card to draw.
     * @return {@code true} if the action succeeds, {@code false} if the player does not exist
     *         or if the draw operation fails.
     */
    public boolean drawLowerBuildingCard(String playerUsername,int pos) {
        Player player= model.getPlayerByUsername(playerUsername);
        if(player==null)
            return false;
        return model.DrawLowerBuildingCardByIndex(model.getPlayerByUsername(playerUsername), pos);
    }

    /**
     * Attempts to pick an optional tribe card for the specified player from the specified position.
     *
     * @param playerUsername the username of the player performing the action.
     * @param pos the position of the optional tribe card to pick.
     * @return {@code true} if the action succeeds, {@code false} if the player does not exist
     *         or if the pick operation fails.
     */
    public boolean pickOptionalTribeCard(String playerUsername,int pos) {
        Player player= model.getPlayerByUsername(playerUsername);
        if(player==null)
            return false;
        return model.PickOptionalTribeCardByIndex(model.getPlayerByUsername(playerUsername), pos);
    }

    /**
     * Attempts to pick an optional building card for the specified player from the specified position.
     *
     * @param playerUsername the username of the player performing the action.
     * @param pos the position of the optional building card to pick.
     * @return {@code true} if the action succeeds, {@code false} if the player does not exist
     *         or if the pick operation fails.
     */
    public boolean pickOptionalBuildingCard(String playerUsername,int pos) {
        Player player= model.getPlayerByUsername(playerUsername);
        if(player==null)
            return false;
        return model.PickOptionalBuildingCard(model.getPlayerByUsername(playerUsername), pos);
    }

    /**
     * Attempts to perform the slot choice action for the specified player at the specified position.
     *
     * @param playerUsername the username of the player performing the action.
     * @param pos the position of the chosen slot.
     * @return {@code true} if the action succeeds, {@code false} if the player does not exist
     *         or if the slot choice operation fails.
     */
    public boolean slotChoice(String playerUsername,int pos) {
        Player player= model.getPlayerByUsername(playerUsername);
        if(player==null)//playerIndex>=model.)
            return false;
        return model.SlotChoiceByIndex(model.getPlayerByUsername(playerUsername),pos);
    }
}
