package me.loganb1max.minionsplus.model.minions;

import me.loganb1max.minionsplus.MinionsPlus;
import me.loganb1max.minionsplus.model.Minion;
import me.loganb1max.minionsplus.util.Replacer;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import java.text.DecimalFormat;
import java.util.*;

public class CollectorMinion extends Minion {

	public CollectorMinion(final UUID owner, final String ownerName) {
		super(
				MinionsPlus.getInstance().getConfig().getConfigurationSection("Collector"),
				owner,
				ownerName
		);
	}

	public CollectorMinion(final UUID owner, final String ownerName, final Location location, final double energy, final int level, final Set<Block> linkedBlocks) {
		this(owner, ownerName);
		setLocation(location);
		setEnergy(energy);
		setLevel(level);
		setLinkedBlocks(linkedBlocks);
		findStand();
	}

	public int getRadius(final int level) {
		return getSection().getInt("Levels." + level + ".Radius", 1);
	}

	@Override
	public void tick() {
		if (getEnergy() < getEnergyPerUse(getLevel())) return;
		final int radius = getRadius(getLevel());
		boolean useEnergy = false;
		for (Entity e : getStand().getNearbyEntities(radius, radius, radius)) {
			if (!(e instanceof Item)) continue;
			if (e.hasMetadata("minionignore")) continue;
			final Item item = (Item) e;
			final List<ItemStack> drops = new ArrayList<>();
			drops.add(item.getItemStack());
			item.remove();
			getLinkedBlocks().stream().filter(b -> b.getState() instanceof InventoryHolder).forEachOrdered(b -> {
				InventoryHolder inv = (InventoryHolder) b.getState();
				final Collection<ItemStack> remaining = inv.getInventory().addItem(drops.toArray(new ItemStack[] {})).values();
				drops.clear();
				drops.addAll(remaining);
			});
			if (!drops.isEmpty()) {
				drops.forEach(i -> {
					Item it = getLocation().getWorld().dropItemNaturally(getLocation(), i);
					it.setMetadata("minionignore", new FixedMetadataValue(MinionsPlus.getInstance(), true));
				});
			}
			useEnergy = true;
		}
		if (useEnergy) consumeEnergy(getEnergyPerUse(getLevel()));
	}

	@Override
	public Replacer getReplacer() {
		final DecimalFormat format = new DecimalFormat("#.#");
		return Replacer.create()
				.add("%level%", String.valueOf(getLevel()))
				.add("%energy%", format.format(getEnergy()))
				.add("%owner%", getOwnerName())
				.add("%radius%", String.valueOf(getRadius(getLevel())));
	}

}
