package dev.crucifixbeta.mod.gui;

import asm.accessors.IMinecraftClient;
import dev.crucifixbeta.mod.commands.impl.TokenLoginApi;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.session.Session;
import net.minecraft.client.session.Session.AccountType;
import net.minecraft.text.Text;

@Environment(EnvType.CLIENT)
public class TokenLoginScreen extends Screen {
   private static final Session ORIGINAL_SESSION;
   private final Screen parent;
   private final TokenLoginScreen.Mode mode;
   private TextFieldWidget tokenField;
   private TextFieldWidget nameField;
   private TextFieldWidget skinField;
   private String status;

   public TokenLoginScreen(Screen parent, TokenLoginScreen.Mode mode) {
      super(Text.literal(mode == TokenLoginScreen.Mode.LOGIN ? "Token Login" : "Account Changer"));
      this.parent = parent;
      this.mode = mode;
      this.status = mode == TokenLoginScreen.Mode.LOGIN ? "Session" : "";
   }

   @Override
   protected void init() {
      int var1 = this.width / 2;
      int var2 = this.height / 2;
      if (this.mode == TokenLoginScreen.Mode.LOGIN) {
         this.tokenField = new TextFieldWidget(this.textRenderer, var1 - 120, var2 - 10, 240, 20, Text.literal("Token"));
         this.tokenField.setMaxLength(32767);
         this.tokenField.setFocused(true);
         this.addDrawableChild(this.tokenField);
         this.addDrawableChild(
            ButtonWidget.builder(Text.literal("Login"), button -> this.login()).dimensions(var1 - 120, var2 + 20, 116, 20).build()
         );
         this.addDrawableChild(
            ButtonWidget.builder(Text.literal("Restore"), button -> this.restore()).dimensions(var1 + 4, var2 + 20, 116, 20).build()
         );
      } else {
         this.nameField = new TextFieldWidget(this.textRenderer, var1 - 120, var2 - 14, 116, 20, Text.literal("Name"));
         this.nameField.setMaxLength(16);
         this.skinField = new TextFieldWidget(this.textRenderer, var1 + 4, var2 - 14, 116, 20, Text.literal("Skin URL"));
         this.skinField.setMaxLength(32767);
         this.nameField.setFocused(true);
         this.addDrawableChild(this.nameField);
         this.addDrawableChild(this.skinField);
         this.addDrawableChild(
            ButtonWidget.builder(Text.literal("Change Name"), button -> this.changeName()).dimensions(var1 - 120, var2 + 16, 116, 20).build()
         );
         this.addDrawableChild(
            ButtonWidget.builder(Text.literal("Change Skin"), button -> this.changeSkin()).dimensions(var1 + 4, var2 + 16, 116, 20).build()
         );
      }

      this.addDrawableChild(
         ButtonWidget.builder(Text.literal("Back"), button -> this.close()).dimensions(var1 - 120, var2 + 46, 240, 20).build()
      );
   }

   @Override
   public void render(DrawContext context, int mouseX, int mouseY, float delta) {
      ScreenBackgroundRenderer.render(context, this.width, this.height);
      context.drawText(this.textRenderer, this.title, this.width / 2 - this.textRenderer.getWidth(this.title) / 2, this.height / 2 - 50, -1, false);
      context.drawText(this.textRenderer, this.status, this.width / 2 - this.textRenderer.getWidth(this.status) / 2, this.height / 2 - 34, -1, false);
      if (this.mode == TokenLoginScreen.Mode.CHANGER) {
         context.drawText(this.textRenderer, "Name:", this.width / 2 - 120, this.height / 2 - 27, -1, false);
         context.drawText(this.textRenderer, "Skin:", this.width / 2 + 4, this.height / 2 - 27, -1, false);
      }

      super.render(context, mouseX, mouseY, delta);
   }

   @Override
   public void close() {
      if (this.client != null) {
         this.client.setScreen(this.parent);
      }
   }

   private void login() {
      String var1 = this.tokenField.getText().trim();
      if (var1.isEmpty()) {
         this.status = "Enter access token";
      } else {
         this.status = "Validating token...";
         CompletableFuture.runAsync(() -> {
            try {
               TokenLoginApi.Profile var2 = TokenLoginApi.profile(var1);
               Session var3 = new Session(var2.name(), parseUuid(var2.id()), var1, Optional.empty(), Optional.empty(), AccountType.MSA);
               MinecraftClient.getInstance().execute(() -> {
                  ((IMinecraftClient)MinecraftClient.getInstance()).setSession(var3);
                  this.status = "Logged in as " + var2.name();
               });
            } catch (Exception var4) {
               MinecraftClient.getInstance().execute(() -> this.status = "Invalid token");
            }
         });
      }
   }

   private void restore() {
      ((IMinecraftClient)MinecraftClient.getInstance()).setSession(ORIGINAL_SESSION);
      this.status = "Restored session: " + ORIGINAL_SESSION.getUsername();
   }

   private void changeName() {
      String var1 = this.nameField.getText().trim();
      if (var1.isEmpty()) {
         this.status = "Enter new name";
      } else {
         String var2 = MinecraftClient.getInstance().getSession().getAccessToken();
         if (var2.equals(ORIGINAL_SESSION.getAccessToken())) {
            this.status = "Blocked main account name change";
         } else {
            this.status = "Changing name...";
            CompletableFuture.runAsync(() -> {
               try {
                  int var3 = TokenLoginApi.changeName(var2, var1);
                  MinecraftClient.getInstance().execute(() -> this.status = var3 == 200 ? "Changed name" : "Name change failed: " + var3);
                  if (var3 == 200) {
                     TokenLoginApi.Profile var4 = TokenLoginApi.profile(var2);
                     Session var5 = new Session(var4.name(), parseUuid(var4.id()), var2, Optional.empty(), Optional.empty(), AccountType.MSA);
                     MinecraftClient.getInstance().execute(() -> ((IMinecraftClient)MinecraftClient.getInstance()).setSession(var5));
                  }
               } catch (Exception var6) {
                  MinecraftClient.getInstance().execute(() -> this.status = "Name change failed");
               }
            });
         }
      }
   }

   private void changeSkin() {
      String var1 = this.skinField.getText().trim();
      if (var1.isEmpty()) {
         this.status = "Enter skin URL";
      } else {
         String var2 = MinecraftClient.getInstance().getSession().getAccessToken();
         this.status = "Changing skin...";
         CompletableFuture.runAsync(
            () -> {
               try {
                  int var3 = TokenLoginApi.changeSkin(var2, var1);
                  MinecraftClient.getInstance()
                     .execute(() -> this.status = var3 != 200 && var3 != 204 ? "Skin change failed: " + var3 : "Changed skin");
               } catch (Exception var4) {
                  MinecraftClient.getInstance().execute(() -> this.status = "Skin change failed");
               }
            }
         );
      }
   }

   private static UUID parseUuid(String value) {
      String var1 = value.replace("-", "");
      return UUID.fromString(
         var1.substring(0, 8) + "-" + var1.substring(8, 12) + "-" + var1.substring(12, 16) + "-" + var1.substring(16, 20) + "-" + var1.substring(20)
      );
   }

   static {

      ORIGINAL_SESSION = MinecraftClient.getInstance().getSession();
   }
@Environment(EnvType.CLIENT)
   public static enum Mode {
      LOGIN,
      CHANGER;

}
}
