package de.blackcraze.grb.commands;

import de.blackcraze.grb.core.BotConfig;
import de.blackcraze.grb.core.Speaker;
import de.blackcraze.grb.i18n.Resource;
import de.blackcraze.grb.model.entity.Mate;
import de.blackcraze.grb.model.entity.StockType;
import de.blackcraze.grb.util.CommandUtils;
import net.dv8tion.jda.core.entities.Message;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static de.blackcraze.grb.util.CommandUtils.*;
import static de.blackcraze.grb.util.InjectorUtils.*;
import static de.blackcraze.grb.util.PrintUtils.*;

@SuppressWarnings("unused")
public final class Commands {

	private Commands() {
	}


	public static void ping(Message message) {
		Speaker.say(message.getTextChannel(), Resource.getString("PONG", getResponseLocale(message)));
	}

	public static void config(Message message) {
		String config_action = CommandUtils.parse(message.getContent(), 2);
		BotConfig.ServerConfig instance = BotConfig.getConfig(message.getGuild());
		if (Objects.isNull(config_action)) {
			StringBuilder response = new StringBuilder();
			response.append("```\n");
			Field[] fields = BotConfig.ServerConfig.class.getDeclaredFields();

			for (Field field : fields) {
				Object value;
				try {
					value = field.get(instance);
				} catch (IllegalAccessException e) {
					e.printStackTrace();
					continue;
				}
				response.append(field.getName());
				response.append(": ");
				response.append(value.toString());
				response.append("\n");
			}
			response.append("```");
			Speaker.say(message.getTextChannel(), response.toString());
			return;
		}
		if ("set".equals(config_action.toLowerCase())) {
			String field = CommandUtils.parse(message.getContent(), 3);
			String value = CommandUtils.parse(message.getContent(), 4);
			if (Objects.isNull(field) || Objects.isNull(value)) {
				message.addReaction(Speaker.Reaction.FAILURE).queue();
				return;
			}
			try {
				Field declaredField = BotConfig.ServerConfig.class.getDeclaredField(field.toUpperCase());
				assert String.class.equals(declaredField.getType());
				declaredField.set(instance, value);
				message.addReaction(Speaker.Reaction.SUCCESS).queue();
			} catch (Exception e) {
				message.addReaction(Speaker.Reaction.FAILURE).queue();
				e.printStackTrace();
			}
		}
	}

	public static void status(Message message) {
		Runtime rt = Runtime.getRuntime();
		long total = rt.totalMemory();
		long free = rt.freeMemory();
		long used = total - free;

		String memConsume = String.format("~~ My Memory | Total:%,d | Used:%,d, Free:%,d", total, used, free);
		System.out.println(memConsume);
		Speaker.say(message.getTextChannel(), memConsume);
	}

	public static void update(Message message) {
		try {
			Map<String, Long> stocks = parseStocks(message);
			List<String> unknown = getMateDao().updateStocks(getOrCreateMate(message.getAuthor()), stocks);
			if (stocks.size() > 0) {
				if (!unknown.isEmpty()) {
					Speaker.err(message, String.format(Resource.getString("DO_NOT_KNOW_ABOUT", getResponseLocale(message)), unknown.toString()));
				}
				if (unknown.size() != stocks.size()) {
					message.addReaction(Speaker.Reaction.SUCCESS).queue();
				}
			} else {
				Speaker.err(message, Resource.getString("RESOURCES_EMPTY", getResponseLocale(message)));
			}
		} catch (Exception e) {
			e.printStackTrace();
			message.addReaction(Speaker.Reaction.FAILURE).queue();
		}
	}

	public static void checkTypes(Message message) {
		Speaker.say(message.getTextChannel(), prettyPrintStockTypes(getStockTypeDao().findAll(), getResponseLocale(message)));
	}


	public static void check(Message message) {
		String mateName = parseStockName(message.getContent(), true);
		if (Objects.isNull(mateName) || mateName.isEmpty()) {
			List<Mate> mates = Collections.singletonList(getOrCreateMate(message.getAuthor()));
			Speaker.say(message.getTextChannel(), prettyPrintMate(mates, getResponseLocale(message)));
		} else {
			List<Mate> mates = getMateDao().findByNameLike(mateName);
			if (!mates.isEmpty()) {
				Speaker.say(message.getTextChannel(), prettyPrintMate(mates, getResponseLocale(message)));
			}
			List<StockType> types = getStockTypeDao().findByNameLike(mateName);
			if (!types.isEmpty()) {
				Speaker.say(message.getTextChannel(), prettyPrintStocks(types, getResponseLocale(message)));
			}
			if (types.isEmpty() && mates.isEmpty()) {
				Speaker.say(message.getTextChannel(),Resource.getString("RESOURCE_AND_USER_UNKNOWN", getResponseLocale(message)));
			}
		}
	}
}

@@ -382,24 +382,27 @@
 ava.
-util.Collections
+lang.reflect.Method
 ;%0Aim
@@ -416,20 +416,17 @@
 va.util.
-List
+*
 ;%0Aimport
@@ -440,36 +440,24 @@
 til.
-Map;%0Aimport java.util.Obj
+stream.Coll
 ect
+or
 s;%0A%0A
@@ -4546,11 +4546,354 @@
 %7D%0A%09%09%7D%0A%09%7D
+%0A%0A%09public static void help(Message message) %7B%0A%09%09String response = Arrays.stream(Commands.class.getDeclaredMethods())%0A%09%09%09%09.map(Method::getName)%0A%09%09%09%09.collect(Collectors.joining(%0A%09%09%09%09%09%09%22%5Cn  %22,%0A%09%09%09%09%09%09%22%60%60%60%5Cn%22 + Resource.getString(%22COMMANDS%22, getResponseLocale(message)) + %22%5Cn  %22,%0A%09%09%09%09%09%09%22%60%60%60%22));%0A%09%09Speaker.say(message.getTextChannel(), response);%0A%09%7D
 %0A%7D%0A

Add help command