package top.r3944realms.lib39.example.core.event;

import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.entity.vehicle.Minecart;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.event.lifecycle.FMLConstructModEvent;
import net.neoforged.neoforge.capabilities.EntityCapability;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import top.r3944realms.lib39.Lib39NeoForge;
import top.r3944realms.lib39.api.event.SyncManagerRegisterEvent;
import top.r3944realms.lib39.core.compat.ICompatManager;
import top.r3944realms.lib39.core.event.CommonEventHandler;
import top.r3944realms.lib39.core.sync.CachedSyncManager;
import top.r3944realms.lib39.example.compat.Lib39Compat;
import top.r3944realms.lib39.example.compat.Lib39CompatManager;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.ExCapabilityHandler;
import top.r3944realms.lib39.example.content.data.TestSyncData;
import top.r3944realms.lib39.example.core.network.ExNetworkHandler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * The type Common handler.
 */
public class ExCommonEventHandler {
    /**
     * The type Game.
     */
    @SuppressWarnings("unused")

    public static class Game extends ExCommonEventHandler {

        /**
         * On register sync.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void onRegisterSync (SyncManagerRegisterEvent event) {
            event.registerSyncManager(
                    TestSyncData.ID,
                    new CachedSyncManager<>() {
                        private final Map<EntityCapability<AbstractedTestSyncData, Void>, AbstractedTestSyncData> syncDataMap = new ConcurrentHashMap<>();
                        @Override
                        public Map<EntityCapability<AbstractedTestSyncData, Void>, AbstractedTestSyncData> getSyncMap() {
                            return syncDataMap;
                        }
                    },
                    ExCapabilityHandler.TEST_CAP

            );
            event.addAllowEntityClass(TestSyncData.ID, LivingEntity.class, Boat.class, Minecart.class);
        }

    }


    /**
     * The type Mod.
     */
    public static class Mod extends ExCommonEventHandler {

        /**
         * Gets compat manager.
         *
         * @return the compat manager
         */
        public static ICompatManager getOrCreateCompatManager() {
            if (compatManager == null) {
                synchronized (CommonEventHandler.Mod.class) {
                    if (compatManager == null) {
                        compatManager = new Lib39CompatManager("compat", Lib39NeoForge.modEventBus, NeoForge.EVENT_BUS);
                    }
                }
            }
            return compatManager;
        }

        /**
         * The Compat manager.
         */
        static volatile ICompatManager compatManager;


        /**
         * On construct mod.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void onConstructMod(FMLConstructModEvent event) {
            event.enqueueWork(() -> {
                ICompatManager orCreateCompatManager = Mod.getOrCreateCompatManager();
                orCreateCompatManager
                        .registerCompat(Lib39Compat.ID, Lib39Compat.INSTANCE);
                orCreateCompatManager.initialize();
            });
        }

        /**
         * Register capability.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void registerCapability(RegisterCapabilitiesEvent event) {
            ExCapabilityHandler.registerCapability(event);
        }

        /**
         * On register payload.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void onRegisterPayload (RegisterPayloadHandlersEvent event) {
            ExNetworkHandler.register(event);
        }

    }
}
