package dev.crucifixbeta.mod.gui.windows.impl;

import com.google.common.collect.Lists;
import com.mojang.blaze3d.systems.RenderSystem;
import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.api.utils.math.AnimateUtil;
import dev.crucifixbeta.api.utils.render.ColorUtil;
import dev.crucifixbeta.api.utils.render.Render2DUtil;
import dev.crucifixbeta.core.Manager;
import dev.crucifixbeta.core.impl.CleanerManager;
import dev.crucifixbeta.core.impl.FontManager;
import dev.crucifixbeta.core.impl.HudItemManager;
import dev.crucifixbeta.core.impl.TradeManager;
import dev.crucifixbeta.core.impl.XrayManager;
import dev.crucifixbeta.mod.gui.items.buttons.StringButton;
import dev.crucifixbeta.mod.gui.windows.WindowBase;
import dev.crucifixbeta.mod.gui.windows.WindowsScreen;
import dev.crucifixbeta.mod.modules.impl.client.ClickGui;
import dev.crucifixbeta.mod.modules.impl.client.ClientSetting;
import dev.crucifixbeta.mod.modules.settings.impl.StringSetting;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Objects;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Block;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.InputUtil;
import net.minecraft.item.Item;
import net.minecraft.registry.Registries;
import net.minecraft.util.StringHelper;

@Environment(EnvType.CLIENT)
public class ItemSelectWindow extends WindowBase {
   private final Manager manager;
   private final ArrayList<ItemSelectWindow.ItemPlate> itemPlates = new ArrayList<>();
   private final ArrayList<ItemSelectWindow.ItemPlate> allItems = new ArrayList<>();
   private final StringSetting searchSetting;
   private final StringButton searchButton;
   private boolean allTab = true;
   private float tabY;
   private float tabH;
   private float tabAllX;
   private float tabAllW;
   private float tabSelX;
   private float tabSelW;
   private float listTop;
   private float tabAnimX;
   private float tabAnimW;
   private boolean tabAnimInit;

   public ItemSelectWindow(Manager manager) {
      this(
         (float)Wrapper.mc.getWindow().getScaledWidth() / 2.0F - 100.0F,
         (float)Wrapper.mc.getWindow().getScaledHeight() / 2.0F - 150.0F,
         200.0F,
         300.0F,
         manager
      );
   }

   public ItemSelectWindow(float x, float y, float width, float height, Manager manager) {
      super(x, y, width, height, getTitleLabel(), null);
      this.manager = manager;
      this.searchSetting = new StringSetting(getSearchLabel(), "").injectTask(this::refreshAllItems);
      this.searchButton = new StringButton(this.searchSetting);
      this.refreshItemPlates();
      float var6 = this.getRowHeight();
      int var7 = 0;

      for (Block var9 : Registries.BLOCK) {
         this.allItems.add(new ItemSelectWindow.ItemPlate((float)var7, (float)var7 * var6, var9.asItem(), var9.getTranslationKey()));
         var7++;
      }

      for (Item var11 : Registries.ITEM) {
         this.allItems.add(new ItemSelectWindow.ItemPlate((float)var7, (float)var7 * var6, var11, var11.getTranslationKey()));
         var7++;
      }
   }

