package at.reisinger.obj;

import at.reisinger.enums.CardType;
import at.reisinger.enums.ElementTyp;
import at.reisinger.server.helper.EnumHelper;
import com.fasterxml.jackson.annotation.*;

/**
 * Ein einzelner Trading deal wird hier verwaltet.
 */
@JsonAutoDetect
public class TradingDeal {
    @JsonProperty
    private final String id;
    @JsonProperty
    private final String username;
    @JsonProperty
    private Card cardToTrade;
    @JsonProperty
    private ElementTyp requiredElementType;
    @JsonProperty
    private double requiredMinDamage;
    @JsonProperty
    private CardType requiredCardType;

    /**
     * Ein TradingDeal wird  erstellt
     * @param id Id des Trading deals
     * @param cardToTrade at.reisinger.obj.Card die getauscht werden soll
     * @param requiredElementType Req ElementType für den Tausch
     * @param requiredMinDamage Req min damage für den Tausch
     * @param requiredCardType Req at.reisinger.obj.Card Type für den Tausch
     * @param username Username der den Deal erstellt
     */
    public TradingDeal(String id, Card cardToTrade, ElementTyp requiredElementType, double requiredMinDamage, CardType requiredCardType, String username) {
        this.id = id;
        this.cardToTrade = cardToTrade;
        if(requiredElementType == null){
            requiredElementType = ElementTyp.UNDEF;
        }
        if(requiredCardType == null) {
            requiredCardType = CardType.UNDEF;
        }
        this.requiredElementType = requiredElementType;
        this.requiredMinDamage = requiredMinDamage;
        this.requiredCardType = requiredCardType;
        this.username = username;
    }

    /**
     * Ein TradingDeal wird  erstellt, anhand des type werden der ElementType und der CardType automatisch bestimmt
     * @param id Id des Trading deals
     * @param cardToTrade at.reisinger.obj.Card die getauscht werden soll
     * @param type ElementTyp und CardType in einem String. Beide Enums werden durch diesen String gewählt.
     *             Wird kein passender Typ gefunden, dann bleibt diese Eigenschaft auf null
     * @param username Username der den TradingDeal erstellt
     * @param requiredMinDamage Required Min Damage
     */
    @JsonCreator
    public TradingDeal(@JsonProperty("Id") String id, @JsonProperty("CardToTrade") Card cardToTrade, @JsonProperty("MinimumDamage") double requiredMinDamage, @JsonProperty("Type") String type, String username) {
        this(id, cardToTrade, EnumHelper.stringToElementType(type), requiredMinDamage, EnumHelper.stringToCardType(type), username);
    }

    /**
     * Holt die ID des Trading deals
     * @return Id des Trading Deals
     */
    public String getId() {
        return id;
    }

    /**
     * Holt den usernamen
     * @return Der username als String
     */
    @JsonGetter
    public String getUsername() {
        return username;
    }

    /**
     * at.reisinger.obj.Card die getraded werden soll
     * @return at.reisinger.obj.Card die getradet werden soll
     */
    @JsonGetter
    public Card getCardToTrade() {
        return this.cardToTrade;
    }

    /**
     * Req Element type holen
     * @return Req Element Type
     */
    @JsonGetter
    public ElementTyp getRequiredElementType() {
        return this.requiredElementType;
    }

    /**
     * Req min damage holen
     * @return Req min damage
     */
    @JsonGetter
    public double getRequiredMinDamage() {
        return this.requiredMinDamage;
    }

    /**
     * Hole req cardtype
     * @return Req at.reisinger.enums.CardType
     */
    @JsonGetter
    public CardType getRequiredCardType() {
        return this.requiredCardType;
    }

    /**
     * Setzt die Karte die Getradet werden soll
     * @param cardToTrade at.reisinger.obj.Card zum tauschen
     */
    @JsonSetter
    public void setCardToTrade(Card cardToTrade) {
        this.cardToTrade = cardToTrade;
    }

    /**
     * Setzt req elementType
     * @param requiredElementType Der Req elementType
     */
    @JsonSetter
    public void setRequiredElementType(ElementTyp requiredElementType) {
        this.requiredElementType = requiredElementType;
    }

    /**
     * Setzt die req Min damage
     * @param requiredMinDamage Die req min gamage
     */
    @JsonSetter
    public void setRequiredMinDamage(double requiredMinDamage) {
        this.requiredMinDamage = requiredMinDamage;
    }

    /**
     * Setzt req cardType
     * @param requiredCardType Der Req at.reisinger.enums.CardType
     */
    @JsonSetter
    public void setRequiredCardType(CardType requiredCardType) {
        this.requiredCardType = requiredCardType;
    }

    /**
     * Von der at.reisinger.obj.Card im Parameter wird die at.reisinger.obj.Card mit den Requirements von THIS verglichen
     * @param checkCard at.reisinger.obj.Card die mit dem Deal verglichen wird
     * @return True wenn der Deal passt
     */
    public boolean cardOk(Card checkCard){
        return checkCard.getCardType().equals(this.requiredCardType) && (checkCard.getElementTyp().equals(this.requiredElementType) || this.requiredElementType.name().equalsIgnoreCase("undef")) && checkCard.getDamage() >= this.requiredMinDamage;
    }
}
