package eu.jonahbauer.wizard.client.libgdx.actors;

import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;
import eu.jonahbauer.wizard.client.libgdx.GameAtlas;
import eu.jonahbauer.wizard.common.model.Card;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;
import java.util.NoSuchElementException;

@Getter
@Setter
public class CardActor extends Actor {
    public static final float ASPECT_RATIO = 400f / 260f;
    public static final float PREF_WIDTH = 135;
    public static final float PREF_HEIGHT = 208;

    private static final Map<Card, String> ATLAS_PATHS;

    static {
        var paths = new EnumMap<Card, String>(Card.class);
        for (Card card : Card.values()) {
            paths.put(card, switch (card) {
                case BLUE_1 -> GameAtlas.CARDS_BLUE_1;
                case BLUE_2 -> GameAtlas.CARDS_BLUE_2;
                case BLUE_3 -> GameAtlas.CARDS_BLUE_3;
                case BLUE_4 -> GameAtlas.CARDS_BLUE_4;
                case BLUE_5 -> GameAtlas.CARDS_BLUE_5;
                case BLUE_6 -> GameAtlas.CARDS_BLUE_6;
                case BLUE_7 -> GameAtlas.CARDS_BLUE_7;
                case BLUE_8 -> GameAtlas.CARDS_BLUE_8;
                case BLUE_9 -> GameAtlas.CARDS_BLUE_9;
                case BLUE_10 -> GameAtlas.CARDS_BLUE_10;
                case BLUE_11 -> GameAtlas.CARDS_BLUE_11;
                case BLUE_12 -> GameAtlas.CARDS_BLUE_12;
                case BLUE_13 -> GameAtlas.CARDS_BLUE_13;
                case RED_1 -> GameAtlas.CARDS_RED_1;
                case RED_2 -> GameAtlas.CARDS_RED_2;
                case RED_3 -> GameAtlas.CARDS_RED_3;
                case RED_4 -> GameAtlas.CARDS_RED_4;
                case RED_5 -> GameAtlas.CARDS_RED_5;
                case RED_6 -> GameAtlas.CARDS_RED_6;
                case RED_7 -> GameAtlas.CARDS_RED_7;
                case RED_8 -> GameAtlas.CARDS_RED_8;
                case RED_9 -> GameAtlas.CARDS_RED_9;
                case RED_10 -> GameAtlas.CARDS_RED_10;
                case RED_11 -> GameAtlas.CARDS_RED_11;
                case RED_12 -> GameAtlas.CARDS_RED_12;
                case RED_13 -> GameAtlas.CARDS_RED_13;
                case YELLOW_1 -> GameAtlas.CARDS_YELLOW_1;
                case YELLOW_2 -> GameAtlas.CARDS_YELLOW_2;
                case YELLOW_3 -> GameAtlas.CARDS_YELLOW_3;
                case YELLOW_4 -> GameAtlas.CARDS_YELLOW_4;
                case YELLOW_5 -> GameAtlas.CARDS_YELLOW_5;
                case YELLOW_6 -> GameAtlas.CARDS_YELLOW_6;
                case YELLOW_7 -> GameAtlas.CARDS_YELLOW_7;
                case YELLOW_8 -> GameAtlas.CARDS_YELLOW_8;
                case YELLOW_9 -> GameAtlas.CARDS_YELLOW_9;
                case YELLOW_10 -> GameAtlas.CARDS_YELLOW_10;
                case YELLOW_11 -> GameAtlas.CARDS_YELLOW_11;
                case YELLOW_12 -> GameAtlas.CARDS_YELLOW_12;
                case YELLOW_13 -> GameAtlas.CARDS_YELLOW_13;
                case GREEN_1 -> GameAtlas.CARDS_GREEN_1;
                case GREEN_2 -> GameAtlas.CARDS_GREEN_2;
                case GREEN_3 -> GameAtlas.CARDS_GREEN_3;
                case GREEN_4 -> GameAtlas.CARDS_GREEN_4;
                case GREEN_5 -> GameAtlas.CARDS_GREEN_5;
                case GREEN_6 -> GameAtlas.CARDS_GREEN_6;
                case GREEN_7 -> GameAtlas.CARDS_GREEN_7;
                case GREEN_8 -> GameAtlas.CARDS_GREEN_8;
                case GREEN_9 -> GameAtlas.CARDS_GREEN_9;
                case GREEN_10 -> GameAtlas.CARDS_GREEN_10;
                case GREEN_11 -> GameAtlas.CARDS_GREEN_11;
                case GREEN_12 -> GameAtlas.CARDS_GREEN_12;
                case GREEN_13 -> GameAtlas.CARDS_GREEN_13;
                case JUGGLER -> GameAtlas.CARDS_JUGGLER;
                case JUGGLER_BLUE -> GameAtlas.CARDS_JUGGLER_BLUE;
                case JUGGLER_RED -> GameAtlas.CARDS_JUGGLER_RED;
                case JUGGLER_GREEN -> GameAtlas.CARDS_JUGGLER_GREEN;
                case JUGGLER_YELLOW -> GameAtlas.CARDS_JUGGLER_YELLOW;
                case CLOUD -> GameAtlas.CARDS_CLOUD;
                case CLOUD_GREEN -> GameAtlas.CARDS_CLOUD_GREEN;
                case CLOUD_RED -> GameAtlas.CARDS_CLOUD_RED;
                case CLOUD_YELLOW -> GameAtlas.CARDS_CLOUD_YELLOW;
                case CLOUD_BLUE -> GameAtlas.CARDS_CLOUD_BLUE;
                case BOMB -> GameAtlas.CARDS_BOMB;
                case FAIRY -> GameAtlas.CARDS_FAIRY;
                case DRAGON -> GameAtlas.CARDS_DRAGON;
                case CHANGELING -> GameAtlas.CARDS_CHANGELING;
                case CHANGELING_WIZARD -> GameAtlas.CARDS_CHANGELING_WIZARD;
                case CHANGELING_JESTER -> GameAtlas.CARDS_CHANGELING_JESTER;
                case BLUE_JESTER -> GameAtlas.CARDS_BLUE_JESTER;
                case RED_JESTER -> GameAtlas.CARDS_RED_JESTER;
                case GREEN_JESTER -> GameAtlas.CARDS_GREEN_JESTER;
                case YELLOW_JESTER -> GameAtlas.CARDS_YELLOW_JESTER;
                case RED_WIZARD -> GameAtlas.CARDS_RED_WIZARD;
                case GREEN_WIZARD -> GameAtlas.CARDS_GREEN_WIZARD;
                case YELLOW_WIZARD -> GameAtlas.CARDS_YELLOW_WIZARD;
                case BLUE_WIZARD -> GameAtlas.CARDS_BLUE_WIZARD;
                case WEREWOLF -> GameAtlas.CARDS_WEREWOLF;
                default -> GameAtlas.CARDS_BACKGROUND;
            });
        }
        ATLAS_PATHS = Collections.unmodifiableMap(paths);
    }

