package it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events;

import it.polimi.ingsw.gc14.Model.Cards.TribeCards.EventType;
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.EventCard;
import it.polimi.ingsw.gc14.Model.Player;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * When activated, rewards the player with the most shaman icons and penalizes the one with the fewest.
 *
 * @see EventCard
 */
public class ShamanicRitual extends EventCard {
    /** Prestige points awarded to the player with the most shaman icons. */
    int prestigeToAdd;

    /** Prestige points removed from the player with the fewest shaman icons. */
    int prestigeToRemove;

    /**
     * Creates a new ShamanicRitual event card.
     *
     * @param Era              the era of the card
     * @param prestigeToAdd    prestige points awarded to the player with the most icons
     * @param prestigeToRemove prestige points removed from the player with the fewest icons
     */
    public ShamanicRitual(int Era, int prestigeToAdd, int prestigeToRemove) {
        super(Era, EventType.SHAMANIC_RITUAL);
        this.prestigeToAdd = prestigeToAdd;
        this.prestigeToRemove = prestigeToRemove;

    }

    /**
     * Activates the event card "Shamanic Ritual".
     * The player with the most icons gains the Prestige Points indicated.
     * The player with the fewest icons loses the Prestige Points indicated.
     * In case of a tie, all players gain or lose the Prestige Points indicated.
     * If all players have the same amount of icons, they all gain and lose Prestige Points.
     *
     * Buildings influence:
     *      Building 2: if you have the lowest number of icons, you don't lose Prestige Points
     *      Building 5: during the Shamanic Ritual, you gain 3 icons
     *      Building 6: if you have more icons than any other player, you gain double of Prestige Points
     *
     * @param playerList contains all the players in the game
     */
    @Override
    public void activateEvent (ArrayList <Player> playerList){
        Map<Player, Integer> playerMap = new HashMap<>();
        int tmpIcons = 0;
        int tmpCount = 0;

        for (Player player : playerList) {
            tmpIcons = player.shamans.stream().mapToInt(sh -> sh.getIcon()).sum();
            tmpCount = (int) player.buildingCards.stream().filter(b -> b.getEffectId() == 5).count();
            if (tmpCount >= 1) {
                tmpIcons = tmpIcons+(3*tmpCount);
            }
            playerMap.put(player, tmpIcons);
        }

        int maxIcon = playerMap.values().stream().mapToInt(Integer::intValue).max().orElse(0);
        int minIcon = playerMap.values().stream().mapToInt(Integer::intValue).min().orElse(0);

        List<Player> maxIconsPlayer = playerMap.entrySet().stream().filter(e -> e.getValue() == maxIcon).map(Map.Entry::getKey).collect(Collectors.toList());
        List<Player> minIconsPlayer = playerMap.entrySet().stream().filter(e -> e.getValue() == minIcon).map(Map.Entry::getKey).collect(Collectors.toList());


        for (Player player : maxIconsPlayer) {
            if (player.buildingCards.stream().anyMatch(b -> b.getEffectId() == 6) && maxIconsPlayer.size() == 1) {
                player.addPrestige(prestigeToAdd * 2);
            } else {
                player.addPrestige(prestigeToAdd);
            }
        }

        for (Player player : minIconsPlayer) {
            if (!(player.buildingCards.stream().anyMatch(b -> b.getEffectId() == 2))) {
                player.removePrestige(prestigeToRemove);
            }
        }

    }

    /**
     * Creates and returns a copy of this ShamanicRitual card.
     *
     * @return a new ShamanicRitual card with the same era and prestige values
     */
    @Override
    public EventCard clone() {
        return new ShamanicRitual(getEra(), prestigeToAdd, prestigeToRemove);
    }


}
