package mage.cards.k;

import mage.ApprovingObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.ProwlAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetOpponent;

import java.util.UUID;

/**
 * @author emerald000
 */
public final class KnowledgeExploitation extends CardImpl {

    public KnowledgeExploitation(UUID ownerId, CardSetInfo setInfo) {
        super(ownerId, setInfo, new CardType[]{CardType.KINDRED, CardType.SORCERY}, "{5}{U}{U}");
        this.subtype.add(SubType.ROGUE);

        // Prowl {3}{U}
        this.addAbility(new ProwlAbility("{3}{U}"));

        // Search target opponent's library for an instant or sorcery card. 
        // You may cast that card without paying its mana cost. 
        // Then that player shuffles their library.
        this.getSpellAbility().addEffect(new KnowledgeExploitationEffect());
        this.getSpellAbility().addTarget(new TargetOpponent());
    }

    private KnowledgeExploitation(final KnowledgeExploitation card) {
        super(card);
    }

    @Override
    public KnowledgeExploitation copy() {
        return new KnowledgeExploitation(this);
    }
}

class KnowledgeExploitationEffect extends OneShotEffect {

    KnowledgeExploitationEffect() {
        super(Outcome.PlayForFree);
        this.staticText = "Search target opponent's library for an "
                + "instant or sorcery card. You may cast that card "
                + "without paying its mana cost. Then that "
                + "player shuffles";
    }

    private KnowledgeExploitationEffect(final KnowledgeExploitationEffect effect) {
        super(effect);
    }

    @Override
    public KnowledgeExploitationEffect copy() {
        return new KnowledgeExploitationEffect(this);
    }

    @Override
    public boolean apply(Game game, Ability source) {
        Player controller = game.getPlayer(source.getControllerId());
        Player opponent = game.getPlayer(source.getFirstTarget());
        if (controller == null || opponent == null) {
            return false;
        }
        TargetCardInLibrary target = new TargetCardInLibrary(
                0, 1, StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY
        );
        controller.searchLibrary(target, source, game, opponent.getId());
        Card card = opponent.getLibrary().getCard(target.getFirstTarget(), game);
        if (card != null) {
            game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
            controller.cast(
                    controller.chooseAbilityForCast(card, game, true),
                    game, true, new ApprovingObject(source, game)
            );
            game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
        }
        opponent.shuffleLibrary(source, game);
        return true;
    }
}
