// Path: app/src/main/java/ultimategdbot/Strings.java
// public final class Strings {
// 
//     public static final String GENERAL = "GeneralStrings";
//     public static final String GD = "GDStrings";
// 
//     private Strings() {
//         throw new AssertionError();
//     }
// }
// 
// Path: app/src/main/java/ultimategdbot/util/EmbedType.java
// public enum EmbedType {
//     USER_PROMOTED(tr -> tr.translate(Strings.GD, "gdevents_title_promoted"), "https://i.imgur.com/zY61GDD.png"),
//     USER_DEMOTED(tr -> tr.translate(Strings.GD, "gdevents_title_demoted"), "https://i.imgur.com/X53HV7d.png"),
//     USER_PROFILE(tr -> tr.translate(Strings.GD, "user_profile"), "https://i.imgur.com/ppg4HqJ.png"),
//     LEVEL_SEARCH_RESULT(tr -> tr.translate(Strings.GD, "search_result"), "https://i.imgur.com/a9B6LyS.png"),
//     DAILY_LEVEL(tr -> tr.translate(Strings.GD, "daily"), "https://i.imgur.com/enpYuB8.png"),
//     WEEKLY_DEMON(tr -> tr.translate(Strings.GD, "weekly"), "https://i.imgur.com/kcsP5SN.png"),
//     RATE(tr -> tr.translate(Strings.GD, "gdevents_title_rate"), "https://i.imgur.com/asoMj1W.png"),
//     UNRATE(tr -> tr.translate(Strings.GD, "gdevents_title_unrate"), "https://i.imgur.com/fPECXUz.png"),
//     MOD(tr -> tr.translate(Strings.GD, "gdevents_title_promoted"), "https://i.imgur.com/zY61GDD.png"),
//     UNMOD(tr -> tr.translate(Strings.GD, "gdevents_title_demoted"), "https://i.imgur.com/X53HV7d.png");
// 
//     private final Function<Translator, String> authorName;
//     private final String authorIconUrl;
// 
//     EmbedType(Function<Translator, String> authorName, String authorIconUrl) {
//         this.authorName = authorName;
//         this.authorIconUrl = authorIconUrl;
//     }
// 
//     public String getAuthorName(Translator tr) {
//         return authorName.apply(tr);
//     }
// 
//     public String getAuthorIconUrl() {
//         return authorIconUrl;
//     }
// }
// 
// Path: app/src/main/java/ultimategdbot/util/GDFormatter.java
// public static String formatCode(Object val, int n) {
// 	var sb = new StringBuilder("" + val);
// 	for (var i = sb.length() ; i <= n ; i++) {
// 		sb.insert(0, " ‌‌");
// 	}
// 	sb.insert(0, '`').append('`');
// 	return sb.toString();
// }
// 
// Path: app/src/main/java/ultimategdbot/util/GDFormatter.java
// public static String formatPolicy(Translator tr, AccessPolicy policy) {
//        String str;
//        switch (policy) {
//            case NONE:
//                str = "policy_none";
//                break;
//            case FRIENDS_ONLY:
//                str = "policy_friends_only";
//                break;
//            case ALL:
//                str = "policy_all";
//                break;
//            default:
//                throw new AssertionError();
//        }
// 	return tr.translate(Strings.GD, str);
// }


