package land.chipmunk.chipmunkmod.commands;

import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.gui.screen.multiplayer.ConnectScreen;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.client.network.ServerAddress;
import net.minecraft.client.session.Session;
import net.minecraft.text.Text;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import java.util.Optional;
import java.util.UUID;

import land.chipmunk.chipmunkmod.mixin.MinecraftClientAccessor;

public class UsernameCommand {
  private static final Session ORIGINAL_SESSION = ((MinecraftClientAccessor) MinecraftClient.getInstance()).session();
  private static final SimpleCommandExceptionType USERNAME_TOO_LONG = new SimpleCommandExceptionType(Text.translatable("The specified username is longer than 16 characters"));

  public static void register (CommandDispatcher<FabricClientCommandSource> dispatcher) {
    dispatcher.register(
      literal("username")
        .then(
          literal("set")
            .then(
              argument("username", greedyString())
                .executes(c -> updateUsername(c))
            )
        )
        .then(
          literal("revert")
            .executes(c -> updateSession(c, ORIGINAL_SESSION))
        )
    );
  }

  public static int updateUsername (CommandContext<FabricClientCommandSource> context) throws CommandSyntaxException {
    final String username = getString(context, "username");
    if (username.length() > 16) throw USERNAME_TOO_LONG.create();
    final Session session = new Session(username, new UUID(0L, 0L), "", Optional.empty(), Optional.empty(), Session.AccountType.MOJANG);
    return updateSession(context, session);
  }

  public static int updateSession (CommandContext<FabricClientCommandSource> context, Session session) throws CommandSyntaxException {
    final FabricClientCommandSource source = context.getSource();

    final MinecraftClient client = source.getClient();

    ((MinecraftClientAccessor) client).session(session);

    // TODO: Put this in a separate class
    final ServerInfo info = client.getCurrentServerEntry();
    client.world.disconnect();
    client.disconnect();
    ConnectScreen.connect(new TitleScreen(), client, ServerAddress.parse(info.address), info, false, null);

    return Command.SINGLE_SUCCESS;
  }
}
