package me.despawningbone.discordbot.command.admin;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.exception.ExceptionUtils;

import me.despawningbone.discordbot.DiscordBot;
import me.despawningbone.discordbot.command.Command;
import me.despawningbone.discordbot.command.CommandResult;
import me.despawningbone.discordbot.command.CommandResult.CommandResultType;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User;

public class UserReport extends Command {
	public UserReport() {
		this.alias = Arrays.asList("ureport");
		this.desc = "Report a user if they are abusing the bot!";
		this.usage = "<userID/username>";
		this.remarks = Arrays.asList("Note: 5 global reports will result in a ban from the bot.");
		this.examples = Arrays.asList(DiscordBot.OwnerID, "despawningbone");
	}

	@Override
	public CommandResult execute(TextChannel channel, User author, Message msg, String[] args) {
		if (args.length < 1) {
			return new CommandResult(CommandResultType.INVALIDARGS, "Please specify which user you want to report.");
		} else {
			String SID = null;
			boolean success = true;
			String pname = String.join(" ", args);
			long ID = 0;
			try {
				ID = Long.parseLong(pname);
			} catch (NumberFormatException e) {
				success = false;
				// System.out.println(pname); //debug
				List<Member> pm = channel.getGuild().getMembersByEffectiveName(pname, true);
				if (pm.size() <= 0) {
					return new CommandResult(CommandResultType.FAILURE, "There is no such user.");
				} else if (pm.size() > 1) {
					return new CommandResult(CommandResultType.FAILURE, "Theres more than 1 user with the same name. Please use !desp ID to get the ID of the user you want to report.");
				} else {
					SID = pm.get(0).getUser().getId();
					ID = Long.parseLong(SID);
				}
			}
			if (success == true) {
				SID = Long.toString(ID);
			}
			if (author.getId().equals(SID)) {
				return new CommandResult(CommandResultType.FAILURE, "You cannot report yourself you dumbo :stuck_out_tongue:");
			} else if (DiscordBot.ModID.contains(SID) || SID.equals(DiscordBot.BotID)) {
				return new CommandResult(CommandResultType.FAILURE, "That user cannot be reported.");
			}
			
			try (Connection con = DiscordBot.db.getConnection(); Statement s = con.createStatement()) {
				String reports = "";
				ResultSet uRs = s.executeQuery("SELECT reports FROM users WHERE id = " + SID + ";");
				if(uRs.next()) {
					reports = uRs.getString(1); 
					if(reports.contains(author.getId())) {
						return new CommandResult(CommandResultType.FAILURE, "You cannot report a user more than once.");  //make it so that its toggling the reports instead?
					} else if(reports.split("\n").length < 5){
						  reports += author.getId() + "\n";
					} else {
						return new CommandResult(CommandResultType.FAILURE, "The user has already been banned!");
					}
				} else {
					reports = author.getId() + "\n";
				}
				PreparedStatement set = con.prepareStatement("INSERT INTO users(id, reports) VALUES (?, ?) ON CONFLICT(id) DO UPDATE SET reports = ?" );
				set.setString(1, SID);
				set.setString(2, reports); set.setString(3, reports);
				int update = set.executeUpdate();
				if(update != 0) {
					int times = reports.split("\n").length;
					channel.sendMessage("You have successfully reported <@!" + ID + ">.\nThe user has been reported for "
							+ times + "/5 times.\n").queue();
					if(times >= 5) {
						channel.sendMessage("The user <@!" + ID + "> is now banned from using the bot.").queue();
					}
					return new CommandResult(CommandResultType.SUCCESS);
				} else {
					throw new IllegalArgumentException("This should never happen");
				}
			} catch (SQLException e) {
				return new CommandResult(CommandResultType.ERROR, ExceptionUtils.getStackTrace(e));
			}
			
			/*for (int i = 0; i < DiscordBot.reportedlist.size(); i++) {
				String[] randrp = DiscordBot.reportedlist.get(i).split(" ");
				if (randrp[0].contains(author.getId()) && randrp[1].contains(SID)) {
					return new CommandResult(CommandResultType.FAILURE, "You cannot report a user more than once.");
				}
			}
			boolean banned = false;
			boolean contains = false;
			for (int i = 0; i < DiscordBot.playerreportlist.size(); i++) {
				if (DiscordBot.playerreportlist.get(i).contains(SID)) {
					contains = true;
				}
			}
			if (contains == false) {
				DiscordBot.playerreportlist.add(SID + " " + "1");
				times = 1;
				FileWriter fileWriter = null;
				BufferedWriter bufferedWriter;
				try {
					fileWriter = new FileWriter(DiscordBot.pfile, true);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				try {
					bufferedWriter = new BufferedWriter(fileWriter);
					bufferedWriter.write(SID + " " + "1" + "\r\n");
					bufferedWriter.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			} else {
				// System.out.println("Got record");//debug
				for (int i = 0; i < DiscordBot.playerreportlist.size(); i++) {
					String[] pandt = DiscordBot.playerreportlist.get(i).split(" ");
					if (pandt[0].contains(SID)) {
						times = Long.parseLong(pandt[1]);
						// System.out.println(times); //debug
						if (times < 5) {
							times = times + (long) 1;
							// System.out.println(times); //debug
							if (times == 5) {
								DiscordBot.BannedID.add(Long.toString(ID));
								banned = true;
							}
							DiscordBot.playerreportlist.set(i, SID + " " + Long.toString(times));
							Path fp = Paths.get(System.getProperty("user.dir"), "PlayerReports.txt");
							try {
								List<String> fileContent = new ArrayList<>(
										Files.readAllLines(fp, StandardCharsets.UTF_8));

								for (int f = 0; f < fileContent.size(); f++) {
									if (fileContent.get(f).startsWith(SID)) {
										fileContent.set(f, SID + " " + Long.toString(times));
										break;
									}
								}

								Files.write(fp, fileContent, StandardCharsets.UTF_8);
							} catch (IOException e) {
								e.printStackTrace();
							}

							break;
						} else {
							if (!DiscordBot.BannedID.contains(String.valueOf(ID))) {
								DiscordBot.BannedID.add(Long.toString(ID));
							}
							return new CommandResult(CommandResultType.FAILURE, "The user <@!" + ID
									+ "> had enough reports therefore he is banned from using this bot.");
						}
					}
				}
			}
			DiscordBot.reportedlist.add(author.getId() + " " + SID);
			channel.sendMessage("You have successfully reported <@!" + ID + ">.\nThe user has been reported for "
					+ times + "/5 times.\n").queue();
			String addinfo = null;
			if (banned == true) {
				channel.sendMessage("The user <@!" + ID + "> is now banned from using the bot.").queue();
				addinfo = channel.getGuild().getMemberById(SID).getEffectiveName() + " (" + SID
						+ ") is banned from the bot.";
			}
			return new CommandResult(CommandResultType.SUCCESS, addinfo);*/
		}
	}
}
