package dev.crucifixbeta.mod.gui.accounts;

import asm.accessors.IMinecraftClient;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import dev.crucifixbeta.core.Manager;
import dev.crucifixbeta.mod.commands.impl.TokenLoginApi;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.session.Session;
import net.minecraft.client.session.Session.AccountType;
import net.minecraft.util.Uuids;

@Environment(EnvType.CLIENT)
public final class MenuAccounts {
   private static final Gson GSON;
   private static final File FILE;
   private static final List<MenuAccounts.Entry> ACCOUNTS;
   private static boolean loaded;

   private MenuAccounts() {
   }

   public static List<MenuAccounts.Entry> all() {
      load();
      return ACCOUNTS;
   }

   public static void addOffline(String name) {
      load();
      MenuAccounts.Entry var1 = new MenuAccounts.Entry(
         MenuAccounts.Type.OFFLINE, name, name, Uuids.getOfflinePlayerUuid(name).toString(), ""
      );
      add(var1);
   }

   public static MenuAccounts.Entry addToken(String token) throws IOException, InterruptedException {
      load();
      TokenLoginApi.Profile var1 = TokenLoginApi.profile(token);
      MenuAccounts.Entry var2 = new MenuAccounts.Entry(MenuAccounts.Type.TOKEN, var1.name(), var1.name(), parseUuid(var1.id()).toString(), token);
      add(var2);
      return var2;
   }

   public static void remove(MenuAccounts.Entry entry) {
      load();
      ACCOUNTS.remove(entry);
      save();
   }

   public static boolean login(MenuAccounts.Entry entry) {
      if (entry != null && entry.username != null && !entry.username.isBlank()) {
         UUID var1 = entry.uuid != null && !entry.uuid.isBlank() ? UUID.fromString(entry.uuid) : Uuids.getOfflinePlayerUuid(entry.username);
         String var2 = entry.token == null ? "" : entry.token;
         Session var3 = new Session(entry.username, var1, var2, Optional.empty(), Optional.empty(), AccountType.MSA);
         MinecraftClient var4 = MinecraftClient.getInstance();
         var4.execute(() -> ((IMinecraftClient)var4).setSession(var3));
         return true;
      } else {
         return false;
      }
   }

   public static void load() {
      if (!loaded) {
         loaded = true;
         ACCOUNTS.clear();
         if (FILE.exists()) {
            try (FileReader var0 = new FileReader(FILE)) {
               MenuAccounts.Store var1 = (MenuAccounts.Store)GSON.fromJson(var0, MenuAccounts.Store.class);
               if (var1 != null && var1.accounts != null) {
                  ACCOUNTS.addAll(var1.accounts);
               }
            } catch (Exception var5) {
               ACCOUNTS.clear();
            }
         }
      }
   }

   public static void save() {
      File var0 = FILE.getParentFile();
      if (var0 != null && !var0.exists()) {
         var0.mkdirs();
      }

      try (FileWriter var1 = new FileWriter(FILE)) {
         MenuAccounts.Store var2 = new MenuAccounts.Store();
         var2.accounts = new ArrayList<>(ACCOUNTS);
         GSON.toJson(var2, var1);
      } catch (IOException var6) {
      }
   }

   private static void add(MenuAccounts.Entry entry) {
      ACCOUNTS.removeIf(existing -> sameAccount(existing, entry));
      ACCOUNTS.add(entry);
      save();
   }

   private static boolean sameAccount(MenuAccounts.Entry a, MenuAccounts.Entry b) {
      if (a == null || b == null) {
         return false;
      } else if (a.type != b.type) {
         return false;
      } else {
         return a.type == MenuAccounts.Type.TOKEN ? safeEquals(a.token, b.token) : safeEquals(a.username, b.username);
      }
   }

   private static boolean safeEquals(String a, String b) {
      return a == null ? b == null : a.equalsIgnoreCase(b);
   }

   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 {

      GSON = new GsonBuilder().setPrettyPrinting().create();
      FILE = Manager.getFile("menu-accounts.json");
      ACCOUNTS = new ArrayList<>();
   }
@Environment(EnvType.CLIENT)
   public static final class Entry {
      public MenuAccounts.Type type;
      public String label;
      public String username;
      public String uuid;
      public String token;

      public Entry() {
      }

      public Entry(MenuAccounts.Type type, String label, String username, String uuid, String token) {
         this.type = type;
         this.label = label;
         this.username = username;
         this.uuid = uuid;
         this.token = token;
      }

      public String displayName() {
         return this.username != null && !this.username.isBlank() ? this.username : this.label;
      }

      public String typeName() {
         return this.type == MenuAccounts.Type.TOKEN ? "Session" : "Offline";
      }
}

   @Environment(EnvType.CLIENT)
   private static final class Store {
      List<MenuAccounts.Entry> accounts = new ArrayList<>();
   }

   @Environment(EnvType.CLIENT)
   public static enum Type {
      OFFLINE,
      TOKEN;

}
}
