package eu.jonahbauer.wizard.core.states.round;

import eu.jonahbauer.wizard.common.model.Card;
import eu.jonahbauer.wizard.core.states.GameData;
import eu.jonahbauer.wizard.core.Game;
import eu.jonahbauer.wizard.common.messages.observer.TrumpMessage;
import eu.jonahbauer.wizard.core.states.GameState;
import eu.jonahbauer.wizard.core.model.card.GameCards;

import java.util.*;

import static eu.jonahbauer.wizard.core.states.GameData.*;

public final class DeterminingTrump extends RoundState {

    public DeterminingTrump(GameData data) {
        super(data.require(TRUMP_CARD).requireEach(PLAYERS, HANDS));
    }

    @Override
    public Optional<GameState> onEnter(Game game) {
        Card trumpCard = get(TRUMP_CARD);

        // handle werewolf
        for (Map.Entry<UUID, List<Card>> entry : get(HANDS).entrySet()) {
            var player = entry.getKey();
            var hand = entry.getValue();
            if (hand.contains(Card.WEREWOLF)) {
                game.notify(new TrumpMessage(trumpCard, null));
                game.notify(new TrumpMessage(Card.WEREWOLF, null));

                var data = getData().with(CURRENT_PLAYER, player);
                return sync(data, DeterminingTrumpUserInput::new);
            }
        }

        // default trump handling
        Card.Suit trumpSuit = trumpCard != null ? GameCards.get(trumpCard).getTrumpSuit() : Card.Suit.NONE;
        if (trumpSuit == null) {
            var player = getDealer();
            game.notify(new TrumpMessage(trumpCard, null));

            var data = getData().with(CURRENT_PLAYER, player);
            return sync(data, DeterminingTrumpUserInput::new);
        } else {
            var data = getData().with(
                    TRUMP_SUIT, trumpSuit,
                    CURRENT_PLAYER, getNextPlayer(getDealer())
            );

            game.notify(new TrumpMessage(get(TRUMP_CARD), trumpSuit));

            return sync(data, Predicting::new);
        }
    }
}