    private final TextureAtlas atlas;

    private Card card;
    private TextureRegion background;

    private CardActor(TextureAtlas atlas) {
        this.atlas = atlas;
        setWidth(PREF_WIDTH);
        setHeight(PREF_HEIGHT);
        setOrigin(PREF_WIDTH / 2, PREF_HEIGHT / 2);
    }

    public CardActor(@NotNull Card card, @NotNull TextureAtlas atlas) {
        this(atlas);
        setCard(card);
    }

    public CardActor(@NotNull Card.Suit suit, @NotNull TextureAtlas atlas) {
        this(atlas);
        setCard(suit);
    }

    public void setCard(@NotNull Card card) {
        this.card = card;
        this.background = atlas.findRegion(ATLAS_PATHS.get(card));
        if (this.background == null) throw new NoSuchElementException("Could not find texture for card " + card + ".");
    }

    public void setCard(@NotNull Card.Suit suit) {
        this.card = null;
        this.background = atlas.findRegion(switch (suit) {
            case NONE -> GameAtlas.CARDS_BACKGROUND;
            case GREEN -> GameAtlas.CARDS_GREEN;
            case YELLOW -> GameAtlas.CARDS_YELLOW;
            case BLUE -> GameAtlas.CARDS_BLUE;
            case RED -> GameAtlas.CARDS_RED;
        });
        if (this.background == null) throw new NoSuchElementException("Could not find texture for suit " + suit + ".");
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        var color = getColor();
        batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);

        float height = getWidth() * ASPECT_RATIO;
        batch.draw(background, getX(), getY() + getHeight() - height, getOriginX(), getOriginY(), getWidth(), height, getScaleX(), getScaleY(), getRotation());
    }
}