package io.badgeup.sponge.award;

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

import javax.validation.constraints.Min;

import org.hibernate.validator.constraints.NotBlank;
import org.json.JSONObject;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.meta.ItemEnchantment;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.item.Enchantment;
import org.spongepowered.api.item.ItemType;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.text.Text;

import io.badgeup.sponge.BadgeUpSponge;
import io.badgeup.sponge.Util;

public class ItemAward extends Award {

	@NotBlank
	private final String typeId;

	@Min(value = 1)
	private final int quantity;

	public ItemAward(BadgeUpSponge plugin, JSONObject award) {
		super(plugin, award);
		this.typeId = Util.safeGetString(data, "itemType").orElse("");
		this.quantity = Util.safeGetInt(data, "quantity").orElse(1);
	}

	@Override
	public boolean awardPlayer(Player player) {
		final Optional<ItemType> optType = Sponge.getRegistry().getType(ItemType.class, typeId);
		if (!optType.isPresent()) {
			plugin.getLogger().error("Could not retrieve ItemType with ID " + typeId + ". Aborting.");
			return false;
		}

		final ItemStack.Builder builder = Sponge.getRegistry().createBuilder(ItemStack.Builder.class)
				.itemType(optType.get()).quantity(this.quantity);

		final Optional<Text> displayNameOpt = Util.deserializeText(Util.safeGet(data, "displayName").orElse(null));
		if (displayNameOpt.isPresent()) {
			builder.add(Keys.DISPLAY_NAME, displayNameOpt.get());
		}

		final Optional<List<Object>> rawLoreOpt = Util.safeGetList(data, "lore");
		if (rawLoreOpt.isPresent()) {
			List<Text> lore = new ArrayList<>();
			for (Object rawLine : rawLoreOpt.get()) {
				Util.deserializeText(rawLine).ifPresent(lore::add);
			}
			builder.add(Keys.ITEM_LORE, lore);
		}

		final Optional<List<Object>> rawEnchantmentsOpt = Util.safeGetList(data, "enchantments");
		if (rawEnchantmentsOpt.isPresent()) {
			List<ItemEnchantment> enchantments = new ArrayList<>();
			for (Object obj : rawEnchantmentsOpt.get()) {
				if (!(obj instanceof JSONObject)) {
					plugin.getLogger().error("Item enchantment entry is not a JSON object. Skipping enchantment.");
					continue;
				}
				JSONObject enchantmentInfo = (JSONObject) obj;
				Optional<String> enchantmentIDOpt = Util.safeGetString(enchantmentInfo, "id");
				if (!enchantmentIDOpt.isPresent()) {
					plugin.getLogger().error("No enchantment ID specified. Skipping enchantment.");
					continue;
				}
				Optional<Enchantment> enchantmentOpt = Sponge.getRegistry().getType(Enchantment.class,
						enchantmentIDOpt.get());
				if (!enchantmentOpt.isPresent()) {
					plugin.getLogger()
							.error("Could not find enchantment with ID " + enchantmentIDOpt.get() + ". Skipping enchantment.");
					continue;
				}
				Optional<Integer> enchantLevelOpt = Util.safeGetInt(enchantmentInfo, "level");
				if (enchantLevelOpt.isPresent()) {
					plugin.getLogger().error("No enchantment level specified. Skipping enchantment.");
					continue;
				}
				int enchantLevel = enchantLevelOpt.get();
				if (enchantLevel <= 0) {
					plugin.getLogger().error("Invalid enchantment level of " + enchantLevel + ". Skipping enchantment.");
					continue;
				}
				enchantments.add(new ItemEnchantment(enchantmentOpt.get(), enchantLevel));
			}
			builder.add(Keys.ITEM_ENCHANTMENTS, enchantments);
		}
		
		final Optional<Integer> itemDurabilityOpt = Util.safeGetInt(data, "durability");
		if(itemDurabilityOpt.isPresent()) {
			builder.add(Keys.ITEM_DURABILITY, itemDurabilityOpt.get());
		}

		// TODO color (stained glass, wool)

		ItemStack item = builder.build();
		player.getInventory().offer(item);
		return true;
	}

}

@@ -3056,32 +3056,33 @@
 evel%22);%0A%09%09%09%09if (
+!
 enchantLevelOpt.
@@ -3484,32 +3484,66 @@
 ntLevel));%0A%09%09%09%7D%0A
+%09%09%09if(!enchantments.isEmpty()) %7B%0A%09
 %09%09%09builder.add(K
@@ -3580,16 +3580,21 @@
 ments);%0A
+%09%09%09%7D%0A
 %09%09%7D%0A%09%09%0A%09

Fix minor issues w/ enchantments