package me.loganb1max.minionsplus.model.minions;

import me.loganb1max.minionsplus.MinionsPlus;
import me.loganb1max.minionsplus.model.Minion;
import me.loganb1max.minionsplus.util.ItemBuilder;
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 FarmerMinion extends Minion {

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

	public FarmerMinion(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());
		for (int y = getLocation().getBlockY() + radius; y > getLocation().getBlockY() - radius; y--) {
			for (int x = getLocation().getBlockX() - radius; x < getLocation().getBlockX() + radius; x++) {
				for (int z = getLocation().getBlockZ() - radius; z < getLocation().getBlockZ() + radius; z++) {
					final Block block = getLocation().getWorld().getBlockAt(x, y, z);
					final List<ItemStack> drops = new ArrayList<>();
					if (block.getType() == Material.POTATO || block.getType() == Material.CARROT || block.getType() == Material.CROPS) {
						if (block.getData() != 7) continue;
						drops.add(ItemBuilder.of(
								block.getType() == Material.CARROT ? Material.CARROT_ITEM
										: block.getType() == Material.POTATO ? Material.POTATO_ITEM : Material.WHEAT
						).build());
						block.setData((byte)0);
					}
					if (block.getType() == Material.CACTUS || block.getType() == Material.SUGAR_CANE_BLOCK) {
						int height = 1;
						final Material type = block.getType();
						Block rel = block;
						while (rel.getRelative(BlockFace.DOWN).getType() == block.getType()) {
							height++;
							rel.setType(Material.AIR);
							rel = rel.getRelative(BlockFace.DOWN);
						}
						if (height > 1) {
							drops.add(ItemBuilder.of(type).amount(height - 1).build());
						}
					}
					if (block.getType() == Material.MELON_BLOCK) {
						drops.addAll(block.getDrops());
						block.setType(Material.AIR);
					}
					if (block.getType() == Material.PUMPKIN) {
						drops.addAll(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));
					}

				}
			}
		}
	}

	@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())));
	}

}
