package asm.mixins;

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.mod.modules.impl.combat.AntiRegear;
import dev.crucifixbeta.mod.modules.impl.misc.ChestStealer;
import dev.crucifixbeta.mod.modules.impl.misc.ShulkerViewer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.ingame.ScreenHandlerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.Slot;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;
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;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Environment(EnvType.CLIENT)
@Mixin({HandledScreen.class})
public abstract class MixinHandledScreen<T extends ScreenHandler> extends Screen implements ScreenHandlerProvider<T> {
   @Unique
   private static final ItemStack[] ITEMS = new ItemStack[27];
   @Shadow
   @Nullable
   protected Slot focusedSlot;
   @Shadow
   protected int x;
   @Shadow
   protected int y;

   protected MixinHandledScreen(Text title) {
      super(title);
   }

   @Inject(
      method = {"render"},
      at = {@At("HEAD")},
      cancellable = true
   )
   private void onRenderHead(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
      if (AntiRegear.INSTANCE != null
         && AntiRegear.INSTANCE.isOn()
         && AntiRegear.INSTANCE.drop.getValue()
         && AntiRegear.INSTANCE.NoUi.getValue()
         && AntiRegear.hideShulkerUI) {
         ci.cancel();
      } else {
         if (ChestStealer.INSTANCE != null && ChestStealer.INSTANCE.shouldUseSilentContainerUi(this)) {
            ChestStealer.INSTANCE.renderSilentContainerUi(context, this.getScreenHandler());
            ci.cancel();
         }
      }
   }

   @Inject(
      method = {"mouseClicked"},
      at = {@At("HEAD")},
      cancellable = true
   )
   private void mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) {
      ItemStack var7;
      if (button == 2
         && this.focusedSlot != null
         && !this.focusedSlot.getStack().isEmpty()
         && Wrapper.mc.player.currentScreenHandler.getCursorStack().isEmpty()
         && ShulkerViewer.INSTANCE.isOn()
         && (ShulkerViewer.hasItems(var7 = this.focusedSlot.getStack()) || var7.getItem() == Items.ENDER_CHEST && CrucifixBeta.PLAYER.known)) {
         cir.setReturnValue(ShulkerViewer.openContainer(this.focusedSlot.getStack(), ITEMS, false));
      }
   }

   @Inject(
      method = {"render"},
      at = {@At("RETURN")}
   )
   private void onRender(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
      if (ShulkerViewer.INSTANCE.isOn()
         && ShulkerViewer.INSTANCE.toolTips.getValue()
         && this.focusedSlot != null
         && !this.focusedSlot.getStack().isEmpty()
         && this.client.player.playerScreenHandler.getCursorStack().isEmpty()
         && (ShulkerViewer.hasItems(this.focusedSlot.getStack()) || this.focusedSlot.getStack().getItem() == Items.ENDER_CHEST && CrucifixBeta.PLAYER.known)) {
         ShulkerViewer.renderShulkerToolTip(context, mouseX, mouseY, this.focusedSlot.getStack());
      }
   }

   @Shadow
   @Override
   public abstract void renderBackground(DrawContext drawContext, int i, int j, float f);
}
