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.*;

import java.util.Objects;

/**
 * Object einer at.reisinger.obj.Card
 */
@JsonAutoDetect
public class Card {
    @JsonProperty
    private String name;
    @JsonProperty
    private double damage;
    @JsonProperty
    private ElementTyp elementTyp;
    @JsonProperty
    private final CardType cardType;
    @SuppressWarnings("unused")
    @JsonProperty
    private boolean locked;

    /**
     * Erstellt eine neue at.reisinger.obj.Card mit gegebenen Eigenschaften
     * @param name Name der at.reisinger.obj.Card
     * @param damage Damage den die at.reisinger.obj.Card macht
     * @param elementTyp ElementType der at.reisinger.obj.Card
     * @param cardType at.reisinger.enums.CardType der at.reisinger.obj.Card
     */
    public Card(String name, double damage, ElementTyp elementTyp, CardType cardType) {
        this.name = name;
        this.damage = damage;
        this.elementTyp = elementTyp;
        this.cardType = cardType;
    }

    /**
     * Erstellt eine neue Card mit, anhand des cardNamen werden der ElementType und der CardType automatisch bestimmt
     * @param name Name der Card (ID)
     * @param elementCardTyp 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 damage Damage der Card
     */
    @JsonCreator
    public Card(@JsonProperty("Id") String name, @JsonProperty("Name") String elementCardTyp, @JsonProperty("Damage") double damage){
        CardType tmpCard = EnumHelper.stringToCardType(elementCardTyp);
        ElementTyp tmpElement = null;
        if(tmpCard == null){
            tmpCard = CardType.UNDEF;
        }

        //Spezialkarten die kein element besitzen, bekommen hier ihr natürliches element zugewiesen
        switch (tmpCard.name().toLowerCase()) {
            case "dragon":
            case "fireelves":
                tmpElement = ElementTyp.FIRE;
                break;
            case "ork":
            case "wizzard":
            case "knight":
            case "troll":
            case "goblin":
            case "elf":
                tmpElement = ElementTyp.REGULAR;
                break;
            case "kraken":
                tmpElement = ElementTyp.WATER;
                break;
        }

        if(tmpElement == null){
            tmpElement = EnumHelper.stringToElementType(elementCardTyp);
            //Deutsch übersetzung
            switch (Objects.requireNonNull(tmpElement).name().toLowerCase()) {
                case "feuer":
                    tmpElement = ElementTyp.FIRE;
                    break;
                case "wasser":
                    tmpElement = ElementTyp.WATER;
                    break;
                case "normal":
                    tmpElement = ElementTyp.REGULAR;
                    break;
            }
        }
        this.name = name;
        this.damage = damage;
        this.elementTyp = tmpElement;
        this.cardType = tmpCard;
    }

    /**
     * Holt den Namen der at.reisinger.obj.Card
     * @return Name der at.reisinger.obj.Card
     */
    @JsonGetter
    public String getName() {
        return this.name;
    }

    /**
     * Holt den Damage der at.reisinger.obj.Card
     * @return Damage der at.reisinger.obj.Card
     */
    @JsonGetter
    public double getDamage() {
        return this.damage;
    }

    /**
     * Holt den ElementType der at.reisinger.obj.Card
     * @return ElementType der at.reisinger.obj.Card
     */
    @JsonGetter
    public ElementTyp getElementTyp() {
        return this.elementTyp;
    }

    /**
     * Holt den at.reisinger.enums.CardType der at.reisinger.obj.Card
     * @return at.reisinger.enums.CardType der at.reisinger.obj.Card
     */
    @JsonGetter
    public CardType getCardType() {
        return this.cardType;
    }

    /**
     * Setzt den namen der Card
     * @param neuerName Name der at.reisinger.obj.Card
     */
    @JsonSetter
    public void setName(String neuerName) {
        this.name = neuerName;
    }

    /**
     * Setzt den Damage der at.reisinger.obj.Card
     * @param damage Der Damage
     */
    @JsonSetter
    public void setDamage(int damage) {
        this.damage = damage;
    }

    /**
     * Setzt den ElementType der at.reisinger.obj.Card
     * @param elementTyp Der ElementType
     */
    @JsonSetter
    public void setElementType(ElementTyp elementTyp) {
        this.elementTyp = elementTyp;
    }

    /**
     * Testet ob die beiden Karten gleich sind
     * @param card at.reisinger.obj.Card die geprüft werden soll
     * @return True wenn die Karten übereinstimmen
     */
    public boolean equals(Card card){
        if(card == null) return false;
        return this.name.equals(card.getName()) && this.cardType == card.getCardType() && this.elementTyp == card.getElementTyp() && this.damage == card.getDamage();
    }
}