   @Override
   public void render(DrawContext context, int mouseX, int mouseY) {
      this.layoutTabs();
      super.render(context, mouseX, mouseY);
      this.layoutSearchButton();
      this.searchButton.drawScreen(context, mouseX, mouseY, 0.0F);
      RenderSystem.setShader(GameRenderer::getPositionColorProgram);
      ClickGui var4 = ClickGui.getInstance();
      boolean var5 = FontManager.isShadowEnabled();
      boolean var6 = Render2DUtil.isHovered((double)mouseX, (double)mouseY, (double)this.tabAllX, (double)this.tabY, (double)this.tabAllW, (double)this.tabH);
      boolean var7 = Render2DUtil.isHovered((double)mouseX, (double)mouseY, (double)this.tabSelX, (double)this.tabY, (double)this.tabSelW, (double)this.tabH);
      int var8 = var4 != null ? var4.defaultColor.getValue().getRGB() : new Color(30, 30, 30, 236).getRGB();
      int var9 = var4 != null ? var4.hoverColor.getValue().getRGB() : new Color(50, 50, 50, 200).getRGB();
      int var10 = var4 != null ? var4.defaultTextColor.getValue().getRGB() : new Color(220, 220, 220).getRGB();
      int var11 = var4 != null ? var4.enableTextColor.getValue().getRGB() : -1;
      Render2DUtil.rect(context.getMatrices(), this.tabAllX, this.tabY, this.tabAllX + this.tabAllW, this.tabY + this.tabH, var6 ? var9 : var8);
      Render2DUtil.rect(context.getMatrices(), this.tabSelX, this.tabY, this.tabSelX + this.tabSelW, this.tabY + this.tabH, var7 ? var9 : var8);
      float var12 = this.allTab ? this.tabAllX : this.tabSelX;
      float var13 = this.allTab ? this.tabAllW : this.tabSelW;
      float var14 = AnimateUtil.deltaTime();
      if (var14 <= 0.0F) {
         var14 = 0.016F;
      }

      float var15 = var14 * 18.0F;
      if (var15 < 0.0F) {
         var15 = 0.0F;
      }

      if (var15 > 0.35F) {
         var15 = 0.35F;
      }

      boolean var16 = WindowsScreen.draggingWindow == this;
      if (this.tabAnimInit && !var16) {
         this.tabAnimX = this.tabAnimX + (var12 - this.tabAnimX) * var15;
         this.tabAnimW = this.tabAnimW + (var13 - this.tabAnimW) * var15;
      } else {
         this.tabAnimX = var12;
         this.tabAnimW = var13;
         this.tabAnimInit = true;
      }

      boolean var17 = this.allTab ? var6 : var7;
      int var18 = var4 != null ? (var17 ? var4.hoverAlpha.getValueInt() : var4.alpha.getValueInt()) : 200;
      if (var4 != null && var4.colorMode.getValue() == ClickGui.ColorMode.Spectrum) {
         Render2DUtil.drawLutRect(
            context.getMatrices(), this.tabAnimX, this.tabY, this.tabAnimW, this.tabH, var4.getSpectrumLutId(), var4.getSpectrumLutHeight(), var18
         );
      } else {
         Color var19 = var4 != null ? var4.getActiveColor((double)this.tabY * 0.25) : new Color(0, 120, 212);
         Render2DUtil.rect(
            context.getMatrices(), this.tabAnimX, this.tabY, this.tabAnimX + this.tabAnimW, this.tabY + this.tabH, ColorUtil.injectAlpha(var19, var18).getRGB()
         );
      }

      int var39 = !this.allTab && !var6 ? var10 : var11;
      int var20 = this.allTab && !var7 ? var10 : var11;
      float var21 = this.tabY + (this.tabH - FontManager.small.getFontHeight()) / 2.0F;
      String var22 = getAllLabel();
      String var23 = getSelectedLabel();
      FontManager.small
         .drawString(
            context.getMatrices(), var22, (double)(this.tabAllX + (this.tabAllW - FontManager.small.getWidth(var22)) / 2.0F), (double)var21, var39, var5
         );
      FontManager.small
         .drawString(
            context.getMatrices(), var23, (double)(this.tabSelX + (this.tabSelW - FontManager.small.getWidth(var23)) / 2.0F), (double)var21, var20, var5
         );
      if (!this.allTab && this.itemPlates.isEmpty()) {
         FontManager.ui
            .drawCenteredString(
               context.getMatrices(),
               getEmptyLabel(),
               (double)(this.getX() + this.getWidth() / 2.0F),
               (double)(this.getY() + this.getHeight() / 2.0F),
               new Color(12434877).getRGB()
            );
      }

      float var24 = this.getRowHeight();
      float var25 = 16.0F;
      float var26 = var24 * 0.3F;
      float var27 = var24 * 0.3F;
      float var28 = Math.max(8.0F, var24 * 0.5F);
      float var29 = var24 * 0.25F + this.getScrollBarWidth();
      context.enableScissor((int)this.getX(), (int)this.listTop, (int)(this.getX() + this.getWidth()), (int)(this.getY() + this.getHeight() - 1.0F));

      for (ItemSelectWindow.ItemPlate var31 : this.allTab ? this.allItems : this.itemPlates) {
         float var32 = var31.offset + this.listTop + this.getScrollOffset();
         if (!(var32 > this.getY() + this.getHeight()) && !(var32 + var24 < this.getY())) {
            context.getMatrices().push();
            context.getMatrices().translate(this.getX() + var26, var32 + (var24 - var25) / 2.0F, 0.0F);
            context.drawItem(var31.item().getDefaultStack(), 0, 0);
            context.getMatrices().pop();
            float var33 = var32 + (var24 - FontManager.ui.getFontHeight()) / 2.0F;
            float var34 = this.getX() + var26 + var25 + var27;
            FontManager.ui.drawString(context.getMatrices(), I18n.translate(var31.key()), (double)var34, (double)var33, new Color(12434877).getRGB(), var5);
            float var35 = this.getX() + this.getWidth() - var29 - var28;
            float var36 = var32 + (var24 - var28) / 2.0F;
            boolean var37 = Render2DUtil.isHovered((double)mouseX, (double)mouseY, (double)var35, (double)var36, (double)var28, (double)var28);
            Render2DUtil.drawRect(context.getMatrices(), var35, var36, var28, var28, var37 ? new Color(-981828998, true) : new Color(-984131753, true));
            boolean var38 = this.itemPlates.stream().anyMatch(sI -> Objects.equals(sI.key, var31.key));
            if (this.allTab && !var38) {
               FontManager.ui
                  .drawString(
                     context.getMatrices(),
                     "+",
                     (double)(var35 + (var28 - FontManager.ui.getWidth("+")) / 2.0F),
                     (double)(var36 + (var28 - FontManager.ui.getFontHeight()) / 2.0F),
                     -1,
                     var5
                  );
            } else {
               FontManager.ui
                  .drawString(
                     context.getMatrices(),
                     "-",
                     (double)(var35 + (var28 - FontManager.ui.getWidth("-")) / 2.0F),
                     (double)(var36 + (var28 - FontManager.ui.getFontHeight()) / 2.0F),
                     -1,
                     var5
                  );
            }
         }
      }

      this.setMaxElementsHeight((float)(this.allTab ? this.allItems : this.itemPlates).size() * var24);
      context.disableScissor();
   }

