package wtf.opal.client.feature.module.property;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.mojang.logging.LogUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BooleanSupplier;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import wtf.opal.client.feature.module.Module;
import wtf.opal.client.feature.module.property.impl.mode.ModeProperty;
import wtf.opal.client.feature.module.property.impl.mode.ModuleMode;
import wtf.opal.client.screen.click.dropdown.panel.property.PropertyPanel;
import wtf.opal.event.EventDispatcher;
import wtf.opal.event.impl.client.PropertyUpdateEvent;

@Environment(EnvType.CLIENT)
public class Property<T> {
   private final String name;
   @Expose
   @SerializedName("name")
   private String id;
   @Expose
   @SerializedName("value")
   private T value;
   private boolean focused;
   private BooleanSupplier hiddenSupplier;
   private List<IPropertyUpdateListener<T>> propertyUpdateListeners;

   protected Property(String name) {
      this.name = name;
      this.id = name;
   }

   protected Property(String name, ModuleMode<?> parent) {
      this.name = name;
      this.id = name;
      Module var3 = parent.getModule();
      ModeProperty var4 = var3.getModeProperty();
      if (var4 == null) {
         LogUtils.getLogger().error(var3.getName() + " does not have a mode property.");
      } else {
         for (Enum var8 : var4.getValues()) {
            if (var8.equals(parent.getEnumValue())) {
               var3.addProperties(this);
               break;
            }
         }
      }
   }

   public final <R extends Property<T>> R hideIf(BooleanSupplier hiddenSupplier) {
      this.hiddenSupplier = hiddenSupplier;
      return (R)this;
   }

   public final String getName() {
      return this.name;
   }

   public final String getId() {
      return this.id;
   }

   public final <R extends Property<T>> R id(String id) {
      this.id = id;
      return (R)this;
   }

   public T getValue() {
      return this.value;
   }

   public void setValue(T value) {
      Object var2 = this.value;
      this.value = (T)value;
      EventDispatcher.dispatch(new PropertyUpdateEvent(this));
      this.callChangeListeners((T)var2, (T)value);
   }

   public final boolean isHidden() {
      return this.hiddenSupplier != null && this.hiddenSupplier.getAsBoolean();
   }

   public PropertyPanel<?> createClickGUIComponent() {
      return null;
   }

   public final <P extends Property<T>> P addUpdateListener(IPropertyUpdateListener<T> listener) {
      if (this.propertyUpdateListeners == null) {
         this.propertyUpdateListeners = new ArrayList<>(1);
      }

      this.propertyUpdateListeners.add(listener);
      return (P)this;
   }

   public final <P extends Property<T>> P addUpdateListener(Runnable listener) {
      if (this.propertyUpdateListeners == null) {
         this.propertyUpdateListeners = new ArrayList<>(1);
      }

      this.propertyUpdateListeners.add((p, v) -> listener.run());
      return (P)this;
   }

   public final void callChangeListeners(T prevValue, T value) {
      if (this.propertyUpdateListeners != null) {
         this.propertyUpdateListeners.forEach(l -> l.onChange((T)prevValue, (T)value));
      }
   }

   public final boolean isFocused() {
      return this.focused;
   }

   public final void setFocused(boolean focused) {
      this.focused = focused;
   }

   public void applyValue(Object propertyValue) {
   }
}
