package me.minidigger.voxelgameslib.components.inventory;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import javax.inject.Inject;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

public abstract class BaseInventory {

    @Inject
    private InventoryHandler inventoryHandler;

    private UUID identifier;
    private Player player;
    protected Inventory bukkitInventory;
    protected String title;
    protected int size;
    protected Consumer<Player> openInventoryAction = (p) -> {
    };
    protected Consumer<Player> closeInventoryAction = (p) -> {
    };
    protected Map<ItemStack, BiConsumer<ItemStack, InventoryClickEvent>> clickActions = new HashMap<>();

    /**
     * Creates a new BaseInventory
     *
     * @param player the player to create the inventory on
     * @param title  title of new inventory
     * @param size   size/capacity of new inventory
     */
    public BaseInventory(Player player, String title, int size) {
        this.identifier = player.getUniqueId();
        this.player = player;
        this.title = title;
        this.size = Math.min(54, (int) (Math.ceil((double) size / 9)) * 9);

        bukkitInventory = Bukkit.createInventory(null, size, title);
    }

    /**
     * <p>Get the inventory's identifier</p>
     *
     * <p>This should be the same as the UUID of the player opening it.</p>
     *
     * @return the identifier (generally player UUID)
     */
    public UUID getIdentifier() {
        return identifier;
    }

    public Inventory getBukkitInventory() {
        return bukkitInventory;
    }

    /**
     * Set the action to be performed when the inventory opens
     *
     * @param action the action to perform
     */
    public void setOpenAction(Consumer<Player> action) {
        openInventoryAction = action;
    }

    /**
     * Set the action to be performed when the inventory closes
     *
     * @param action the action to perform
     */
    public void setCloseAction(Consumer<Player> action) {
        closeInventoryAction = action;
    }

    /**
     * Add new actions to be performed when a player clicks an ItemStack in an inventory
     *
     * @param is     itemstack to create the click action for
     * @param action the action to perform
     */
    public void addClickAction(ItemStack is, BiConsumer<ItemStack, InventoryClickEvent> action) {
        clickActions.put(is, action);
    }

    /**
     * Perform the defined action when an inventory is opened by a player
     */
    public void onOpen() {
        openInventoryAction.accept(player);
    }

    /**
     * Perform the defined action when an inventory is opened by a player
     */
    public void onClose() {
        closeInventoryAction.accept(player);
    }

    /**
     * Perform the defined action when a certain ItemStack is clicked in an inventory
     *
     * @param is clicked item
     * @param e  click event
     */
    public void onClick(ItemStack is, InventoryClickEvent e) {
        if (clickActions.containsKey(is)) {
            clickActions.get(is).accept(is, e);
        }
    }

    /**
     * Make the player close the inventory
     *
     * @param player player to close inventory for
     */
    public void close(Player player) {
        player.closeInventory();
    }
}

@@ -462,69 +462,8 @@
 y %7B%0A
-%0A    @Inject%0A    private InventoryHandler inventoryHandler;%0A%0A
     
@@ -1270,10 +1270,9 @@
 min(
-54
+9
 , (i
@@ -1368,16 +1368,21 @@
 y(null, 
+this.
 size, ti
@@ -1663,24 +1663,171 @@
 ier;%0A    %7D%0A%0A
+    /**%0A     * Returns the inventory holder%0A     *%0A     * @return the player%0A     */%0A    public Player getPlayer() %7B%0A        return player;%0A    %7D%0A%0A
     public I
@@ -3431,21 +3431,20 @@
  player 
-close
+open
  the inv
@@ -3460,37 +3460,120 @@
    *
+/
 %0A    
- * @param player
+public void open() %7B%0A        player.openInventory(bukkitInventory);%0A    %7D%0A%0A    /**%0A     * Make the
  player 
 to c
@@ -3572,17 +3572,18 @@
 yer 
-to 
 close 
+the 
 inve
@@ -3587,20 +3587,16 @@
 nventory
- for
 %0A     */
@@ -3618,29 +3618,16 @@
 d close(
-Player player
 ) %7B%0A    

fix a bug where the rounding of inventory size wasn't applied because it was using a local variable