/*
 * 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.client.render.block;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import com.remains_cave.block.ChallengeAltarBlock;
import com.remains_cave.block.entity.ChallengeAltarBlockEntity;
import com.remains_cave.dungeon.tomb.ChallengeType;
import com.remains_cave.item.ModItems;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;

public class ChallengeAltarRenderer implements BlockEntityRenderer<ChallengeAltarBlockEntity> {
    private static final float ITEM_HEIGHT = 1.5F;
    private static final float FLOAT_AMPLITUDE = 0.05F;
    private static final float ROTATION_SPEED = 5.0F;
    private static final float ITEM_SCALE = 0.75F;
    private static final float AURA_SCALE = 2.0F;

    private BakedModel auraModel;

    public ChallengeAltarRenderer(BlockEntityRendererProvider.Context context) {
        ModelManager modelManager = Minecraft.getInstance().getModelManager();
        ResourceLocation modelLocation = ResourceLocation.parse("remains_cave:block/kings_aura");
        ModelResourceLocation modelResourceLocation = ModelResourceLocation.standalone(modelLocation);
        auraModel = modelManager.getModel(modelResourceLocation);
    }

    @Override
    public void render(ChallengeAltarBlockEntity altar, float partialTick, PoseStack poseStack,
                       MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
        BlockState state = altar.getBlockState();

        // 挑战激活时，只有激活祭坛显示光环
        if (altar.isChallengeActive()) {
            BlockPos activePos = altar.getActiveAltarPos();
            if (activePos != null && activePos.equals(altar.getBlockPos())) {
                renderAura(altar, partialTick, poseStack, bufferSource, packedLight, packedOverlay);
            }
            return;
        }

        // 开放状态：不渲染额外物品
        if (state.getValue(ChallengeAltarBlock.OPEN)) {
            return;
        }

        // 冷却状态：不渲染任何额外物品（避免短暂激活时的闪烁）
        if (altar.isOnCooldown()) {
            return;
        }

        // 正常状态：玩家靠近时渲染悬浮物品
        if (state.getValue(ChallengeAltarBlock.ACTIVE)) {
            renderItem(altar, partialTick, poseStack, bufferSource, packedLight, packedOverlay);
        }
    }

    private void renderItem(ChallengeAltarBlockEntity altar, float partialTick, PoseStack poseStack,
                            MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
        BlockState state = altar.getBlockState();
        ChallengeType type = state.getValue(ChallengeAltarBlock.TYPE);
        if (type == ChallengeType.NONE) return;

        ItemStack stack = getItemStackForType(type);
        if (stack.isEmpty()) return;

        poseStack.pushPose();
        poseStack.translate(0.5, ITEM_HEIGHT, 0.5);

        long gameTime = altar.getLevel() != null ? altar.getLevel().getGameTime() : 0;
        float yOffset = (float) Math.sin((gameTime + partialTick) * 0.1) * FLOAT_AMPLITUDE;
        poseStack.translate(0, yOffset, 0);

        float angle = (gameTime + partialTick) * ROTATION_SPEED;
        poseStack.mulPose(Axis.YP.rotationDegrees(angle));

        poseStack.scale(ITEM_SCALE, ITEM_SCALE, ITEM_SCALE);

        ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
        BakedModel model = itemRenderer.getModel(stack, altar.getLevel(), null, 0);
        itemRenderer.render(stack, ItemDisplayContext.FIXED, false, poseStack, bufferSource, packedLight, packedOverlay, model);

        poseStack.popPose();
    }

    private void renderAura(ChallengeAltarBlockEntity altar, float partialTick, PoseStack poseStack,
                            MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
        if (auraModel == null) {
            return;
        }

        poseStack.pushPose();
        poseStack.translate(0.5, ITEM_HEIGHT, 0.5);

        long gameTime = altar.getLevel() != null ? altar.getLevel().getGameTime() : 0;
        float yOffset = (float) Math.sin((gameTime + partialTick) * 0.1) * FLOAT_AMPLITUDE;
        poseStack.translate(0, yOffset, 0);

        float angle = (gameTime + partialTick) * 2.0F;
        poseStack.mulPose(Axis.YP.rotationDegrees(angle));

        poseStack.scale(AURA_SCALE, AURA_SCALE, AURA_SCALE);

        var dispatcher = Minecraft.getInstance().getBlockRenderer();
        var consumer = bufferSource.getBuffer(RenderType.cutout());
        dispatcher.getModelRenderer().renderModel(
                poseStack.last(), consumer, null, auraModel, 1.0F, 1.0F, 1.0F, packedLight, packedOverlay
        );

        poseStack.popPose();
    }

    private ItemStack getItemStackForType(ChallengeType type) {
        return switch (type) {
            case WARRIOR -> new ItemStack(ModItems.BONE_HATCHET.get());
            case ARCHER -> new ItemStack(ModItems.TOMB_BOW.get());
            case WARLOCK -> new ItemStack(ModItems.DOOM_STAFF.get());
            default -> ItemStack.EMPTY;
        };
    }
}