package top.r3944realms.lib39.core.event;

import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.item.ItemProperties;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
import net.neoforged.neoforge.client.event.RegisterShadersEvent;
import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions;
import net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent;
import net.neoforged.neoforge.event.level.LevelEvent;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.client.model.DollModel;
import top.r3944realms.lib39.client.renderer.block.DollBlockEntityRenderer;
import top.r3944realms.lib39.client.shader.Lib39Shaders;
import top.r3944realms.lib39.content.item.NeoForgeDollItem;
import top.r3944realms.lib39.core.register.Lib39BlockEntities;
import top.r3944realms.lib39.core.register.Lib39Items;
import top.r3944realms.lib39.util.ILevelHelper;

import java.io.IOException;

/**
 * The type Client handler.
 */
public class ClientEventHandler {
    /**
     * The type Mod.
     */
    @EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD, modid = Lib39.MOD_ID)
    public static class Mod extends ClientEventHandler {
        /**
         * On register shaders.
         *
         * @param event the event
         * @throws IOException the io exception
         */
        @SubscribeEvent
        public static void onRegisterShaders(@NotNull RegisterShadersEvent event) throws IOException {
            event.registerShader(new ShaderInstance(event.getResourceProvider(), Lib39.rl("ring"), DefaultVertexFormat.POSITION_COLOR), Lib39Shaders::setRingShader);
            event.registerShader(new ShaderInstance(event.getResourceProvider(), Lib39.rl("selection"), DefaultVertexFormat.POSITION_COLOR), Lib39Shaders::setSelectionShader);
        }

        /**
         * On register renderer.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void onRegisterRenderer (EntityRenderersEvent.@NotNull RegisterRenderers event) {
            event.registerBlockEntityRenderer(Lib39BlockEntities.DOLL_BLOCK_ENTITY.get(),DollBlockEntityRenderer::new);
        }

        /**
         * Register layer definitions.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void registerLayerDefinitions(EntityRenderersEvent.@NotNull RegisterLayerDefinitions event) {
            event.registerLayerDefinition(DollModel.LAYER_LOCATION, DollModel::createBodyLayer);
        }

        /**
         * On register client ex.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void onRegisterClientEx (@NotNull RegisterClientExtensionsEvent event) {
           event.registerItem(NeoForgeDollItem.ClientOpt.getExtensions(), Lib39Items.DOLL.get());
        }

    }

    /**
     * The type Game.
     */
    @EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.GAME, modid = Lib39.MOD_ID)
    public static class Game extends ClientEventHandler {
        /**
         * Register layer definitions.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void obClientUnload(LevelEvent.@NotNull Load event) {
           if (event.getLevel() != null && event.getLevel() instanceof ClientLevel level) {
               ILevelHelper.LevelHelper.CLIENT.setLevel(level);
           }
        }

        /**
         * Register layer definitions.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void obClientUnload(LevelEvent.@NotNull Unload event) {
            if (event.getLevel() != null && event.getLevel() instanceof ClientLevel level) {
                ILevelHelper.LevelHelper.CLIENT.setLevel(null);
            }
        }
    }

}
