/*
 * Copyright (c) 2026 盐灯水母
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

package com.remains_cave.event;

import com.remains_cave.RemainsCaveMod;
import com.remains_cave.block.ModBlocks;
import com.remains_cave.block.entity.SkeletonKingRemainsBlockEntity;
import com.remains_cave.block.entity.SkeletonKingSummonBlockEntity;
import com.remains_cave.client.render.block.EmblemRenderer;
import com.remains_cave.client.render.block.TrophyRenderer;
import com.remains_cave.client.render.block.TombDoorRenderer;
import com.remains_cave.item.client.layer.BackItemRenderLayer;
import com.remains_cave.client.render.effect.KingsAuraRenderLayer;
import com.remains_cave.client.screen.QuiverScreen;
import com.remains_cave.entity.AuraBearer;
import com.remains_cave.entity.ModEntities;
import com.remains_cave.entity.client.*;
import com.remains_cave.item.menu.ModMenus;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.client.resources.PlayerSkin;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
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.ModelEvent;
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.bernie.geckolib.animatable.GeoAnimatable;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
import software.bernie.geckolib.renderer.GeoBlockRenderer;
import software.bernie.geckolib.model.GeoModel;

@EventBusSubscriber(modid = RemainsCaveMod.MODID, value = Dist.CLIENT)
public class ClientModEvents {
    private static final Logger LOGGER = LoggerFactory.getLogger("ClientModEvents");

    @SubscribeEvent
    public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) {
        // 实体渲染器
        event.registerEntityRenderer(ModEntities.SKELETON_WARRIOR.get(), SkeletonWarriorRenderer::new);
        event.registerEntityRenderer(ModEntities.TOMB_ARROW.get(), TombArrowRenderer::new);
        event.registerEntityRenderer(ModEntities.SKELETON_ARCHER.get(), SkeletonArcherRenderer::new);
        event.registerEntityRenderer(ModEntities.SKELETON_WARLOCK.get(), SkeletonWarlockRenderer::new);
        event.registerEntityRenderer(ModEntities.RUNE.get(), RuneRenderer::new);
        event.registerEntityRenderer(ModEntities.SKELETON_KING.get(), SkeletonKingRenderer::new);

        // 战利品方块实体渲染器
        event.registerBlockEntityRenderer(ModBlocks.TROPHY_BLOCK_ENTITY.get(), TrophyRenderer::new);

        // 骷髅王遗骸渲染器
        event.registerBlockEntityRenderer(ModBlocks.SKELETON_KING_REMAINS_BLOCK_ENTITY.get(),
                context -> new GeoBlockRenderer<>(new GeoModel<>() {
                    @Override
                    public ResourceLocation getModelResource(SkeletonKingRemainsBlockEntity animatable) {
                        return ResourceLocation.fromNamespaceAndPath(RemainsCaveMod.MODID, "geo/entity/skeleton_king.geo.json");
                    }

                    @Override
                    public ResourceLocation getTextureResource(SkeletonKingRemainsBlockEntity animatable) {
                        return ResourceLocation.fromNamespaceAndPath(RemainsCaveMod.MODID, "textures/block/skeleton_king_trophy.png");
                    }

                    @Override
                    public ResourceLocation getAnimationResource(SkeletonKingRemainsBlockEntity animatable) {
                        return ResourceLocation.fromNamespaceAndPath(RemainsCaveMod.MODID, "animations/block/skeleton_king_remains.animation.json");
                    }
                }));

        // 骷髅王召唤方块渲染器
        event.registerBlockEntityRenderer(ModBlocks.SKELETON_KING_SUMMON_BLOCK_ENTITY.get(),
                context -> new GeoBlockRenderer<>(new GeoModel<SkeletonKingSummonBlockEntity>() {
                    @Override
                    public ResourceLocation getModelResource(SkeletonKingSummonBlockEntity animatable) {
                        return ResourceLocation.fromNamespaceAndPath(RemainsCaveMod.MODID, "geo/block/skeleton_king.geo.json");
                    }

                    @Override
                    public ResourceLocation getTextureResource(SkeletonKingSummonBlockEntity animatable) {
                        return ResourceLocation.fromNamespaceAndPath(RemainsCaveMod.MODID, "textures/block/skeleton_king_trophy.png");
                    }

                    @Override
                    public ResourceLocation getAnimationResource(SkeletonKingSummonBlockEntity animatable) {
                        return ResourceLocation.fromNamespaceAndPath(RemainsCaveMod.MODID, "animations/block/skeleton_king.animation.json");
                    }
                }));

        // 暗门方块实体渲染器
        event.registerBlockEntityRenderer(ModBlocks.TOMB_DOOR_BLOCK_ENTITY.get(), context -> new TombDoorRenderer());

        // 徽章方块实体渲染器（新增）
        event.registerBlockEntityRenderer(ModBlocks.EMBLEM_BLOCK_ENTITY.get(), EmblemRenderer::new);
    }

    @SubscribeEvent
    public static void registerScreens(RegisterMenuScreensEvent event) {
        event.register(ModMenus.QUIVER_MENU.get(), QuiverScreen::new);
    }

    @SubscribeEvent
    public static void onModelRegister(ModelEvent.RegisterAdditional event) {
        event.register(ModelResourceLocation.standalone(ResourceLocation.parse("remains_cave:block/kings_aura")));
    }

    @SubscribeEvent
    public static void onAddLayers(EntityRenderersEvent.AddLayers event) {
        // 为骷髅实体添加光环层
        addLayer(event, ModEntities.SKELETON_ARCHER.get(), SkeletonArcherRenderer.class);
        addLayer(event, ModEntities.SKELETON_WARLOCK.get(), SkeletonWarlockRenderer.class);
        addLayer(event, ModEntities.SKELETON_WARRIOR.get(), SkeletonWarriorRenderer.class);

        // 为所有玩家皮肤添加背部物品渲染层
        for (PlayerSkin.Model skinModel : event.getSkins()) {
            EntityRenderer<? extends Player> renderer = event.getSkin(skinModel);
            if (renderer instanceof LivingEntityRenderer<?, ?> livingRenderer) {
                @SuppressWarnings("unchecked")
                LivingEntityRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> playerRenderer =
                        (LivingEntityRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>>) livingRenderer;
                playerRenderer.addLayer(new BackItemRenderLayer(playerRenderer));
            }
        }
    }

    // 为实体添加光环渲染层的方法
    private static <T extends LivingEntity & GeoAnimatable & AuraBearer> void addLayer(
            EntityRenderersEvent.AddLayers event,
            EntityType<T> type,
            Class<? extends GeoEntityRenderer<T>> rendererClass) {
        Object rendererObj = event.getRenderer(type);
        LOGGER.info("Renderer for {}: {}", type, rendererObj);
        if (rendererObj instanceof GeoEntityRenderer<?> renderer) {
            GeoEntityRenderer<T> geoRenderer = rendererClass.cast(renderer);
            geoRenderer.addRenderLayer(new KingsAuraRenderLayer<>(geoRenderer));
            LOGGER.info("Added KingsAuraRenderLayer to {}", type);
        } else {
            LOGGER.warn("Renderer for {} is not a GeoEntityRenderer", type);
        }
    }
    @SubscribeEvent
    public static void onClientSetup(FMLClientSetupEvent event) {
        event.enqueueWork(() -> {
            BlockEntityRenderers.register(ModBlocks.CHALLENGE_ALTAR_BE.get(), com.remains_cave.client.render.block.ChallengeAltarRenderer::new);
        });
    }

}