package core.entities;

import java.awt.Color;
import java.text.DecimalFormat;
import java.util.HashMap;

import core.util.Utils;
import core.Database;
import core.util.Trigger;
import net.dv8tion.jda.core.OnlineStatus;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.User;

// Server class; Controls bot actions for each server
public class Server {
	private String id;
	private Guild guild;
	private Settings settings;
	private QueueManager qm;
	private HashMap<User, Long> activityList = new HashMap<User, Long>();
	
	public Commands cmds;

	public Server(Guild guild) {
		this.guild = guild;
		this.id = guild.getId();
		Utils.createDir(String.format("%s/%s", "app_data", id));
		qm = new QueueManager(id);
		cmds = new Commands();
		settings = new Settings(id);
		qm.getQueueList().forEach((q) -> q.getPlayersInQueue().forEach((u) -> updateActivityList(u)));
		
		// Insert guild into database
		Database.insertDiscordServer(guild.getIdLong(), guild.getName());
		// Insert members into database
		for(Member m : guild.getMembers()){
			Database.insertPlayer(m.getUser().getIdLong(), m.getEffectiveName());
		}
		
		startAFKTimer();
	}

	public String getid() {
		return id;
	}

	public QueueManager getQueueManager() {
		return qm;
	}

	public Settings getSettings() {
		return settings;
	}

	public TextChannel getPugChannel() {
		for (TextChannel c : guild.getTextChannels()) {
			if (c.getName().equalsIgnoreCase(settings.pugChannel())) {
				return c;
			}
		}
		return guild.getDefaultChannel();
	}
	
	private void startAFKTimer() {
		Trigger tt = () -> afkTimerEnd();
		Timer afkTimer = new Timer(60, tt);
		afkTimer.start();
	}

	private void afkTimerEnd() {
		activityList.forEach((u, l) -> {
			if (qm.isPlayerInQueue(u) && (System.currentTimeMillis() - l) / 60000 >= settings.afkTime()) {
				qm.deletePlayer(u);
				String s = String.format("%s has been removed from the queue due to inactivity", u.getName());
				getPugChannel().sendMessage(Utils.createMessage("", s, Color.red)).queue();
				u.openPrivateChannel().complete().sendMessage("You have been removed from the queue due to inactivity")
						.queue();
				qm.updateTopic();
				System.out.println(s);
			}
			activityList.remove(u);
		});

		startAFKTimer();
	}

	private void startDcTimer(Member m) {
		Trigger trigger = () -> dcTimerEnd(m);
		Timer timer = new Timer(settings.dcTime(), trigger);
		timer.start();
		System.out.println(String.format("User %s has gone offline, starting dc timer", m.getEffectiveName()));
	}

	private void dcTimerEnd(Member m) {
		if (m.getOnlineStatus().equals(OnlineStatus.OFFLINE) && qm.isPlayerInQueue(m.getUser())) {
			qm.deletePlayer(m.getUser());
			qm.updateTopic();
			String s = String.format("%s has been removed from queue after being offline for %s minutes", m.getEffectiveName(), new DecimalFormat("#.##").format((double)settings.dcTime()/60));
			getPugChannel().sendMessage(Utils.createMessage("", s,Color.red)).queue();
			System.out.println(s);
		}
	}
	
	public void updateActivityList(User u){
		if(qm.isPlayerInQueue(u) || qm.hasPlayerJustFinished(u)){
			activityList.put(u, System.currentTimeMillis());
		}
	}
	
	public void playerDisconnect(Member m){
		if(qm.isPlayerInQueue(m.getUser()) || qm.hasPlayerJustFinished(m.getUser())){
			startDcTimer(m);
		}
	}
	
	public Guild getGuild(){
		return guild;
	}
	
	public void setGuild(Guild guild){
		this.guild = guild;
	}
}

@@ -2311,35 +2311,8 @@
 %09%09%7D%0A
-%09%09%09activityList.remove(u);%0A
 %09%09%7D)

Fix exception caused by removing player from activityList