package dev.crucifixbeta.core.impl;

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.BlockActivateEvent;
import dev.crucifixbeta.api.events.impl.GameLeftEvent;
import dev.crucifixbeta.api.events.impl.OpenScreenEvent;
import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.api.utils.world.BlockPosX;
import dev.crucifixbeta.mod.modules.Module;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Blocks;
import net.minecraft.block.EnderChestBlock;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.GenericContainerScreenHandler;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;

@Environment(EnvType.CLIENT)
public class PlayerManager implements Wrapper {
   public static Screen screenToOpen;
   public final DefaultedList<ItemStack> ENDERCHEST_ITEM = DefaultedList.ofSize(27, ItemStack.EMPTY);
   public final Map<PlayerEntity, PlayerManager.EntityAttribute> map = new ConcurrentHashMap<>();
   public final CopyOnWriteArrayList<PlayerEntity> inWebPlayers = new CopyOnWriteArrayList<>();
   public boolean known = false;
   private int echestOpenedState;

   public PlayerManager() {
      CrucifixBeta.EVENT_BUS.subscribe(this);
   }

   @EventListener
   public void onLogout(GameLeftEvent event) {
      this.inWebPlayers.clear();
      this.map.clear();
      this.ENDERCHEST_ITEM.clear();
      this.known = false;
   }

   @EventListener
   private void onBlockActivate(BlockActivateEvent event) {
      if (event.blockState.getBlock() instanceof EnderChestBlock && this.echestOpenedState == 0) {
         this.echestOpenedState = 1;
      }
   }

   @EventListener
   private void onOpenScreenEvent(OpenScreenEvent event) {
      if (this.echestOpenedState == 1 && event.screen instanceof GenericContainerScreen) {
         this.echestOpenedState = 2;
      } else if (this.echestOpenedState != 0) {
         if (mc.currentScreen instanceof GenericContainerScreen) {
            GenericContainerScreenHandler var2 = ((GenericContainerScreen)mc.currentScreen).getScreenHandler();
            if (var2 != null) {
               Inventory var3 = var2.getInventory();

               for (int var4 = 0; var4 < 27; var4++) {
                  this.ENDERCHEST_ITEM.set(var4, var3.getStack(var4));
               }

               this.known = true;
               this.echestOpenedState = 0;
            }
         }
      }
   }

   public void onUpdate() {
      if (!Module.nullCheck()) {
         if (screenToOpen != null && mc.currentScreen == null) {
            mc.setScreen(screenToOpen);
            screenToOpen = null;
         }

         this.inWebPlayers.clear();

         for (PlayerEntity var2 : CrucifixBeta.THREAD.getPlayers()) {
            this.map.put(var2, new PlayerManager.EntityAttribute(var2.getArmor(), var2.getAttributeValue(EntityAttributes.GENERIC_ARMOR_TOUGHNESS)));
            this.webUpdate(var2);
         }
      }
   }

   public boolean isInWeb(PlayerEntity player) {
      return this.inWebPlayers.contains(player);
   }

   private void webUpdate(PlayerEntity player) {
      for (float var5 : new float[]{0.0F, 0.3F, -0.3F}) {
         for (float var9 : new float[]{0.0F, 0.3F, -0.3F}) {
            for (int var13 : new int[]{-1, 0, 1, 2}) {
               BlockPos var14 = new BlockPosX(player.getX() + (double)var5, player.getY(), player.getZ() + (double)var9).up(var13);
               if (new Box(var14).intersects(player.getBoundingBox()) && mc.world.getBlockState(var14).getBlock() == Blocks.COBWEB) {
                  this.inWebPlayers.add(player);
                  return;
               }
            }
         }
      }
   }

   @Environment(EnvType.CLIENT)
   public static record EntityAttribute(int armor, double toughness) {
   }
}
