package net.halbear.aotg.registries;

import net.halbear.aotg.AgeoftheGods;
import net.halbear.aotg.custom.blocks.AlloyFurnace.AlloyFurnaceGUI;
import net.halbear.aotg.custom.blocks.Forge.ForgeWorkbenchGUI;
import net.halbear.aotg.utility.Networking.MenuStateUpdate;
import net.minecraft.client.Minecraft;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.inventory.Slot;
import net.neoforged.neoforge.client.network.ClientPacketDistributor;
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension;
import net.neoforged.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;

import java.util.Map;

public class ModMenus {
    public static DeferredRegister<MenuType<?>> MENUS =
            DeferredRegister.create(BuiltInRegistries.MENU, AgeoftheGods.MODID);

    public static final DeferredHolder<MenuType<?>, MenuType<AlloyFurnaceGUI>> ALLOY_FURNACE_GUI =
            MENUS.register("alloy_furnace_gui", () -> IMenuTypeExtension.create(AlloyFurnaceGUI::new));

    public static final DeferredHolder<MenuType<?>, MenuType<ForgeWorkbenchGUI>> FORGE_WORKBENCH_GUI =
            MENUS.register("forge_workbench", () -> IMenuTypeExtension.create(ForgeWorkbenchGUI::new));


    public interface MenuAccessor {
        Map<String, Object> getMenuState();

        Map<Integer, Slot> getSlots();

        default void sendMenuStateUpdate(Player player, int elementType, String name, Object elementState, boolean needClientUpdate) {
            getMenuState().put(elementType + ":" + name, elementState);
            if (player instanceof ServerPlayer serverPlayer) {
                PacketDistributor.sendToPlayer(serverPlayer, new MenuStateUpdate(elementType, name, elementState));
            } else if (player.level().isClientSide()) {
                if (Minecraft.getInstance().screen instanceof ModScreens.ScreenAccessor accessor && needClientUpdate)
                    accessor.updateMenuState(elementType, name, elementState);
                ClientPacketDistributor.sendToServer(new MenuStateUpdate(elementType, name, elementState));
            }
        }

        default <T> T getMenuState(int elementType, String name, T defaultValue) {
            try {
                return (T) getMenuState().getOrDefault(elementType + ":" + name, defaultValue);
            } catch (ClassCastException e) {
                return defaultValue;
            }
        }
    }


}