   @Override
   public void mouseClicked(double mouseX, double mouseY, int button) {
      super.mouseClicked(mouseX, mouseY, button);
      this.layoutSearchButton();
      this.layoutTabs();
      if (this.searchButton.isHovering((int)mouseX, (int)mouseY)) {
         this.searchButton.mouseClicked((int)mouseX, (int)mouseY, button);
      } else {
         if (Render2DUtil.isHovered(mouseX, mouseY, (double)this.tabAllX, (double)this.tabY, (double)this.tabAllW, (double)this.tabH)) {
            this.allTab = true;
            this.resetScroll();
         }

         if (Render2DUtil.isHovered(mouseX, mouseY, (double)this.tabSelX, (double)this.tabY, (double)this.tabSelW, (double)this.tabH)) {
            this.allTab = false;
            this.resetScroll();
         }

         float var6 = this.getRowHeight();
         float var7 = Math.max(8.0F, var6 * 0.5F);
         float var8 = var6 * 0.25F + this.getScrollBarWidth();

         for (ItemSelectWindow.ItemPlate var11 : Lists.newArrayList(this.allTab ? this.allItems : this.itemPlates)) {
            float var12 = var11.offset + this.listTop + this.getScrollOffset();
            if (!(var12 + var6 > this.getY() + this.getHeight())) {
               String var13 = var11.key()
                  .replace("item.minecraft.", "")
                  .replace("block.minecraft.", "");
               float var14 = this.getX() + this.getWidth() - var8 - var7;
               float var15 = var12 + (var6 - var7) / 2.0F;
               if (Render2DUtil.isHovered(mouseX, mouseY, (double)var14, (double)var15, (double)var7, (double)var7)) {
                  boolean var16 = this.itemPlates.stream().anyMatch(sI -> Objects.equals(sI.key(), var11.key));
                  if (this.allTab && !var16) {
                     Manager var24 = this.manager;
                     if (var24 instanceof TradeManager) {
                        TradeManager var28 = (TradeManager)var24;
                        if (!var28.inWhitelist(var13)) {
                           var28.add(var13);
                           this.refreshItemPlates();
                        }
                     } else {
                        var24 = this.manager;
                        if (var24 instanceof CleanerManager) {
                           CleanerManager var29 = (CleanerManager)var24;
                           if (!var29.inList(var13)) {
                              var29.add(var13);
                              this.refreshItemPlates();
                           }
                        } else {
                           var24 = this.manager;
                           if (var24 instanceof HudItemManager) {
                              HudItemManager var30 = (HudItemManager)var24;
                              if (!var30.inList(var13)) {
                                 var30.add(var13);
                                 this.refreshItemPlates();
                              }
                           } else {
                              var24 = this.manager;
                              XrayManager var31;
                              if (var24 instanceof XrayManager && !(var31 = (XrayManager)var24).inWhitelist(var13)) {
                                 var31.add(var13);
                                 this.refreshItemPlates();
                              }
                           }
                        }
                     }
                  } else {
                     if (this.manager instanceof TradeManager var18) {
                        var18.remove(var13);
                     } else {
                        Manager var22 = this.manager;
                        if (var22 instanceof CleanerManager var19) {
                           var19.remove(var13);
                        } else if (var22 instanceof HudItemManager var20) {
                           var20.remove(var13);
                        } else if (this.manager instanceof XrayManager var21) {
                           var21.remove(var13);
                        }
                     }

                     this.refreshItemPlates();
                  }
               }
            }
         }
      }
   }

