package wtf.opal.client.screen.click.dropdown.panel;

import com.ibm.icu.impl.Pair;
import java.util.Optional;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.input.KeyInput;
import net.minecraft.util.Formatting;
import wtf.opal.client.OpalClient;
import wtf.opal.client.binding.repository.BindRepository;
import wtf.opal.client.binding.type.InputType;
import wtf.opal.client.feature.module.Module;
import wtf.opal.client.renderer.NVGRenderer;
import wtf.opal.client.renderer.repository.FontRepository;
import wtf.opal.client.renderer.text.NVGTextRenderer;
import wtf.opal.client.screen.click.OpalPanelComponent;
import wtf.opal.client.screen.click.dropdown.ClickGuiAnimationConfig;
import wtf.opal.client.screen.click.dropdown.DropdownClickGUI;
import wtf.opal.client.screen.click.dropdown.panel.property.PropertyProvider;
import wtf.opal.utility.misc.HoverUtility;
import wtf.opal.utility.render.ColorUtility;
import wtf.opal.utility.render.animation.Animation;
import wtf.opal.utility.render.animation.Easing;

@Environment(EnvType.CLIENT)
public final class ModulePanel extends OpalPanelComponent {
   private final Module module;
   private Animation hoverAnimation;
   private Animation toggleAnimation;
   private final Animation expandAnimation = new Animation(Easing.DECELERATE, 125L);
   private boolean lastModule;
   private boolean expanded;
   private boolean selectingBind;
   private final PropertyProvider propertyProvider;
   private final BindRepository bindRepository = OpalClient.getInstance().getBindRepository();

   public ModulePanel(Module module) {
      this.module = module;
      this.propertyProvider = new PropertyProvider(module, this::isExpandedAnimation, this::isLastModule);
   }

   private boolean isExpandedAnimation() {
      return this.expanded || this.expandAnimation.getValue() > 0.0F;
   }

   public boolean isExpanded() {
      return this.expanded;
   }

   @Override
   public void render(DrawContext context, int mouseX, int mouseY, float delta) {
      this.handleAnimations((float)mouseX, (float)mouseY);
      int var5 = ColorUtility.scaleOpacity(ColorUtility.getModuleBackgroundColor(), 0.38F);
      String var6 = this.module.isEnabled() ? "productsans-bold" : "productsans-medium";
      Pair var7 = ColorUtility.getClientTheme();
      if (!this.lastModule) {
         NVGRenderer.rect(this.x, this.y, this.width, this.height, var5);
         NVGRenderer.rect(
            this.x, this.y, this.width, this.height, ColorUtility.scaleOpacity(ColorUtility.getModuleHoverColor(), this.hoverAnimation.getValue() * 0.26F)
         );
         NVGRenderer.rect(this.x, this.y, this.width, this.height, ColorUtility.applyOpacity((Integer)var7.first, this.toggleAnimation.getValue() * 0.55F));
      } else {
         NVGRenderer.roundedRectVarying(this.x, this.y, this.width, this.height, 0.0F, 0.0F, 8.0F, 8.0F, var5);
         NVGRenderer.roundedRectVarying(
            this.x,
            this.y,
            this.width,
            this.height,
            0.0F,
            0.0F,
            8.0F,
            8.0F,
            ColorUtility.scaleOpacity(ColorUtility.getModuleHoverColor(), this.hoverAnimation.getValue() * 0.26F)
         );
         NVGRenderer.roundedRectVarying(
            this.x,
            this.y,
            this.width,
            this.height,
            0.0F,
            0.0F,
            8.0F,
            8.0F,
            ColorUtility.applyOpacity((Integer)var7.first, this.toggleAnimation.getValue() * 0.55F)
         );
      }

      NVGRenderer.scissor(
         this.x,
         this.y,
         this.width,
         this.height,
         () -> {
            int var6x = this.module.isEnabled() ? -1 : ColorUtility.darker(-1, 0.2F);
            FontRepository.getFont(var6).drawString(this.module.getDisplayName(), this.x + 6.0F, this.y + 12.5F, 8.0F, var6x);
            if (this.propertyProvider.isHasProperties() && !this.selectingBind && !DropdownClickGUI.displayingBinds) {
               String var7x = "\ue5cf";
               NVGTextRenderer var8 = FontRepository.getFont("materialicons-regular");
               float var9 = 12.0F;
               float var10 = var8.getStringWidth("\ue5cf", 12.0F);
               NVGRenderer.rotate(
                  (double)(this.expandAnimation.getValue() * 180.0F),
                  this.x + this.width - 17.0F,
                  this.y + 4.0F,
                  var10,
                  12.0F,
                  () -> var8.drawString("\ue5cf", 0.0F, 0.0F, 12.0F, var6x, false, 18)
               );
            }

            Optional var11 = this.bindRepository.getBindingService().getKeyFromBindable(this.module);
            String var12 = null;
            if (this.selectingBind) {
               var12 = Formatting.GRAY + "[" + Formatting.WHITE + "..." + Formatting.GRAY + "]";
            } else if (DropdownClickGUI.displayingBinds && var11.isPresent()) {
               String var13 = this.bindRepository.getNameFromInteger((Integer)((Pair)var11.get()).first);
               var12 = Formatting.GRAY + "[" + Formatting.WHITE + var13 + Formatting.GRAY + "]";
            }

            if (var12 != null) {
               FontRepository.getFont("productsans-medium")
                  .drawString(var12, this.x + this.width - FontRepository.getFont(var6).getStringWidth(var12, 7.0F) - 5.0F, this.y + 12.0F, 7.0F, -1);
            }

            if (!this.expandAnimation.isFinished() || this.isExpanded()) {
               this.propertyProvider.setX(this.x);
               this.propertyProvider.setY(this.y + 20.0F);
               this.propertyProvider.setWidth(this.width);
               this.propertyProvider.render(context, mouseX, mouseY, delta);
            }
         }
      );
   }

