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.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import java.text.DecimalFormat;
import java.util.*;

public class MinerMinion extends Minion {

	private static Set<Material> VALID_BLOCKS = new HashSet<>();

	static {
		VALID_BLOCKS.add(Material.STONE);
		VALID_BLOCKS.add(Material.COBBLESTONE);
		for (Material mat : Material.values()) {
			if (!mat.name().toLowerCase().contains("ore")) continue;
			VALID_BLOCKS.add(mat);
		}
	}

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

	public MinerMinion(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 getBlockLimit(final int level) {
		return getSection().getInt("Levels." + level + ".BlockLimit", 1);
	}

	@Override
	public void tick() {
		if (getEnergy() < getEnergyPerUse(getLevel())) return;
		Block block = getLocation().getBlock();
		for (BlockFace direction: new BlockFace[] {BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}) {
			if (!VALID_BLOCKS.contains(block.getRelative(direction).getType())) continue;
			block = block.getRelative(direction);
			final Collection<ItemStack> drops = block.getDrops();
			block.setType(Material.AIR);

			if (!drops.isEmpty()) consumeEnergy(getEnergyPerUse(getLevel()));

			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(item -> getLocation().getWorld().dropItemNaturally(getLocation(), item));
			}
			break;
		}
		/*getLinkedBlocks().stream().filter(block -> !(block.getState() instanceof InventoryHolder)).filter(block -> VALID_BLOCKS.contains(block.getType())).limit(getBlockLimit(getLevel())).forEachOrdered(block -> {
			final Collection<ItemStack> drops = block.getDrops();
			block.setType(Material.AIR);
			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(item -> getLocation().getWorld().dropItemNaturally(getLocation(), item));
			}
		});*/
	}

	@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("%blocklimit%", String.valueOf(getBlockLimit(getLevel())));
	}

}
