package net.fabricmc.fabric.mixin.renderer.client.block.render;

import com.llamalad7.mixinextras.sugar.Local;
import java.util.Iterator;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.render.FabricBlockModelRenderer;
import net.fabricmc.fabric.api.renderer.v1.render.RenderLayerHelper;
import net.fabricmc.fabric.impl.renderer.BatchingRenderCommandQueueExtension;
import net.fabricmc.fabric.impl.renderer.DelegatingBlockVertexConsumerProviderImpl;
import net.fabricmc.fabric.impl.renderer.ExtendedBlockCommand;
import net.fabricmc.fabric.impl.renderer.ExtendedBlockStateModelCommand;
import net.minecraft.class_1087;
import net.minecraft.class_11661;
import net.minecraft.class_11681;
import net.minecraft.class_11788;
import net.minecraft.class_11791;
import net.minecraft.class_2680;
import net.minecraft.class_4587;
import net.minecraft.class_4597;
import net.minecraft.class_4608;
import net.minecraft.class_4618;
import net.minecraft.class_776;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Environment(EnvType.CLIENT)
@Mixin({class_11681.class})
abstract class FallingBlockCommandRendererMixin {
   @Shadow
   @Final
   private class_4587 field_61826;

   @Inject(
      method = {"method_72998(Lnet/minecraft/class_11788;Lnet/minecraft/class_4597$class_4598;Lnet/minecraft/class_776;Lnet/minecraft/class_4618;)V"},
      at = {@At(
   value = "INVOKE",
   target = "Ljava/util/Iterator;hasNext()Z",
   ordinal = 0
)}
   )
   private void beforeRenderMovingBlocks(class_11788 queue, class_4597.class_4598 vertexConsumers, class_776 blockRenderManager, class_4618 outlineVertexConsumers, CallbackInfo ci, @Local Iterator<class_11661.class_11790> iterator) {
      while(iterator.hasNext()) {
         class_11661.class_11790 command = (class_11661.class_11790)iterator.next();
         class_11791 renderState = command.comp_4653();
         class_2680 blockState = renderState.field_62247;
         class_1087 model = blockRenderManager.method_3349(blockState);
         long seed = blockState.method_26190(renderState.field_62245);
         this.field_61826.method_22903();
         this.field_61826.method_34425(command.comp_4652());
         blockRenderManager.method_3350().render(renderState, model, blockState, renderState.field_62246, this.field_61826, RenderLayerHelper.movingDelegate(vertexConsumers), false, seed, class_4608.field_21444);
         this.field_61826.method_22909();
      }

   }

   @Inject(
      method = {"method_72998(Lnet/minecraft/class_11788;Lnet/minecraft/class_4597$class_4598;Lnet/minecraft/class_776;Lnet/minecraft/class_4618;)V"},
      at = {@At("RETURN")}
   )
   private void onReturnRender(class_11788 queue, class_4597.class_4598 vertexConsumers, class_776 blockRenderManager, class_4618 outlineVertexConsumers, CallbackInfo ci) {
      DelegatingBlockVertexConsumerProviderImpl blockVertexConsumerProvider = new DelegatingBlockVertexConsumerProviderImpl();

      for(ExtendedBlockCommand command : ((BatchingRenderCommandQueueExtension)queue).fabric_getExtendedBlockCommands()) {
         this.field_61826.method_22903();
         this.field_61826.method_23760().method_66521(command.matricesEntry());
         blockRenderManager.renderBlockAsEntity(command.state(), this.field_61826, vertexConsumers, command.lightCoords(), command.overlayCoords(), command.blockView(), command.pos());
         if (command.outlineColor() != 0) {
            outlineVertexConsumers.method_23286(command.outlineColor());
            blockRenderManager.renderBlockAsEntity(command.state(), this.field_61826, outlineVertexConsumers, command.lightCoords(), command.overlayCoords(), command.blockView(), command.pos());
         }

         this.field_61826.method_22909();
      }

      for(ExtendedBlockStateModelCommand command : ((BatchingRenderCommandQueueExtension)queue).fabric_getExtendedBlockStateModelCommands()) {
         blockVertexConsumerProvider.renderLayerFunction = command.renderLayerFunction();
         blockVertexConsumerProvider.vertexConsumerProvider = vertexConsumers;
         FabricBlockModelRenderer.render(command.matricesEntry(), blockVertexConsumerProvider, command.model(), command.r(), command.g(), command.b(), command.lightCoords(), command.overlayCoords(), command.blockView(), command.pos(), command.state());
         if (command.outlineColor() != 0) {
            outlineVertexConsumers.method_23286(command.outlineColor());
            blockVertexConsumerProvider.vertexConsumerProvider = outlineVertexConsumers;
            FabricBlockModelRenderer.render(command.matricesEntry(), blockVertexConsumerProvider, command.model(), command.r(), command.g(), command.b(), command.lightCoords(), command.overlayCoords(), command.blockView(), command.pos(), command.state());
         }
      }

   }
}