   @Override
   public void keyPressed(int keyCode, int scanCode, int modifiers) {
      if (keyCode != 70 || !InputUtil.isKeyPressed(Wrapper.mc.getWindow().getHandle(), 341) && !InputUtil.isKeyPressed(Wrapper.mc.getWindow().getHandle(), 345)
         )
       {
         this.searchButton.onKeyPressed(keyCode);
      } else {
         this.searchButton.toggle();
      }
   }

   @Override
   public void charTyped(char key, int keyCode) {
      if (StringHelper.isValidChar(key)) {
         this.searchButton.onKeyTyped(key, keyCode);
      }
   }

   private void refreshItemPlates() {
      this.itemPlates.clear();
      float var1 = this.getRowHeight();
      int var2 = 0;

      for (Item var4 : Registries.ITEM) {
         Manager var5 = this.manager;
         if (var5 instanceof TradeManager) {
            TradeManager var6 = (TradeManager)var5;
            if (var6.inWhitelist(var4.getTranslationKey())) {
               this.itemPlates.add(new ItemSelectWindow.ItemPlate((float)var2, (float)var2 * var1, var4.asItem(), var4.getTranslationKey()));
               var2++;
            }
         } else {
            var5 = this.manager;
            if (var5 instanceof CleanerManager) {
               CleanerManager var11 = (CleanerManager)var5;
               if (var11.inList(var4.getTranslationKey())) {
                  this.itemPlates.add(new ItemSelectWindow.ItemPlate((float)var2, (float)var2 * var1, var4.asItem(), var4.getTranslationKey()));
                  var2++;
               }
            } else {
               var5 = this.manager;
               if (var5 instanceof HudItemManager) {
                  HudItemManager var12 = (HudItemManager)var5;
                  if (var12.inList(var4.getTranslationKey())) {
                     this.itemPlates.add(new ItemSelectWindow.ItemPlate((float)var2, (float)var2 * var1, var4.asItem(), var4.getTranslationKey()));
                     var2++;
                  }
               } else {
                  var5 = this.manager;
                  XrayManager var7;
                  if (var5 instanceof XrayManager && (var7 = (XrayManager)var5).inWhitelist(var4.getTranslationKey())) {
                     this.itemPlates.add(new ItemSelectWindow.ItemPlate((float)var2, (float)var2 * var1, var4.asItem(), var4.getTranslationKey()));
                     var2++;
                  }
               }
            }
         }
      }
   }

