/*
 *  Copyright 2025-2026 R3944Realms
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package top.r3944realms.eroticdungeongame.core.event;

import com.google.common.collect.ImmutableList;
import net.minecraft.client.RecipeBookCategories;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.npc.VillagerTrades;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RegisterRecipeBookCategoriesEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
import net.minecraftforge.data.event.GatherDataEvent;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLConstructModEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import top.r3944realms.eroticdungeongame.EroticDungeon;
import top.r3944realms.eroticdungeongame.api.EroticDungeonGameApi;
import top.r3944realms.eroticdungeongame.content.EDGVillagerTrades;
import top.r3944realms.eroticdungeongame.content.capability.DungeonDataSyncManager;
import top.r3944realms.eroticdungeongame.content.command.EDGCommand;
import top.r3944realms.eroticdungeongame.content.recipe.DungeonCraftingBookCategory;
import top.r3944realms.eroticdungeongame.content.recipe.DungeonRecipe;
import top.r3944realms.eroticdungeongame.content.recipe.EDGRecipeBookTypes;
import top.r3944realms.eroticdungeongame.content.recipe.EDGRecipeTypeCategories;
import top.r3944realms.eroticdungeongame.core.compat.*;
import top.r3944realms.eroticdungeongame.core.register.EDGCapabilities;
import top.r3944realms.eroticdungeongame.core.register.EDGRecipeTypes;
import top.r3944realms.eroticdungeongame.datagen.EDGDataGenEvent;
import top.r3944realms.lib39.api.event.SyncManagerRegisterEvent;
import top.r3944realms.lib39.core.compat.CompatManager;
import top.r3944realms.lib39.core.event.CommonEventHandler;

import java.util.List;

public class CommonHandler {
    @net.minecraftforge.fml.common.Mod.EventBusSubscriber(modid = EroticDungeon.MOD_ID, bus = net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus.FORGE)
    public static class Game extends CommonHandler {
        public static DungeonDataSyncManager dungeonDataSyncManager;
        public static ResourceLocation DUNGEON_SYNC = EroticDungeon.rl("dungeon_sync");
        @SubscribeEvent
        public static void attachCapability(AttachCapabilitiesEvent<?> event) {
            EDGCapabilities.attachCapability(event);
        }

        @SubscribeEvent
        public static void syncCapabilities(SyncManagerRegisterEvent event) {
            dungeonDataSyncManager = new DungeonDataSyncManager();
            event.registerSyncManager(DUNGEON_SYNC, dungeonDataSyncManager, EroticDungeonGameApi.PLAYER_DUNGEON_DATA_CAP);
        }
        private static char ticks = 0;
        @SubscribeEvent
        public static void onPlayerTick (TickEvent.PlayerTickEvent event) {
            Player player = event.player;
            ticks++;

            if (ticks % 2 == 0) {
                DungeonDataSyncManager.tick(player);
            }
        }

        @SubscribeEvent
        public static void onPlayerLogin (PlayerEvent.PlayerLoggedInEvent event) {
            Player player = event.getEntity();
            if (player == null || player.level().isClientSide()) return;
            DungeonDataSyncManager.login(player);
        }

        @SubscribeEvent
        public static void onPlayerLogout (PlayerEvent.PlayerLoggedOutEvent event) {
            Player player = event.getEntity();
            if (player == null || player.level().isClientSide()) return;
            DungeonDataSyncManager.logout(player);
        }
        @SubscribeEvent
        public static void onCommandRegister(RegisterCommandsEvent event) {
            EDGCommand command = new EDGCommand(event);
        }
    }
    @net.minecraftforge.fml.common.Mod.EventBusSubscriber(modid = EroticDungeon.MOD_ID, bus = net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus.MOD)
    public static class Mod extends CommonHandler {
        public static final IEventBus EVENT_BUS = FMLJavaModLoadingContext.get().getModEventBus();
        /**
         * Gets compat manager.
         *
         * @return the compat manager
         */
        public static CompatManager getOrCreateCompatManager() {
            if (compatManager == null) {
                synchronized (CommonEventHandler.Mod.class) {
                    if (compatManager == null) {
                        compatManager = new EDGCompatManager("compat", EVENT_BUS, MinecraftForge.EVENT_BUS);
                    }
                }
            }
            return compatManager;
        }

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


        /**
         * On construct mod.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void onConstructMod(FMLConstructModEvent event) {
            event.enqueueWork(() -> {
                CompatManager orCreateCompatManager = Mod.getOrCreateCompatManager();
                orCreateCompatManager
                        .registerCompat(CarryOnCompat.ID, CarryOnCompat.INSTANCE);
                orCreateCompatManager
                        .registerCompat(SuperLeadRopeCompat.ID, SuperLeadRopeCompat.INSTANCE);
                orCreateCompatManager
                        .registerCompat(EmoteCraftCompat.ID, EmoteCraftCompat.INSTANCE);
                orCreateCompatManager
                        .registerCompat(TouhouLittleMaidCompat.ID, TouhouLittleMaidCompat.INSTANCE);
               DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
                           orCreateCompatManager
                                   .registerCompat(FreecamCompat.ID, FreecamCompat.INSTANCE);
                           orCreateCompatManager
                                   .registerCompat(RealCameraCompat.ID, RealCameraCompat.INSTANCE);
                           orCreateCompatManager
                                   .registerCompat(FirstPersonModelAndRealCameraCompat.ID, FirstPersonModelAndRealCameraCompat.INSTANCE);
                       }
               );
               orCreateCompatManager.initialize();
            });
        }
        @SubscribeEvent
        public static void onSetUp (FMLCommonSetupEvent event) {
            event.enqueueWork(() -> EDGVillagerTrades.init(VillagerTrades.TRADES));
        }

        @SubscribeEvent
        public static void registerCapability(RegisterCapabilitiesEvent event) {
            EDGCapabilities.registerCapability(event);
        }
        @SubscribeEvent
        public static void gatherData(GatherDataEvent event) {
            EDGDataGenEvent.gatherData(event);
        }
        @SubscribeEvent
        public static void RegisterRecipeBookCategories (RegisterRecipeBookCategoriesEvent event) {
            EDGRecipeTypeCategories.reload();
            event.registerBookCategories(EDGRecipeBookTypes.DUNGEON_CRAFTING, List.of(
                    EDGRecipeTypeCategories.EDG_CRAFTING_SEARCH ,EDGRecipeTypeCategories.WOODEN_DEVICE,
                    EDGRecipeTypeCategories.METAL_DEVICE, EDGRecipeTypeCategories.MISC_THING, EDGRecipeTypeCategories.EQUIPMENT
            ));
            event.registerAggregateCategory(EDGRecipeTypeCategories.EDG_CRAFTING_SEARCH,
                    ImmutableList.of(
                            EDGRecipeTypeCategories.WOODEN_DEVICE,
                            EDGRecipeTypeCategories.METAL_DEVICE,
                            EDGRecipeTypeCategories.EQUIPMENT,
                            EDGRecipeTypeCategories.MISC_THING
                    )
            );
            event.registerRecipeCategoryFinder(EDGRecipeTypes.DUNGEON_CRAFTING.get(), recipe -> {
                if (recipe instanceof DungeonRecipe dungeonRecipe){
                    DungeonCraftingBookCategory category = dungeonRecipe.category();
                    return switch (category) {
                        case WOODEN_DEVICE -> EDGRecipeTypeCategories.WOODEN_DEVICE;
                        case METAL_DEVICE -> EDGRecipeTypeCategories.METAL_DEVICE;
                        case OTHER_DEVICE -> EDGRecipeTypeCategories.OTHER_DEVICE;
                        case EQUIPMENT -> EDGRecipeTypeCategories.EDG_CRAFTING_SEARCH;
                        case MISC -> EDGRecipeTypeCategories.MISC_THING;
                    };
                }
                return RecipeBookCategories.UNKNOWN;
            });
        }

    }
}
