package de.iani.cubequest.commands;

import de.iani.cubequest.CubeQuest;
import de.iani.cubequest.PlayerData;
import de.iani.cubequest.QuestManager;
import de.iani.cubequest.questStates.AmountQuestState;
import de.iani.cubequest.questStates.QuestState.Status;
import de.iani.cubequest.quests.AmountQuest;
import de.iani.cubequest.quests.BlockBreakQuest;
import de.iani.cubequest.quests.BlockPlaceQuest;
import de.iani.cubequest.quests.ComplexQuest;
import de.iani.cubequest.quests.FishingQuest;
import de.iani.cubequest.quests.KillEntitiesQuest;
import de.iani.cubequest.quests.Quest;
import de.iani.cubequest.quests.TameEntitiesQuest;
import de.iani.cubequest.util.ChatAndTextUtil;
import de.iani.cubequest.util.Util;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.HoverEvent.Action;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class AchievementInfoCommand extends SubCommand {
    
    public static final String COMMAND_PATH = "achievements";
    public static final String FULL_COMMAND = "quest " + COMMAND_PATH;
    
    @Override
    public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
        
        OfflinePlayer player;
        if (args.hasNext()) {
            String playerString = args.next();
            try {
                UUID id = UUID.fromString(playerString);
                player = CubeQuest.getInstance().getPlayerUUIDCache().getPlayer(id);
            } catch (IllegalArgumentException e) {
                player = CubeQuest.getInstance().getPlayerUUIDCache().getPlayer(playerString);
            }
            
            if (player == null) {
                ChatAndTextUtil.sendWarningMessage(sender, "Spieler " + playerString + " nicht gefunden.");
                return true;
            }
        } else if (sender instanceof Player) {
            player = (Player) sender;
        } else {
            ChatAndTextUtil.sendWarningMessage(sender, "Bitt gib einen Spieler an.");
            return true;
        }
        
        ChatAndTextUtil.sendNormalMessage(sender,
                sender == player ? ("Deine erreichten Achievements:") : ("Die erreicheten Achievements von " + player.getName() + ":"));
        PlayerData data = CubeQuest.getInstance().getPlayerData(player);
        boolean none = true;
        
        List<ComplexQuest> achievementQuests = QuestManager.getInstance().getQuests(ComplexQuest.class).stream()
                .filter(ComplexQuest::isAchievementQuest).collect(Collectors.toCollection(ArrayList::new));
        achievementQuests.sort(Quest.QUEST_DISPLAY_COMPARATOR);
        
        for (ComplexQuest quest : achievementQuests) {
            if (quest.getFollowupQuest() != null && !data.isGivenTo(quest.getFollowupQuest().getId())) {
                continue;
            }
            if (quest.getFollowupQuest() == null && data.getPlayerStatus(quest.getId()) != Status.SUCCESS) {
                continue;
            }
            if (quest.getFollowupQuest() != null && !Util.isLegalAchievementQuest(quest.getFollowupQuest())) {
                continue;
            }
            
            none = false;
            ComponentBuilder builder = new ComponentBuilder(quest.getDisplayName());
            builder.color(ChatColor.GOLD);
            if (quest.getFollowupQuest() != null) {
                AmountQuest inner = (AmountQuest) ((ComplexQuest) quest.getFollowupQuest()).getSubQuests().iterator().next();
                
                String possibilities = null;
                if (inner instanceof BlockBreakQuest) {
                    possibilities = ChatAndTextUtil.multipleMaterialsString(((BlockBreakQuest) inner).getTypes());
                } else if (inner instanceof BlockPlaceQuest || inner instanceof FishingQuest) {
                    possibilities = ChatAndTextUtil.multipleMaterialsString(((BlockPlaceQuest) inner).getTypes());
                } else if (inner instanceof KillEntitiesQuest) {
                    possibilities = ChatAndTextUtil.multipleMobsString(((KillEntitiesQuest) inner).getTypes());
                } else if (inner instanceof TameEntitiesQuest) {
                    possibilities = ChatAndTextUtil.multipleMobsString(((TameEntitiesQuest) inner).getTypes());
                }
                
                builder.append(" (für nächste Stufe: ").color(ChatColor.BLUE);
                if (possibilities != null) {
                    builder.event(new HoverEvent(Action.SHOW_TEXT, new ComponentBuilder(possibilities).create()));
                }
                
                builder.append(String.valueOf(((AmountQuestState) data.getPlayerState(inner.getId())).getAmount())).color(ChatColor.AQUA)
                        .append(" / ").append(String.valueOf(inner.getAmount())).append(")").color(ChatColor.BLUE);
            } else {
                builder.append(" (höchste Stufe)").color(ChatColor.BLUE);
            }
            sender.sendMessage(builder.create());
        }
        
        if (none)
        
        {
            ChatAndTextUtil.sendNormalMessage(sender, "- keine -");
        }
        
        return true;
    }
    
    @Override
    public List<String> onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) {
        return Bukkit.getServer().getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList());
    }
    
    @Override
    public String getRequiredPermission() {
        return CubeQuest.ACCEPT_QUESTS_PERMISSION;
    }
    
    @Override
    public String getUsage() {
        return "[player]";
    }
    
}

@@ -342,254 +342,133 @@
 sts.
-BlockBreakQuest;%0D%0Aimport de.iani.cubequest.quests.BlockPlaceQuest;%0D%0Aimport de.iani.cubequest.quests.ComplexQuest;%0D%0Aimport de.iani.cubequest.quests.FishingQuest;%0D%0Aimport de.iani.cubequest.quests.KillEntitiesQuest;%0D%0Aimport de.iani.cubequest.quests.
+ComplexQuest;%0D%0Aimport de.iani.cubequest.quests.EntityTypesAndAmountQuest;%0D%0Aimport de.iani.cubequest.quests.MaterialsAndAmount
 Ques
@@ -503,28 +503,16 @@
 .quests.
-TameEntities
 Quest;%0D%0A
@@ -3871,508 +3871,132 @@
 eof 
-BlockBreakQuest) %7B%0D%0A                    possibilities = ChatAndTextUtil.multipleMaterialsString(((BlockBreakQuest) inner).getTypes());%0D%0A                %7D else if (inner instanceof BlockPlaceQuest %7C%7C inner instanceof FishingQuest) %7B%0D%0A                    possibilities = ChatAndTextUtil.multipleMaterialsString(((BlockPlaceQuest) inner).getTypes());%0D%0A                %7D else if (inner instanceof KillEntitiesQuest) %7B%0D%0A                    possibilities = ChatAndTextUtil.multipleMobsString(((KillEntities
+MaterialsAndAmountQuest) %7B%0D%0A                    possibilities = ChatAndTextUtil.multipleMaterialsString(((MaterialsAndAmount
 Ques
@@ -4063,28 +4063,36 @@
 tanceof 
-Tame
 Entit
-ies
+yTypesAndAmount
 Quest) %7B
@@ -4170,20 +4170,28 @@
 g(((
-Tame
 Entit
-ies
+yTypesAndAmount
 Ques

Fix ClassCastException.