package me.despawningbone.discordbot.command.info;

import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.time.OffsetDateTime;
import java.util.Arrays;
import java.util.Locale;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

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

public class Wikipedia extends Command {
	public Wikipedia() {
		this.desc = "Ask the almighty Wikipedia!";
		this.alias = Arrays.asList("wiki");
		this.usage = "[-lang] <search> [| index]";
		this.remarks = Arrays.asList("You can search a specific language's Wikipedia with the parameter, as long as there is a valid subdomain for that language,", "e.g. `en.wikipedia.org` or `ja.wikipedia.org`.");
		this.examples = Arrays.asList("C++", "ping | 4", "-ja 秋葉原");
	}

	@Override
	public CommandResult execute(TextChannel channel, User author, Message msg, String[] args) {  //DONE make use of XHR instead?
		if (args.length < 1) {
			return new CommandResult(CommandResultType.INVALIDARGS, "Search something :joy:");
		}
		try {
			String lang = "en";
			if(args.length > 1 && args[0].startsWith("-")) {
				lang = args[0].substring(1);
				args = Arrays.copyOfRange(args, 1, args.length);
			}
			
			String[] split = String.join(" ", args).split(" \\|");
			String sword = split[0];
			int index = 0;
			try {
				if(split.length > 1) {
					index = Integer.parseInt(split[1].trim()) - 1;	
					if(index < 1 || index > 10) throw new NumberFormatException();
				}
			} catch (NumberFormatException e) {
				channel.sendMessage("Invalid index inputted. Defaulting to first result...").queue();
			}
			
			String search = URLEncoder.encode(sword, "UTF-8");
			
			String title;
			
			try {
				JSONObject s = new JSONObject(new JSONTokener(new URL("https://" + lang + ".wikipedia.org/w/api.php?action=query&format=json&list=search&srsearch=" + search).openStream()));
				title = URLEncoder.encode(s.getJSONObject("query").getJSONArray("search").getJSONObject(index).getString("title"), "UTF-8").replaceAll("\\+", "%20");
			} catch(IOException e) {  //usually caused by wrong language wiki
				return new CommandResult(CommandResultType.INVALIDARGS, "Unknown wiki language version specified.");
			} catch(JSONException e) {
				return new CommandResult(CommandResultType.INVALIDARGS, "There are not enough results for your specified index!");
			}
			
			JSONObject result = new JSONObject(new JSONTokener(new URL("https://" + lang + ".wikipedia.org/api/rest_v1/page/summary/" + title).openStream()));
			
			//TODO do something with type = disambiguition?
			
			EmbedBuilder eb = new EmbedBuilder();
			
			eb.setAuthor(new Locale(result.getString("lang")).getDisplayName(Locale.ENGLISH) + " Wikipedia");  //DONE add support for other languages?
			if(result.has("thumbnail")) eb.setThumbnail(result.getJSONObject("thumbnail").getString("source"));
			eb.setTitle(result.getString("displaytitle").replaceAll("</{0,1}i>", "*"), result.getJSONObject("content_urls").getJSONObject("desktop").getString("page"));
			eb.setDescription(result.getString("extract"));
			eb.setFooter("Last revision id " + result.getString("revision"), "https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2.png");
			eb.setTimestamp(OffsetDateTime.parse(result.getString("timestamp")));
			
			channel.sendMessageEmbeds(eb.build()).queue();
			return new CommandResult(CommandResultType.SUCCESS);   //add searched result name?
		} catch (Exception e) {
			return new CommandResult(CommandResultType.ERROR, ExceptionUtils.getStackTrace(e));
		}
	}
}
