package asm.mixins;

import dev.crucifixbeta.mod.modules.impl.render.NoRender;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.ItemEntityRenderer;
import net.minecraft.client.render.entity.EntityRendererFactory.Context;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.json.ModelTransformationMode;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.ItemEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.random.Random;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
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({ItemEntityRenderer.class})
public abstract class MixinItemEntityRenderer extends EntityRenderer<ItemEntity> {
   @Final
   @Shadow
   private ItemRenderer itemRenderer;
   @Final
   @Shadow
   private Random random;

   protected MixinItemEntityRenderer(Context ctx) {
      super(ctx);
   }

   @Unique
   private static int getRenderedAmount(ItemStack stackSize) {
      int var1 = stackSize.getCount();
      if (var1 <= 1) {
         return 1;
      } else if (var1 <= 16) {
         return 2;
      } else if (var1 <= 32) {
         return 3;
      } else {
         return var1 <= 48 ? 4 : 5;
      }
   }

   @Inject(
      method = {"render*"},
      at = {@At("HEAD")},
      cancellable = true
   )
   public void render(ItemEntity itemEntity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) {
      if (NoRender.INSTANCE.isOn() && NoRender.INSTANCE.fastItem.getValue()) {
         matrixStack.push();
         ItemStack var8 = itemEntity.getStack();
         long var9 = var8.isEmpty() ? 187L : (long)(Item.getRawId(var8.getItem()) + var8.getDamage());
         this.random.setSeed(var9);
         BakedModel var11 = this.itemRenderer.getModel(var8, itemEntity.getWorld(), null, itemEntity.getId());
         boolean var12 = var11.hasDepth();
         this.shadowRadius = NoRender.INSTANCE.castShadow.getValue() ? 0.15F : 0.0F;
         float var13 = MathHelper.sin(((float)itemEntity.getItemAge() + g) / 10.0F + itemEntity.uniqueOffset) * 0.1F + 0.1F;
         float var14 = var11.getTransformation().getTransformation(ModelTransformationMode.GROUND).scale.y();
         matrixStack.translate(0.0F, var13 + 0.25F * var14, 0.0F);
         matrixStack.multiply(this.dispatcher.getRotation());
         float var15 = var11.getTransformation().ground.scale.x();
         float var16 = var11.getTransformation().ground.scale.y();
         float var17 = var11.getTransformation().ground.scale.z();
         int var18 = getRenderedAmount(var8);
         if (!var12) {
            float var19 = -0.0F * (float)(var18 - 1) * 0.5F * var15;
            float var20 = -0.0F * (float)(var18 - 1) * 0.5F * var16;
            float var21 = -0.09375F * (float)(var18 - 1) * 0.5F * var17;
            matrixStack.translate(var19, var20, var21);
         }

         for (int var23 = 0; var23 < var18; var23++) {
            matrixStack.push();
            if (var23 > 0) {
               if (var12) {
                  float var24 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F;
                  float var26 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F;
                  float var22 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F;
                  matrixStack.translate(var24, var26, var22);
               } else {
                  float var25 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F;
                  float var27 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F;
                  matrixStack.translate(var25, var27, 0.0F);
               }
            }

            this.itemRenderer.renderItem(var8, ModelTransformationMode.GROUND, false, matrixStack, vertexConsumerProvider, i, OverlayTexture.DEFAULT_UV, var11);
            matrixStack.pop();
            if (!var12) {
               matrixStack.translate(0.0F * var15, 0.0F * var16, 0.0425F * var17);
            }
         }

         matrixStack.pop();
         super.render(itemEntity, f, g, matrixStack, vertexConsumerProvider, i);
         ci.cancel();
      }
   }
}