import botrino.api.i18n.Translator;
import botrino.interaction.InteractionFailedException;
import com.github.alex1304.rdi.finder.annotation.RdiFactory;
import com.github.alex1304.rdi.finder.annotation.RdiService;
import discord4j.common.util.Snowflake;
import discord4j.core.GatewayDiscordClient;
import discord4j.core.object.entity.User;
import discord4j.core.spec.EmbedCreateSpec;
import discord4j.core.spec.MessageCreateFields.File;
import discord4j.core.spec.MessageCreateSpec;
import jdash.client.GDClient;
import jdash.common.IconType;
import jdash.common.Role;
import jdash.common.entity.GDUserProfile;
import jdash.graphics.GDUserIconSet;
import jdash.graphics.SpriteFactory;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import reactor.util.annotation.Nullable;
import ultimategdbot.Strings;
import ultimategdbot.util.EmbedType;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Random;
import java.util.stream.Collectors;
import static botrino.api.util.Markdown.italic;
import static discord4j.core.retriever.EntityRetrievalStrategy.STORE_FALLBACK_REST;
import static reactor.function.TupleUtils.function;
import static ultimategdbot.util.GDFormatter.formatCode;
import static ultimategdbot.util.GDFormatter.formatPolicy;
                for (var iconType : IconType.values()) {
                    icons.add(iconSet.generateIcon(iconType));
                }
            } catch (IllegalArgumentException e) {
                return Mono.just(new GeneratedIconSet(null, e.getMessage()));
            }
            final var iconSetImg = new BufferedImage(icons.stream().mapToInt(BufferedImage::getWidth).sum(),
                    icons.get(0).getHeight(), icons.get(0).getType());
            final var g = iconSetImg.createGraphics();
            var offset = 0;
            for (var icon : icons) {
                g.drawImage(icon, offset, 0, null);
                offset += icon.getWidth();
            }
            g.dispose();
            return imageStream(iconSetImg).map(inputStream -> new GeneratedIconSet(inputStream, null));
        });
    }

    public Mono<GDUserProfile> stringToUser(Translator tr, String str) {
        final var gdClient = this.gdClient.withWriteOnlyCache();
        if (!str.matches("[a-zA-Z0-9 _-]+")) {
            return Mono.error(new InteractionFailedException(tr.translate(Strings.GD, "error_invalid_characters")));
        }
        return gdClient.searchUsers(str, 0).next()
                .filter(user -> user.accountId() > 0)
                .flatMap(user -> gdClient.getUserProfile(user.accountId()));
    }

    private String statEntry(String emojiName, int stat) {
// Path: app/src/main/java/ultimategdbot/Strings.java
// public final class Strings {
// 
//     public static final String GENERAL = "GeneralStrings";
//     public static final String GD = "GDStrings";
// 
//     private Strings() {
//         throw new AssertionError();
//     }
// }
// 
// Path: app/src/main/java/ultimategdbot/util/EmbedType.java
// public enum EmbedType {
//     USER_PROMOTED(tr -> tr.translate(Strings.GD, "gdevents_title_promoted"), "https://i.imgur.com/zY61GDD.png"),
//     USER_DEMOTED(tr -> tr.translate(Strings.GD, "gdevents_title_demoted"), "https://i.imgur.com/X53HV7d.png"),
//     USER_PROFILE(tr -> tr.translate(Strings.GD, "user_profile"), "https://i.imgur.com/ppg4HqJ.png"),
//     LEVEL_SEARCH_RESULT(tr -> tr.translate(Strings.GD, "search_result"), "https://i.imgur.com/a9B6LyS.png"),
//     DAILY_LEVEL(tr -> tr.translate(Strings.GD, "daily"), "https://i.imgur.com/enpYuB8.png"),
//     WEEKLY_DEMON(tr -> tr.translate(Strings.GD, "weekly"), "https://i.imgur.com/kcsP5SN.png"),
//     RATE(tr -> tr.translate(Strings.GD, "gdevents_title_rate"), "https://i.imgur.com/asoMj1W.png"),
//     UNRATE(tr -> tr.translate(Strings.GD, "gdevents_title_unrate"), "https://i.imgur.com/fPECXUz.png"),
//     MOD(tr -> tr.translate(Strings.GD, "gdevents_title_promoted"), "https://i.imgur.com/zY61GDD.png"),
//     UNMOD(tr -> tr.translate(Strings.GD, "gdevents_title_demoted"), "https://i.imgur.com/X53HV7d.png");
// 
//     private final Function<Translator, String> authorName;
//     private final String authorIconUrl;
// 
//     EmbedType(Function<Translator, String> authorName, String authorIconUrl) {
//         this.authorName = authorName;
//         this.authorIconUrl = authorIconUrl;
//     }
// 
//     public String getAuthorName(Translator tr) {
//         return authorName.apply(tr);
//     }
// 
//     public String getAuthorIconUrl() {
//         return authorIconUrl;
//     }
// }
// 
// Path: app/src/main/java/ultimategdbot/util/GDFormatter.java
// public static String formatCode(Object val, int n) {
// 	var sb = new StringBuilder("" + val);
// 	for (var i = sb.length() ; i <= n ; i++) {
// 		sb.insert(0, " ‌‌");
// 	}
// 	sb.insert(0, '`').append('`');
// 	return sb.toString();
// }
// 
// Path: app/src/main/java/ultimategdbot/util/GDFormatter.java
// public static String formatPolicy(Translator tr, AccessPolicy policy) {
//        String str;
//        switch (policy) {
//            case NONE:
//                str = "policy_none";
//                break;
//            case FRIENDS_ONLY:
//                str = "policy_friends_only";
//                break;
//            case ALL:
//                str = "policy_all";
//                break;
//            default:
//                throw new AssertionError();
//        }
// 	return tr.translate(Strings.GD, str);
// }


// Path: app/src/main/java/ultimategdbot/service/GDUserService.java
import botrino.api.i18n.Translator;
import botrino.interaction.InteractionFailedException;
import com.github.alex1304.rdi.finder.annotation.RdiFactory;
import com.github.alex1304.rdi.finder.annotation.RdiService;
import discord4j.common.util.Snowflake;
import discord4j.core.GatewayDiscordClient;
import discord4j.core.object.entity.User;
import discord4j.core.spec.EmbedCreateSpec;
import discord4j.core.spec.MessageCreateFields.File;
import discord4j.core.spec.MessageCreateSpec;
import jdash.client.GDClient;
import jdash.common.IconType;
import jdash.common.Role;
import jdash.common.entity.GDUserProfile;
import jdash.graphics.GDUserIconSet;
import jdash.graphics.SpriteFactory;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import reactor.util.annotation.Nullable;
import ultimategdbot.Strings;
import ultimategdbot.util.EmbedType;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Random;
import java.util.stream.Collectors;
import static botrino.api.util.Markdown.italic;
import static discord4j.core.retriever.EntityRetrievalStrategy.STORE_FALLBACK_REST;
import static reactor.function.TupleUtils.function;
import static ultimategdbot.util.GDFormatter.formatCode;
import static ultimategdbot.util.GDFormatter.formatPolicy;

                for (var iconType : IconType.values()) {
                    icons.add(iconSet.generateIcon(iconType));
                }
            } catch (IllegalArgumentException e) {
                return Mono.just(new GeneratedIconSet(null, e.getMessage()));
            }
            final var iconSetImg = new BufferedImage(icons.stream().mapToInt(BufferedImage::getWidth).sum(),
                    icons.get(0).getHeight(), icons.get(0).getType());
            final var g = iconSetImg.createGraphics();
            var offset = 0;
            for (var icon : icons) {
                g.drawImage(icon, offset, 0, null);
                offset += icon.getWidth();
            }
            g.dispose();
            return imageStream(iconSetImg).map(inputStream -> new GeneratedIconSet(inputStream, null));
        });
    }

    public Mono<GDUserProfile> stringToUser(Translator tr, String str) {
        final var gdClient = this.gdClient.withWriteOnlyCache();
        if (!str.matches("[a-zA-Z0-9 _-]+")) {
            return Mono.error(new InteractionFailedException(tr.translate(Strings.GD, "error_invalid_characters")));
        }
        return gdClient.searchUsers(str, 0).next()
                .filter(user -> user.accountId() > 0)
                .flatMap(user -> gdClient.getUserProfile(user.accountId()));
    }

    private String statEntry(String emojiName, int stat) {
        return emoji.get(emojiName) + "  " + formatCode(stat, 9) + '\n';