package com.r3944realms.modernlifepatch.client.render;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.r3944realms.modernlifepatch.ModernLifePatch;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.client.event.RenderHighlightEvent;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public final class BlockOutlineRenderer {
    private static final Map<ISpecialHitBoxType, OutlineRender> OUTLINE_RENDERERS = new HashMap<>();
    private static final Set<ISpecialHitBoxType> ERRORED_TYPES = new HashSet<>();
    public static void onRenderBlockHighlight(final RenderHighlightEvent.Block event)
    {
        BlockHitResult result = event.getTarget();
        //noinspection ConstantConditions
        BlockState state = Minecraft.getInstance().level.getBlockState(result.getBlockPos());
        if (!(state.getBlock() instanceof ISpecialHitBoxType block)) { return; }


        if (block.hasSpecialHitbox())
        {
            PoseStack mstack = event.getPoseStack();
            Vec3 offset = Vec3.atLowerCornerOf(result.getBlockPos()).subtract(event.getCamera().getPosition());
            VertexConsumer builder = event.getMultiBufferSource().getBuffer(RenderType.lines());

            OutlineRender render = OUTLINE_RENDERERS.get(block.getSpecialHitBoxType());
            if (render == null)
            {
                if (ERRORED_TYPES.add(block))
                {
                    ModernLifePatch.logger.error("IBlockType '{}' requests custom outline rendering but no OutlineRender was registered!", block.getSTName());
                }
                return;
            }

            mstack.pushPose();
            mstack.translate(offset.x, offset.y, offset.z);
            mstack.translate(.5, .5, .5);
            render.rotateMatrix(mstack, state, block.getFaceDirection());
            mstack.translate(-.5, -.5, -.5);

            render.draw(state, Minecraft.getInstance().level, result.getBlockPos(), mstack, builder);

            mstack.popPose();

            event.setCanceled(true);
        }
    }
    public static synchronized void registerOutlineRender(ISpecialHitBoxType type, OutlineRender render)
    {
        if (!type.hasSpecialHitbox())
        {
            throw new IllegalArgumentException(String.format("Type %s doesn't return true from IBlockType#hasSpecialHitbox()", type));
        }

        OUTLINE_RENDERERS.put(type, render);
    }
    private BlockOutlineRenderer() { }
}