   private void refreshAllItems() {
      this.allItems.clear();
      this.resetScroll();
      float var1 = this.getRowHeight();
      int var2 = 0;

      for (Item var4 : Registries.ITEM) {
         String var5 = this.searchSetting.getValue();
         if (var5.isEmpty() || var4.getTranslationKey().contains(var5) || var4.getName().getString().toLowerCase().contains(var5.toLowerCase())) {
            this.allItems.add(new ItemSelectWindow.ItemPlate((float)var2, (float)var2 * var1, var4, var4.getTranslationKey()));
            var2++;
         }
      }
   }

   private float getRowHeight() {
      float var1 = 16.0F;
      float var2 = FontManager.ui.getFontHeight();
      return Math.max(var1, var2) + Math.max(4.0F, var2 * 0.4F);
   }

   private void layoutSearchButton() {
      ClickGui var1 = ClickGui.getInstance();
      float var2 = var1 != null ? (float)var1.categoryBarHeight.getValueInt() : 14.0F;
      float var4 = Math.min(this.getWidth() * 0.4F, this.getWidth() - var2 - var2 * 0.5F);
      int var5 = Math.max((int)(var4 * 0.85F), (int)(var2 * 2.2F));
      int var6 = Math.max(9, (int)(var2 * 0.7F));
      this.searchButton.setWidth(var5);
      this.searchButton.setHeight(var6);
      this.searchButton.setLocation(this.getX() + this.getWidth() - var2 - var4, this.getY() + (var2 - (float)var6) / 2.0F);
   }

   private void layoutTabs() {
      ClickGui var1 = ClickGui.getInstance();
      float var2 = var1 != null ? (float)var1.categoryBarHeight.getValueInt() : 14.0F;
      float var3 = 0.0F;
      float var4 = Math.max(2.0F, var2 * 0.25F);
      float var5 = FontManager.small.getFontHeight();
      float var7 = var5 * 2.5F;
      this.tabH = Math.max(7.0F, var2 * 0.8F);
      this.tabY = this.getY() + var2 + var4;
      String var8 = getAllLabel();
      String var9 = getSelectedLabel();
      this.tabAllW = Math.max(var7, FontManager.small.getWidth(var8) + var5);
      this.tabSelW = Math.max(var7, FontManager.small.getWidth(var9) + var5);
      float var10 = var2 * 0.6F;
      this.tabAllX = this.getX() + var10;
      this.tabSelX = this.tabAllX + this.tabAllW + var3;
      this.listTop = this.tabY + this.tabH + var4;
   }

   @Override
   protected float getScrollTop(float headerH) {
      return this.listTop;
   }

   @Override
   protected float getScrollHeight(float headerH) {
      float var2 = this.getY() + this.getHeight() - 1.0F;
      return Math.max(1.0F, var2 - this.listTop);
   }

   private static boolean isChinese() {
      return ClientSetting.INSTANCE != null && ClientSetting.INSTANCE.chinese.getValue();
   }

   private static String getTitleLabel() {
      return isChinese() ? "\u7269\u54c1" : "Items";
   }

   private static String getSearchLabel() {
      return isChinese() ? "\u641c\u7d22" : "Search";
   }

   private static String getAllLabel() {
      return isChinese() ? "\u5168\u90e8" : "All";
   }

   private static String getSelectedLabel() {
      return isChinese() ? "\u5df2\u9009" : "Selected";
   }

   private static String getEmptyLabel() {
      return isChinese() ? "\u8fd9\u91cc\u8fd8\u6ca1\u6709\u5185\u5bb9" : "It's empty here yet";
   }
@Environment(EnvType.CLIENT)
   private static record ItemPlate(float id, float offset, Item item, String key) {
   }
}
