/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.bausystem.features.inventoryfiller;

import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.linkage.Linked;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Container;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

@Linked
public class InventoryFiller implements Listener {

    @EventHandler
    public void onPlayerDropItem(PlayerDropItemEvent event) {
        if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
        if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return;
        if (!event.getPlayer().isSneaking()) return;
        Block block = event.getPlayer().getTargetBlockExact(5);
        if (block == null) return;
        if (!(block.getState() instanceof Container)) return;
        Container container = (Container) block.getState();
        Inventory inventory = container.getInventory();
        ItemStack itemStack = event.getItemDrop().getItemStack().clone();
        itemStack.setAmount(itemStack.getType().getMaxStackSize());
        event.setCancelled(true);
        for (int i = 0; i < inventory.getSize(); i++) {
            inventory.setItem(i, itemStack);
        }
        BauSystem.MESSAGE.sendPrefixless("CHESTFILLER_FILLED", event.getPlayer(), ChatMessageType.ACTION_BAR);
    }

    /**
     * For MacOS user: https://www.curseforge.com/minecraft/mc-mods/shift-scroll-fix
     */
    @EventHandler
    public void onPlayerItemHeld(PlayerItemHeldEvent event) {
        if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
        if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return;
        if (!event.getPlayer().isSneaking()) return;
        ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand();
        if (itemStack.getType() == Material.AIR) return;
        Block block = event.getPlayer().getTargetBlockExact(5);
        if (block == null) return;
        if (!(block.getState() instanceof Container)) return;
        Container container = (Container) block.getState();
        Inventory inventory = container.getInventory();
        event.setCancelled(true);

        int upperBound = event.getPreviousSlot() + 4;
        if (upperBound > 8) upperBound -= 8;
        int lowerBound = event.getPreviousSlot() - 5;
        if (lowerBound < 0) lowerBound += 8;

        int direction = 0;
        if (event.getPreviousSlot() != 0 && (event.getNewSlot() > event.getPreviousSlot() || (upperBound < event.getPreviousSlot() && event.getNewSlot() < upperBound))) {
            direction = 1;
        } else if (event.getPreviousSlot() == 0 && event.getNewSlot() > upperBound) {
            direction = -1;
        } else if (event.getNewSlot() < event.getPreviousSlot() || (lowerBound > event.getPreviousSlot() && event.getNewSlot() >= lowerBound)) {
            direction = -1;
        } else if (event.getPreviousSlot() == 0) {
            direction = 1;
        }

        int count = 0;
        int emptySlot = -1;
        int filledSlot = -1;
        for (int i = 0; i < inventory.getSize(); i++) {
            ItemStack current = inventory.getItem(i);
            if (current == null) {
                if (emptySlot == -1) emptySlot = i;
                continue;
            }
            if (current.getType() == itemStack.getType()) {
                count += current.getAmount();
                int emptyAmount = itemStack.getType().getMaxStackSize() - current.getAmount();
                if (direction == -1) filledSlot = Math.max(filledSlot, i);
                if (emptyAmount > 0) filledSlot = Math.min(i, filledSlot);
                if (emptyAmount > 0 && filledSlot == -1) filledSlot = i;
            }
        }

        int slotToUse = direction == -1 ? filledSlot : (filledSlot == -1 ? emptySlot : filledSlot);
        if (slotToUse == -1) return;

        ItemStack current = inventory.getItem(slotToUse);
        if (current == null) {
            ItemStack now = itemStack.clone();
            now.setAmount(1);
            inventory.setItem(slotToUse, now);
        } else {
            current.setAmount(current.getAmount() + direction);
        }

        BauSystem.MESSAGE.sendPrefixless("CHESTFILLER_COUNT", event.getPlayer(), ChatMessageType.ACTION_BAR, itemStack.getType(), count + direction);
    }
}
