package me.despawningbone.discordbot.command.info;

import java.io.IOException;
import java.time.OffsetDateTime;
import java.util.Arrays;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

import org.jsoup.Jsoup;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.jsoup.Connection;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.nodes.Document;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

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 Translate extends Command {
	public Translate() {
		this.desc = "Translate some sentences!";
		this.usage = "[-fromlang] <sentence> [-tolang]";
		this.remarks = Arrays.asList("Supported Languages: `en, ja, zh, de, es, fr, it, ru, pl, pt, nl`");
		this.examples = Arrays.asList("-ja あなたも文化人だと思います", "-es despacito");
		this.alias = Arrays.asList("tl");
		/*try {
			refresh();
			Response resp = Jsoup.connect("https://s.deepl.com/web/stats?request_type=jsonrpc").userAgent(agent)
					.requestBody("{\"jsonrpc\":\"2.0\",\"method\":\"WebAppPushStatistics\",\"params\":{\"value\":{\"instanceId\":\"" + cVars.getString("uid") + "\",\"event\":\"web/pageview\",\"url\":\"https://www.deepl.com/en/translator\",\"data\":{\"gaBlocked\":false,\"referrer\":\"https://www.google.com/\"}}},\"id\":" + id++ + "}").method(Method.POST).execute();
				cookie = resp.cookies().get("LMTBID");
				//System.out.println(cookie);	
		} catch(IOException e) {
			e.printStackTrace();
		}*/
		executor.scheduleAtFixedRate(() -> refresh(), 0, 450, TimeUnit.SECONDS);
	}
	
	private int id = (ThreadLocalRandom.current().nextInt(1000) + 1) * 100000 + 1;
	private String cookie = null, agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0";
	//private JSONObject cVars;  //old ver only
	//private boolean update = true;
	
	final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryBuilder().setDaemon(true).setNameFormat("tl-scheduler-%d").build());
	
	@Override 
	public CommandResult execute(TextChannel channel, User author, Message msg, String[] args) {
		//if(cookie == null) return new CommandResult(CommandResultType.FAILURE, "The translation service is unavailable right now!");  //disable of cookie not found
		
		try {
			String langF = "auto", langT = "EN", query = String.join(" ", args).replaceAll("\n", " ").replace("-", ""); //since it hates new lines and hyphens apparently
			if(Arrays.asList("-en", "-ja", "-zh", "-de", "-es", "-fr", "-it", "-ru", "-pl", "-pt", "-nl").contains(args[0].toLowerCase())) {
				langF = args[0].substring(1).toUpperCase();
				query = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
			}
			if(Arrays.asList("-en", "-ja", "-zh", "-de", "-es", "-fr", "-it", "-ru", "-pl", "-pt", "-nl").contains(args[args.length - 1].toLowerCase())) {
				langT = args[args.length - 1].substring(1).toUpperCase();
				query = query.substring(0, query.length() - 3);
			}
			if((args.length < 5 ? query.length() > 40 : args.length > 20)) return new CommandResult(CommandResultType.INVALIDARGS, "Please type a shorter phrase to translate!");
			//System.out.println(query);
			//System.out.println(id);
			//System.out.println("{\"jsonrpc\":\"2.0\",\"method\": \"LMT_handle_jobs\",\"params\":{\"jobs\":[{\"kind\":\"default\",\"raw_en_sentence\":\"" + query + "\",\"raw_en_context_before\":[],\"raw_en_context_after\":[],\"preferred_num_beams\":4,\"quality\":\"fast\"}]"
			//				+ ",\"lang\":{\"user_preferred_langs\":[\"JA\"],\"source_lang_user_selected\":\"auto\",\"target_lang\":\"" + langT + "\"},\"priority\":-1,\"timestamp\":" + OffsetDateTime.now().toEpochSecond() + "000},\"id\":" + id + "}");
			
			/*if(update) {
				refresh();
				update = false;
				executor.schedule(() -> update = true, 300, TimeUnit.SECONDS);
			}*/

			Connection con = Jsoup.connect("https://www2.deepl.com/jsonrpc").userAgent(agent)
			.requestBody("{\"jsonrpc\":\"2.0\",\"method\": \"LMT_handle_jobs\",\"params\":{\"jobs\":[{\"kind\":\"default\",\"raw_en_sentence\":\"" + query + "\",\"raw_en_context_before\":[],\"raw_en_context_after\":[],\"preferred_num_beams\":4" + ((args.length < 2 ? query.length() > 5 : args.length > 5) ? "" : ",\"quality\":\"fast\"") + "}],\"commonJobParams\":{}"
					+ ",\"lang\":{\"user_preferred_langs\":[\"EN\", \"JA\"],\"source_lang_user_selected\":\"" + langF + "\",\"target_lang\":\"" + langT + "\"},\"priority\":-1,\"timestamp\":" + OffsetDateTime.now().toEpochSecond() + "000},\"id\":" + id++ + "}");
			if(cookie != null) con.cookie("LMTBID", cookie);
			Response resp = con.method(Method.POST).execute();
			if(resp.hasCookie("LMTBID")) cookie = resp.cookie("LMTBID");
			Document doc = resp.parse();
			//System.out.println(doc.text());
			JSONObject main = new JSONObject(new JSONTokener(doc.text())).getJSONObject("result");
			EmbedBuilder eb = new EmbedBuilder();
			eb.setColor(0x0f2b46);
			eb.setTitle("Translation: " + (langF.equals("auto") ? main.getString("source_lang") + "(detected)" : langF) + " -> " + main.getString("target_lang"));
			eb.addField("Original", query, true);
			String tl = "";
			for(Object obj : main.getJSONArray("translations").getJSONObject(0).getJSONArray("beams")) {
				String p = ((JSONObject) obj).getString("postprocessed_sentence");
				if(tl.isEmpty()) tl = p + "\n";
				else tl += "*" + p + "*\n";
				
			}
			eb.addField("Translated", tl, true);
			eb.setFooter("Translated by DeepL", "https://egress.storeden.net/gallery/5a2577c9ffe48e7e4b418464");
			eb.setTimestamp(OffsetDateTime.now());
			channel.sendMessage(eb.build()).queue();
			return new CommandResult(CommandResultType.SUCCESS);
		} catch(IOException e) {
			String ex = ExceptionUtils.getStackTrace(e);
			/*if(ex.contains("Status=429")) {
				refresh();
				return execute(channel, author, msg, args);
			} else {
				return new CommandResult(CommandResultType.ERROR, ex);
			}*/
			return new CommandResult(CommandResultType.ERROR, ex);
		}
	}
	
	private void refresh() {
		//System.out.println(update);
		//System.out.println("{\"jsonrpc\":\"2.0\",\"method\":\"getClientState\",\"params\":{\"v\":\"20180814\"" + (cVars == null ? "" : "," + cVars.toString()) + "},\"id\":" + id++ + "}");
		Connection con = Jsoup.connect("https://www.deepl.com/PHP/backend/clientState.php?request_type=jsonrpc&il=EN").userAgent(agent)
		.requestBody("{\"jsonrpc\":\"2.0\",\"method\":\"getClientState\",\"params\":{\"v\":\"20180814\"" + /*(cVars == null ? "" : ",\"clientVars\":" + cVars.toString()) + */"},\"id\":" + id++ + "}");
		if(cookie != null) con.cookie("LMTBID", cookie);
		
		//JSONObject json = new JSONObject(new JSONTokener(con.post().text()));
		//System.out.println(json);
		//if(cVars == null) cVars = json.getJSONObject("result").getJSONObject("clientVars");
		
	}
}
