package me.despawningbone.discordbot.command.info;

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import me.despawningbone.discordbot.command.Command;
import me.despawningbone.discordbot.command.CommandResult;
import me.despawningbone.discordbot.command.CommandResult.CommandResultType;
import me.despawningbone.discordbot.utils.MiscUtils;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Activity.ActivityType;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User;

public class UserInfo extends Command {
	public UserInfo() {
		this.desc = "Get a user's information";
		this.usage = "[-a] [usertag/username]";
		this.alias = Arrays.asList("ui", "user");
		this.remarks = Arrays.asList("Leave blank for your own user info!", "", "* Specify the `-a` parameter to get a larger profile picture instead of a thumbnail.");
	}
	
	//DONE merge with ID.java?
	@Override
	public CommandResult execute(TextChannel channel, User author, Message msg, String[] args) {
		List<User> userList = msg.getMentionedUsers();
		User user = null;
		List<String> params = new ArrayList<>(Arrays.asList(args));
		boolean bigPfp = params.removeAll(Collections.singleton("-a"));  //pass by ref so it removes from the list 
		if (params.size() < 1) {
			user = author;
		} else {
			if (userList.isEmpty()) {
				String pname = String.join(" ", params);
				List<Member> pm = channel.getGuild().getMembersByEffectiveName(pname, true);
				if (pm.size() == 0) pm = channel.getGuild().getMembersByName(pname, true);
				if (pm.size() == 0) {
					return new CommandResult(CommandResultType.FAILURE, "There is no such user.");
				}
				if (pm.size() > 1) {
					return new CommandResult(CommandResultType.FAILURE, "Theres more than 1 user with the same name. Please use tags instead.\n");
				}
				user = pm.get(0).getUser();
			} else {
				if (userList.size() > 1) {
					return new CommandResult(CommandResultType.INVALIDARGS, "Please only enter one user.");
				}
				user = userList.get(0);
			}	
		}
		Member member = channel.getGuild().getMember(user);
		EmbedBuilder eb = new EmbedBuilder();
		eb.setTitle(user.getName() + "#" + user.getDiscriminator() + "'s " + (user.isBot() ? "bot" : "user") + " info");
		eb.addField("Tag", "<@!" + user.getId() + ">", true);
		eb.addField("ID", user.getId(), true);
		eb.addField("Nickname", member.getNickname() == null ? "N/A" : member.getNickname(), true);
		member.getActivities().forEach(game -> {
			String playing = game.getName();
			if(game.getType().equals(ActivityType.CUSTOM_STATUS)) playing = (game.getEmoji() == null ? "" : game.getEmoji().getAsMention()) + " " + (game.getName().equals("Custom Status") ? "" : game.getName());
			if(game.isRich()) {
				if(game.asRichPresence().getState() != null) playing += " - " + game.asRichPresence().getState();
				if(game.asRichPresence().getTimestamps() != null) playing += "\n (Elapsed: " + MiscUtils.convertMillis(game.asRichPresence().getTimestamps().getElapsedTime(ChronoUnit.MILLIS)) + ")";
			}
			eb.addField(game.getType().name().equals("DEFAULT") ? "Playing" : StringUtils.capitalize(game.getType().name().toLowerCase().replaceAll("_", " ")), playing, true);
		});
		if(member.getActivities().size() == 0) eb.addField("Playing", "N/A", true);  //add back N/A
		eb.addField("In voice", member.getVoiceState().inVoiceChannel() ? (member.getVoiceState().getChannel().getName() + (member.getVoiceState().isMuted() ? " (Muted)" : "")) : "N/A", true);
		eb.addField("Creation date", user.getTimeCreated().format(DateTimeFormatter.RFC_1123_DATE_TIME), true);
		eb.addField("Join date", member.getTimeJoined().format(DateTimeFormatter.RFC_1123_DATE_TIME), true);
		ArrayList<String> roleList = new ArrayList<>();
		for(Role role : member.getRoles()) {
			roleList.add(role.getName());
		}
		eb.addField("Roles (" + roleList.size() + ")", roleList.isEmpty() ? "N/A" : String.join(", ", roleList), false);
		eb.setColor(member.getColor());
		eb.setFooter(StringUtils.capitalize(member.getOnlineStatus().name().toLowerCase().replaceAll("_", " ")), null);
		eb.setTimestamp(OffsetDateTime.now());
		if(user.getAvatarUrl() != null) 
			if(bigPfp) eb.setImage(user.getAvatarUrl() + "?size=2048"); else eb.setThumbnail(user.getAvatarUrl() + "?size=1024");
		channel.sendMessageEmbeds(eb.build()).queue();
		return new CommandResult(CommandResultType.SUCCESS);
	}
}
