package com.tiedup.remake.v2.client;

import com.mojang.blaze3d.vertex.PoseStack;
import com.tiedup.remake.client.renderer.obj.ObjModel;
import com.tiedup.remake.client.renderer.obj.ObjModelRegistry;
import com.tiedup.remake.client.renderer.obj.ObjModelRenderer;
import com.tiedup.remake.v2.blocks.ObjBlockEntity;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

/**
 * Block entity renderer for OBJ model blocks.
 * Uses the existing OBJ rendering system from client/renderer/obj/.
 */
@OnlyIn(Dist.CLIENT)
public class ObjBlockRenderer implements BlockEntityRenderer<ObjBlockEntity> {

    public ObjBlockRenderer(BlockEntityRendererProvider.Context context) {}

    @Override
    public void render(
        ObjBlockEntity blockEntity,
        float partialTick,
        PoseStack poseStack,
        MultiBufferSource buffer,
        int packedLight,
        int packedOverlay
    ) {
        ResourceLocation modelLoc = blockEntity.getModelLocation();
        if (modelLoc == null) return;

        ObjModel model = ObjModelRegistry.get(modelLoc);
        if (model == null) return;

        poseStack.pushPose();

        // Center on block
        poseStack.translate(0.5, 0.0, 0.5);

        // Apply block rotation based on facing direction
        applyBlockRotation(poseStack, blockEntity.getBlockState());

        // Apply custom scale if specified
        float scale = blockEntity.getModelScale();
        if (scale != 1.0f) {
            poseStack.scale(scale, scale, scale);
        }

        // Apply custom offset if specified
        float[] offset = blockEntity.getModelOffset();
        if (offset[0] != 0 || offset[1] != 0 || offset[2] != 0) {
            poseStack.translate(offset[0], offset[1], offset[2]);
        }

        // Render using the existing OBJ renderer system
        ObjModelRenderer.render(
            model,
            poseStack,
            buffer,
            packedLight,
            packedOverlay
        );

        poseStack.popPose();
    }

    private void applyBlockRotation(
        PoseStack poseStack,
        BlockState blockState
    ) {
        if (blockState.hasProperty(HorizontalDirectionalBlock.FACING)) {
            Direction facing = blockState.getValue(
                HorizontalDirectionalBlock.FACING
            );
            float rotation = switch (facing) {
                case NORTH -> 0f;
                case SOUTH -> 180f;
                case WEST -> 90f;
                case EAST -> -90f;
                default -> 0f;
            };
            poseStack.mulPose(
                com.mojang.math.Axis.YP.rotationDegrees(rotation)
            );
        }
    }

    /**
     * Always true. Furniture OBJ models routinely have visible geometry that
     * extends past the block's 1×1×1 AABB (a 3-wide couch), so the default
     * per-entity frustum cull produces visible pop-in at screen edges as the
     * origin block leaves view. Extra cost: a few OBJ draws per frame for
     * off-screen furniture.
     */
    @Override
    public boolean shouldRenderOffScreen(ObjBlockEntity blockEntity) {
        return true;
    }
}
