package top.r3944realms.lib39.api.callback;

import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;

/**
 * Fabric版的铁砧更新事件，对应Forge的AnvilUpdateEvent
 */
public class AnvilUpdateCallback {

    /**
     * 铁砧更新事件接口
     */
    @FunctionalInterface
    public interface AnvilUpdate {
        /**
         * 当铁砧内容改变时调用
         *
         * @param left       左侧输入槽的物品
         * @param right      右侧输入槽的物品
         * @param outputSlot 输出槽的物品
         * @param name       输入的名字
         * @param baseCost   基础花费
         * @param player     玩家
         * @return AnvilUpdateResult 包含处理结果，如果返回null则继续默认处理
         */
        AnvilUpdateResult onAnvilUpdate(ItemStack left, ItemStack right, ItemStack outputSlot,
                                        String name, int baseCost, Player player);
    }

    /**
     * 铁砧更新结果
     */
    public record AnvilUpdateResult(ItemStack output, int cost, int materialCost, boolean cancel) {

        /**
         * Cancelled anvil update result.
         *
         * @return the anvil update result
         */
        public static AnvilUpdateResult cancelled() {
                return new AnvilUpdateResult(ItemStack.EMPTY, 0, 0, true);
            }

        /**
         * Passed anvil update result.
         *
         * @return the anvil update result
         */
        public static AnvilUpdateResult passed() {
                return new AnvilUpdateResult(ItemStack.EMPTY, 0, 0, false);
            }

        /**
         * With output anvil update result.
         *
         * @param output       the output
         * @param cost         the cost
         * @param materialCost the material cost
         * @return the anvil update result
         */
        public static AnvilUpdateResult withOutput(ItemStack output, int cost, int materialCost) {
                return new AnvilUpdateResult(output, cost, materialCost, false);
            }

        /**
         * Should override boolean.
         *
         * @return the boolean
         */
        public boolean shouldOverride() {
            return !output.isEmpty();
        }
    }

    /**
     * The constant EVENT.
     */
    public static final Event<AnvilUpdate> EVENT = EventFactory.createArrayBacked(
            AnvilUpdate.class,
            (listeners) -> (left, right, outputSlot, name, baseCost, player) -> {
                for (AnvilUpdate listener : listeners) {
                    AnvilUpdateResult result = listener.onAnvilUpdate(left, right, outputSlot, name, baseCost, player);
                    if (result != null) {
                        if (result.cancel()) {
                            return result; // 取消事件
                        }
                        if (result.shouldOverride()) {
                            return result; // 返回自定义结果
                        }
                    }
                }
                return AnvilUpdateResult.passed(); // 继续默认处理
            }
    );
}