package thb.jeanluc.adventure.command.impl;

import thb.jeanluc.adventure.command.Command;
import thb.jeanluc.adventure.game.Conditions;
import thb.jeanluc.adventure.game.Effects;
import thb.jeanluc.adventure.game.GameContext;
import thb.jeanluc.adventure.model.Npc;
import thb.jeanluc.adventure.model.NpcReaction;
import thb.jeanluc.adventure.model.item.Item;

import java.util.List;
import java.util.Optional;

/**
 * Offers an item from the inventory to an NPC. If the NPC has a matching
 * reaction, the item is consumed (when {@code consumes} is set) and the
 * NPC may give back another item. Usage: {@code give <item> <npc>}.
 */
public class GiveCommand implements Command {

    @Override
    public void execute(GameContext ctx, List<String> args) {
        if (args.size() < 2) {
            ctx.getIo().write("Usage: give <item> <npc>.");
            return;
        }
        String itemId = args.get(0);
        String npcId = args.get(1);

        Optional<Item> held = ctx.getPlayer().findItem(itemId);
        if (held.isEmpty()) {
            ctx.getIo().write("You are not carrying '" + itemId + "'.");
            return;
        }
        Optional<Npc> npcOpt = ctx.getPlayer().getCurrentRoom().findNpc(npcId);
        if (npcOpt.isEmpty()) {
            ctx.getIo().write("There is no '" + npcId + "' here.");
            return;
        }

        Npc npc = npcOpt.get();
        Optional<NpcReaction> reactionOpt = npc.reactionFor(itemId);
        if (reactionOpt.isEmpty()) {
            ctx.getIo().write(npc.getName() + " does not react to the " + held.get().getName() + ".");
            return;
        }

        NpcReaction reaction = reactionOpt.get();
        if (!Conditions.all(reaction.getRequires(), ctx)) {
            ctx.getIo().write(npc.getName() + " isn't ready for that yet.");
            return;
        }
        if (reaction.getConsumes() != null) {
            ctx.getPlayer().removeItem(reaction.getConsumes().getId());
        }
        if (reaction.getGives() != null) {
            ctx.getPlayer().addItem(reaction.getGives());
        }
        Effects.applyAll(reaction.getEffects(), ctx);
        ctx.getIo().write(npc.getName() + ": " + reaction.getResponse());
    }

    @Override
    public String help() {
        return "give <item> <npc>  -  hand an item to an NPC";
    }
}
