package co.phoenixlab.discord;

import co.phoenixlab.discord.api.DiscordApiClient;
import co.phoenixlab.discord.api.entities.Channel;
import co.phoenixlab.discord.api.entities.Message;
import co.phoenixlab.discord.api.entities.Server;
import co.phoenixlab.discord.api.entities.User;
import co.phoenixlab.discord.api.event.MemberChangeEvent;
import co.phoenixlab.discord.api.event.MessageReceivedEvent;
import co.phoenixlab.discord.api.event.ServerJoinLeaveEvent;
import com.google.common.eventbus.Subscribe;

public class EventListener {

    private final VahrhedralBot bot;

    public EventListener(VahrhedralBot bot) {
        this.bot = bot;
    }

    @Subscribe
    public void onMessageRecieved(MessageReceivedEvent messageReceivedEvent) {
        Message message = messageReceivedEvent.getMessage();
        if (message.getContent().startsWith(bot.getConfig().getCommandPrefix())) {
            bot.getMainCommandDispatcher().handleCommand(message);
            return;
        }
        User me = bot.getApiClient().getClientUser();
        for (User user : message.getMentions()) {
            if (me.equals(user)) {
                handleMention(message);
                return;
            }
        }
    }

    private void handleMention(Message message) {
        String otherId = message.getAuthor().getId();
        bot.getApiClient().sendMessage(bot.getLocalizer().localize("message.mention.response",
                message.getAuthor().getUsername()),
                message.getChannelId(), new String[] {otherId});
    }

    @Subscribe
    public void onServerJoinLeave(ServerJoinLeaveEvent event) {
        if (event.isJoin()) {
            Server server = event.getServer();
            //  Default channel has same ID as server
            Channel channel = bot.getApiClient().getChannelById(server.getId());
            if (channel != DiscordApiClient.NO_CHANNEL) {
                bot.getApiClient().sendMessage(bot.getLocalizer().localize("message.on_join.response",
                        bot.getApiClient().getClientUser().getUsername()),
                        channel.getId());
            }
        }
    }

    @Subscribe
    public void onMemberChangeEvent(MemberChangeEvent event) {
        if (event.getMemberChange() == MemberChangeEvent.MemberChange.ADDED) {
            Server server = event.getServer();
            //  TODO TEMPORARY Disable for servers with more than 100 people
            //  until per-server feature controls are implemented
            if (server.getMembers().size() > 100) {
                return;
            }
            //  Default channel has same ID as server
            Channel channel = bot.getApiClient().getChannelById(server.getId());
            if (channel != DiscordApiClient.NO_CHANNEL) {
                bot.getApiClient().sendMessage(bot.getLocalizer().localize("message.new_member.response",
                        event.getMember().getUser().getUsername()),
                        channel.getId());
            }
        }
    }


}

@@ -502,16 +502,127 @@
 cribe;%0A%0A
+import java.util.HashMap;%0Aimport java.util.Map;%0Aimport java.util.Objects;%0Aimport java.util.function.Consumer;%0A%0A
 public c
@@ -681,16 +681,78 @@
 t bot;%0A%0A
+    private Map%3CString, Consumer%3CMessage%3E%3E messageListeners;%0A%0A
     publ
@@ -813,16 +813,384 @@
  = bot;%0A
+        messageListeners = new HashMap%3C%3E();%0A        messageListeners.put(%22mention-bot%22, message -%3E %7B%0A            User me = bot.getApiClient().getClientUser();%0A            for (User user : message.getMentions()) %7B%0A                if (me.equals(user)) %7B%0A                    handleMention(message);%0A                    return;%0A                %7D%0A            %7D%0A        %7D);%0A
     %7D%0A%0A 
@@ -1535,226 +1535,66 @@
     
-User me = bot.getApiClient().getClientUser();%0A        for (User user : message.getMentions()) %7B%0A            if (me.equals(user)) %7B%0A                handleMention(message);%0A                return;%0A            %7D%0A        %7D
+messageListeners.values().forEach(c -%3E c.accept(message));
 %0A   
@@ -3397,11 +3397,317 @@
 %0A    %7D%0A%0A
+    public void registerMessageListner(String name, Consumer%3CMessage%3E listener) %7B%0A        messageListeners.put(Objects.requireNonNull(name), Objects.requireNonNull(listener));%0A    %7D%0A%0A    public void deleteMessageListener(String name) %7B%0A        messageListeners.remove(Objects.requireNonNull(name));%0A    %7D%0A%0A
 %0A%7D%0A

Add message listener framework