package it.polimi.ingsw.gc14.Model.Cards.Building.Effects;

import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType;
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Inventor;
import it.polimi.ingsw.gc14.Model.Player;

import java.util.HashMap;

/**
 * From the moment you purchase this building, every time you obtain a pair of identical inventors, you gain 3 food.
 * This effect doesn't apply to already owned pairs at the time of purchase.
 */
public class Building4 extends BuildingCard {

    /**
     * The purchased attribute is used to indicate whether the card has already been initialized.
     */
    boolean purchased ;

    /**
     * The numPair attribute indicates how many pairs of inventors the player has.
     */
    int numPair;

    /**
     * Constructor of the building
     * @param era The game era of the building.
     * @param price The price (in food) of the building.
     * @param prestigeValue The number of Prestige Points gained from this building at the end of the game.
     */
    public Building4(int era, int price,int prestigeValue) {
        super(era,price,prestigeValue);
        effectType= EffectType.INVENTOR_PAIR;
        effectId=4;
    }

    /**
     * Initializes the building by counting the number of pairs of inventors at the moment of purchase.
     * The building can only be initialized once.
     * @param player the player who owns the building, whose inventors are counted to determine the number of pairs.
     */
    public void initialize(Player player)
    {
        if(purchased)
        {
            return;
        }
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<10;i++)
        {
            map.put(i,0);
        }
        for(Inventor inv : player.inventors)
        {
            map.merge(inv.Icon(),1,Integer::sum);
        }
        numPair=0;
        for(Integer i : map.values())
        {
            numPair+=(i/2);
        }
        purchased = true;

    }

    /**
     * Method used to purchase the building. It also handles its initialization.
     * @param player The player who buys the building.
     * @return The outcome of the operation.
     */
    @Override
    public boolean buy(Player player)
    {
        if(!super.buy(player))
            return false;
        initialize(player);
        return true;
    }

    /**
     * Method to clone the building: it creates an exact copy.
     * @return The new copy of the building.
     */
    @Override
    public BuildingCard clone() {
        return new Building4(getEra(),getPrice(),getPrestigeValue());
    }

    /**
     * Calculates the current number of pairs and subtracts the previous value (i.e., the number of newly obtained pairs).
     * The player gains an amount of food equal to 3 times this result.
     * @param player The player who owns the building.
     * @throws IllegalArgumentException Thrown if the specified player does not own this card.
     */
    @Override
    public void applyEffect(Player player) throws IllegalArgumentException {
        if(!player.buildingCards.contains(this))
            throw new IllegalArgumentException();
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<10;i++)
        {
            map.put(i,0);
        }
        for(Inventor inv : player.inventors)
        {
            map.merge(inv.Icon(),1,Integer::sum);
        }
        int temp=0;
        for(Integer i : map.values())
        {
            temp+=(i/2);
        }
        if(temp<= numPair)
        {
            return;
        }
        player.addFood(3*(temp-numPair));
        numPair = temp;
    };
}