   private void handleAnimations(float mouseX, float mouseY) {
      float var3 = HoverUtility.isHovering(
            this.x, this.y, this.width, this.height - (this.isExpanded() ? this.propertyProvider.getExtraHeight() : 0.0F), (double)mouseX, (double)mouseY
         )
         ? 0.7F
         : 0.0F;
      if (this.hoverAnimation == null) {
         this.hoverAnimation = new Animation(Easing.DECELERATE, 150L);
         this.hoverAnimation.setValue(var3);
      } else {
         this.hoverAnimation.run(var3);
      }

      float var4 = this.module.isEnabled() ? 0.4F : 0.0F;
      if (this.toggleAnimation == null) {
         this.toggleAnimation = new Animation(Easing.DECELERATE, 150L);
         this.toggleAnimation.setValue(var4);
      } else {
         this.toggleAnimation.run(var4);
      }
   }

   @Override
   public void mouseClicked(double mouseX, double mouseY, int button) {
      if (!DropdownClickGUI.selectingBind && !this.selectingBind) {
         if (HoverUtility.isHovering(
            this.x, this.y, this.width, this.height - (this.isExpanded() ? this.propertyProvider.getExtraHeight() : 0.0F), mouseX, mouseY
         )) {
            switch (button) {
               case 0:
                  this.module.toggle();
                  break;
               case 1:
                  if (!this.module.getPropertyList().isEmpty()) {
                     this.expanded = !this.expanded;
                  }
                  break;
               case 2:
                  DropdownClickGUI.selectingBind = true;
                  this.selectingBind = true;
            }
         }

         this.propertyProvider.mouseClicked(mouseX, mouseY, button);
      } else {
         this.bindRepository.getBindingService().clearBindings(this.module);
         this.bindRepository.getBindingService().register(button, this.module, InputType.MOUSE);
         DropdownClickGUI.selectingBind = false;
         this.selectingBind = false;
      }
   }

   @Override
   public void keyPressed(KeyInput keyInput) {
      if (!DropdownClickGUI.selectingBind && !this.selectingBind) {
         this.propertyProvider.keyPressed(keyInput);
      } else {
         this.bindRepository.getBindingService().clearBindings(this.module);
         if (keyInput.key() != 256) {
            this.bindRepository.getBindingService().register(keyInput.key(), this.module, InputType.KEYBOARD);
         }

         DropdownClickGUI.selectingBind = false;
         this.selectingBind = false;
      }
   }

   @Override
   public void charTyped(char chr, int modifiers) {
      this.propertyProvider.charTyped(chr, modifiers);
   }

   public float getAddedHeight() {
      return this.propertyProvider.getExtraHeight();
   }

   public Animation getExpandAnimation() {
      ClickGuiAnimationConfig.applyParameterPanel(this.expandAnimation, 125L, Easing.DECELERATE);
      return this.expandAnimation;
   }

   @Override
   public void mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
      this.propertyProvider.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
   }

   @Override
   public void mouseReleased(double mouseX, double mouseY, int button) {
      this.propertyProvider.mouseReleased(mouseX, mouseY, button);
   }

   @Override
   public void init() {
      this.propertyProvider.init();
   }

   @Override
   public void close() {
      this.propertyProvider.close();
   }

   public void setLastModule(boolean lastModule) {
      this.lastModule = lastModule;
   }

   public boolean isLastModule() {
      return this.lastModule;
   }

   public Module getModule() {
      return this.module;
   }
}
