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

import it.polimi.ingsw.gc14.Model.Cards.Building.BuildingEffect;
import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType;
import it.polimi.ingsw.gc14.Model.PlayableCard;
import it.polimi.ingsw.gc14.Model.Player;

import java.io.Serializable;
import java.util.ArrayList;
public class BuildingCard extends PlayableCard implements Cloneable , BuildingEffect, Serializable {
     /**
     * The price of this building card.
     */
    private int price;

    /**
     * Returns the price of this building card.
     *
     * @return the price of this building card.
     */
    public int getPrice() {
        return price;
    }

    /**
     * Indicates whether this building card has already been bought.
     */
    private boolean bought;

    /**
     * The type of effect associated with this building card.
     */
    protected EffectType effectType;

    /**
     * The identifier of the effect associated with this building card.
     */
    protected int effectId;

    /**
     * The prestige value of this building card.
     */
    private int prestigeValue;

    /**
     * Returns the prestige value of this building card.
     *
     * @return the prestige value of this building card.
     */
    public int  getPrestigeValue() {
        return prestigeValue;
    }

    /**
     * Returns the identifier of the effect associated with this building card.
     *
     * @return the effect identifier of this building card.
     */
    public int getEffectId() {
        return effectId;
    }

    /**
     * Returns the type of effect associated with this building card.
     *
     * @return the effect type of this building card.
     */
    public EffectType getEffectType() {
        return effectType;
    }

    /**
     * Creates a building card with the specified era, price, and prestige value.
     *
     * @param era the era of the building card.
     * @param price the price of the building card.
     * @param prestigeValue the prestige value of the building card.
     * @throws IllegalArgumentException if {@code price <= 0} or {@code prestigeValue < 0}
     */
    protected BuildingCard(int era,int price,int prestigeValue) throws IllegalArgumentException{
        super(era);
        if (price > 0) {
            this.price = price;
        } else {
            throw new IllegalArgumentException();
        }
        if (prestigeValue >= 0) {
            this.prestigeValue = prestigeValue;
        } else {
            throw new IllegalArgumentException();
        }

        bought = false;
    }


    /**
     * Creates a building card with the specified effect identifier, era, price,
     * and prestige value.
     * The effect type is determined from the given effect identifier.
     *
     * @param effectId the identifier of the effect associated with the building card.
     * @param era the era of the building card.
     * @param price the price of the building card.
     * @param prestigeValue the prestige value of the building card.
     * @throws IllegalArgumentException if the effect identifier is not valid,
     *         if {@code price <= 0}, or if {@code prestigeValue < 0}
     */
    public BuildingCard(int effectId ,int era,int price,int prestigeValue) throws IllegalArgumentException{
        this.effectId = effectId;
        switch (effectId){
            case 2:
                this.effectType=EffectType.ON_EVENT;
                break;
            case 3:
                this.effectType=EffectType.ON_END_TURN;
                break;
            case 5:
                this.effectType=EffectType.ON_EVENT;
                break;
            case 6:
                this.effectType=EffectType.ON_EVENT;
                break;
            case 7:
                this.effectType=EffectType.ON_EVENT;
                break;
            case 9:
                this.effectType=EffectType.ON_EVENT;
                break;
            case 12:
                    this.effectType=EffectType.ON_ROUND_END;
                break;
            default:
                throw new IllegalArgumentException();

        }
        this(era,price,prestigeValue);
    }

    /**
     * Creates and returns a copy of this building card.
     *
     * @return a clone of this building card.
     */
    @Override
    public BuildingCard clone()
    {
        return new BuildingCard(effectId,getEra(),getPrice(),getPrestigeValue());
    }

    /**
     * Attempts to buy this building card for the specified player.
     * The purchase succeeds only if the card has not already been bought
     * and the player can pay its price in Food.
     * If the purchase succeeds, the card is added to the player's building cards
     * and marked as bought.
     *
     * @param player the player attempting to buy the building card.
     * @return {@code true} if the building card is successfully bought,
     *         {@code false} otherwise.
     */
    public boolean buy(Player player) {
        if( bought || !player.removeFood(getPrice()))
            return false;
        player.buildingCards.add(this);
        bought=true;
        return true;
    }

    /**
     * Applies the effect of this building card to the specified player.
     *
     * @param player the player to whom the effect is applied.
     */
    @Override
    public void applyEffect(Player player){};

    /**
     * Returns the string representation of this building card.
     *
     * @return the string representation of this building card.
     */
    @Override
    public String toString() {
        return "Era:"+String.valueOf(getEra())+" Price:"+String.valueOf(getPrice())+" Prestige:"+String.valueOf(getPrestigeValue());
    }
}
