package de.hessj.betterhoppers;

import java.io.IOException;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;

import de.hessj.helper.Helper;
import net.kyori.adventure.text.Component;

public class BetterHopperListener implements Listener {
    Component inventoryname = Component.text("Items zum filtern:");
    @EventHandler
    public void onBlockPlace(BlockPlaceEvent e) {
        if (App.main.checkFilterHopper(e.getItemInHand())) {
            Location loc = e.getBlockPlaced().getLocation();
            InventoryHolder invh = (InventoryHolder) e.getBlockPlaced().getState();
            Inventory newHopperinv = Bukkit.createInventory(invh, 9);
            App.main.getConfig()
                    .set("hoppers." + loc.getWorld().getName() + "." + loc.getBlockX() + "~"
                            + loc.getBlockY() + "~" + loc.getBlockZ() + ".filterinventory",
                            Helper.itemStackArrayToBase64(newHopperinv.getContents()));
            App.main.saveConfig();
        }

    }

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent e) throws IllegalArgumentException, IOException {
    
        if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.AIR && e.getAction().equals(Action.RIGHT_CLICK_BLOCK) && e.getPlayer().isSneaking()
                && e.getClickedBlock().getType().equals(Material.HOPPER)) {
            e.setCancelled(true);
            if (App.main.getConfig().getConfigurationSection("hoppers") != null) {

                String w = e.getClickedBlock().getWorld().getName();
                Location loc = e.getClickedBlock().getLocation();

                if (App.main.getConfig().get("hoppers." + w + "." + loc.getBlockX() + "~" + loc.getBlockY() + "~"
                        + loc.getBlockZ()) != null) {
                    InventoryHolder invh = (InventoryHolder) e.getClickedBlock().getState();

                    Inventory hopperinv = Bukkit.createInventory(invh, 9, inventoryname);
                    hopperinv.setContents(Helper.itemStackArrayFromBase64(
                            App.main.getConfig().getString("hoppers." + w + "." + loc.getBlockX() + "~"
                                    + loc.getBlockY() + "~" + loc.getBlockZ() + ".filterinventory")));
                    e.getPlayer().openInventory(hopperinv);
                }

            }
        }
    }

    @EventHandler
    public void onInvClose(InventoryCloseEvent e) {
        if (e.getView().title().equals(inventoryname)) {
            Inventory invtosave = e.getInventory();
            InventoryHolder invholder = e.getInventory().getHolder();
            Location loc = invholder.getInventory().getLocation();
            App.main.getConfig()
                    .set("hoppers." + loc.getWorld().getName() + "." + loc.getBlockX() + "~"
                            + loc.getBlockY() + "~" + loc.getBlockZ() + ".filterinventory",
                            Helper.itemStackArrayToBase64(invtosave.getContents()));
            App.main.saveConfig();
        }
    }

    @EventHandler
    public void onInventoryClick(InventoryClickEvent e) {
        Inventory top = e.getView().getTopInventory();
        Inventory bottom = e.getView().getBottomInventory();
        if (e.getView().title().equals(inventoryname)) {
            e.setCancelled(true);
            if (e.getClickedInventory() == top) {
                if (top.getItem(e.getSlot()) != null) {
                    top.setItem(e.getSlot(), null);
                }
            } else if (e.getClickedInventory() == bottom) {
                if (bottom.getItem(e.getSlot()) != null) {
                    if (top.firstEmpty() != -1) {
                        ItemStack is = bottom.getItem(e.getSlot()).clone();
                        is.setAmount(1);
                        if (!top.containsAtLeast(is, 1)) {// if top hat das item noch nicht dann nur adden

                            top.addItem(is);
                        }
                    }
                }
            }

        }
    }

    @EventHandler
    public void onBlockBreak(BlockBreakEvent e) {
        if (e.getPlayer() != null && e.getPlayer().getGameMode() == GameMode.SURVIVAL) {
            if (e.getBlock().getType() == Material.HOPPER) {
                Location loc = e.getBlock().getLocation();
                if (App.main.getConfig()
                        .contains("hoppers." + loc.getWorld().getName() + "." + loc.getBlockX() + "~"
                                + loc.getBlockY() + "~" + loc.getBlockZ() + ".filterinventory")) {

                    App.main.getConfig().getConfigurationSection("hoppers")
                            .set(loc.getWorld().getName() + "." + loc.getBlockX() + "~"
                                    + loc.getBlockY() + "~" + loc.getBlockZ(), null);
                    App.main.saveConfig();
                    e.setCancelled(true);
                    e.getBlock().setType(Material.AIR);
                    e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(),
                            new ItemStack(Material.HOPPER, 1));
                    e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(),
                            new ItemStack(Material.COMPARATOR, 1));
                }
            }
        }
    }

    @EventHandler
    public void onBlockBreak(EntityExplodeEvent e) {
        for (Block b : e.blockList()) {
            if (b.getType() == Material.HOPPER) {
                Location loc = b.getLocation();
                if (App.main.getConfig()
                        .contains("hoppers." + loc.getWorld().getName() + "." + loc.getBlockX() + "~"
                                + loc.getBlockY() + "~" + loc.getBlockZ() + ".filterinventory")) {
                    App.main.getConfig().getConfigurationSection("hoppers")
                            .set(loc.getWorld().getName() + "." + loc.getBlockX() + "~"
                                    + loc.getBlockY() + "~" + loc.getBlockZ(), null);
                    App.main.saveConfig();
                    b.setType(Material.AIR);
                    b.getWorld().dropItemNaturally(loc, new ItemStack(Material.HOPPER, 1));
                    b.getWorld().dropItemNaturally(loc, new ItemStack(Material.COMPARATOR, 1));
                }
            }
        }
    }

    @EventHandler
    public void onInventoryPickupEvent(InventoryPickupItemEvent event) throws IllegalArgumentException, IOException {
        Inventory dest = event.getInventory();
        Location loc = dest.getLocation();
        if (App.main.getConfig()
                .contains("hoppers." + loc.getWorld().getName() + "." + loc.getBlockX() + "~"
                        + loc.getBlockY() + "~" + loc.getBlockZ() + ".filterinventory")) {

            InventoryHolder invh = (InventoryHolder) event.getInventory().getLocation().getWorld()
                    .getBlockAt(event.getInventory().getLocation()).getState();

            Inventory hopperinv = Bukkit.createInventory(invh, 9, inventoryname);
            hopperinv.setContents(Helper.itemStackArrayFromBase64(
                    App.main.getConfig().getString("hoppers." + loc.getWorld().getName() + "." + loc.getBlockX() + "~"
                            + loc.getBlockY() + "~" + loc.getBlockZ() + ".filterinventory")));

            if (!checkSimilarity(event.getItem().getItemStack().getType(), hopperinv)) {

                event.setCancelled(true);
            }
        }
    }


    







    


    @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled=true)
    public void onItemMove(InventoryMoveItemEvent e) throws IllegalArgumentException, IOException {
        Inventory dest = e.getDestination();
        if(dest.getLocation() != null){
        Location destLoc = dest.getLocation();
		Inventory source = e.getSource();



        if (App.main.getConfig()
        .contains("hoppers." + destLoc.getWorld().getName() + "." + destLoc.getBlockX() + "~"
                + destLoc.getBlockY() + "~" + destLoc.getBlockZ() + ".filterinventory")) {


                    InventoryHolder invh = (InventoryHolder) destLoc.getWorld().getBlockAt(destLoc).getState();
                    Inventory filterInv = Bukkit.createInventory(invh, 9, inventoryname);

                  



                    filterInv.setContents(Helper.itemStackArrayFromBase64(
                            App.main.getConfig().getString("hoppers." + destLoc.getWorld().getName() + "." + destLoc.getBlockX() + "~"
                                    + destLoc.getBlockY() + "~" + destLoc.getBlockZ() + ".filterinventory")));



                                    if(!filterInv.contains(e.getItem().getType())){
                                        e.setCancelled(true);
                                     
                                            for (int slot = 1; slot < source.getSize(); slot++) {
                                                if(source.getItem(slot) != null){
                                                    ItemStack temp = source.getItem(slot).clone();
                                                    temp.setAmount(1);
                                                    if(filterInv.containsAtLeast(temp,1)){
                                                        moveItem(source, slot, dest);
                                                        return;
                                                    }
                                                    
                                                }
                                               
                                            }
                                        
                                    }
 
}}
    }



public void moveItem(Inventory source, Integer slot, Inventory dest){
    Boolean freespace = false;
    ItemStack i = source.getItem(slot);








    for (ItemStack is : dest.getContents()) {
        if (is != null) {
            if (is.isSimilar(i)) {
      
                if (is.getAmount() == is.getMaxStackSize()) {
                    // nix tun
                } else {
                    is.setAmount(is.getAmount()+1);
                    i.setAmount(i.getAmount()-1);
                    return;
                }

            }
        } else {
            freespace = true;
        }

    }













    if (freespace) {
        ItemStack iClone = i.clone();
        iClone.setAmount(1);
        dest.setItem(dest.firstEmpty(), iClone);
        i.setAmount(i.getAmount()-1);
    }
}










    public static boolean checkSimilarity(Material material, Inventory inv) {

        for (ItemStack itemstack : inv.getContents()) {
            if (itemstack == null) {
                continue;
            }
            if (material.equals(itemstack.getType())) {
                return true;
            }
        }

        return false;
    }

}
