package xyz.thastertyn.JecnaParse;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import xyz.thastertyn.Tuples.Pair;

public class Znamky {

	private boolean wasDownloaded;

	private ArrayList<Pair<String, Pair<ArrayList<Pair<Integer, Double>>,Double>>> grades = new ArrayList<>();

	// Integer znaci id roku, boolean jestli je jen prvni nebo i druhe pololeti
	private ArrayList<Pair<Integer, Boolean>> options = new ArrayList<>();

	public void downloadZnamky(/*, int schoolYearId, int schoolYearHalfId*/) throws UnknownHostException, IOException
	{
		//String url = String.format("https://www.spsejecna.cz/score/student?schoolYearId=%d&schoolYearHalfId=%d", schoolYearId, schoolYearHalfId);
		Document znamkyDoc = Downloader.download("https://www.spsejecna.cz/score/student").get();
		
		Elements rows = znamkyDoc.select("table.score").select("tr");

		Elements[] rows_split = new Elements[rows.size()];

		for (int i = 0; i < rows.size(); i++)
		{
			rows_split[i] = rows.get(i).children();
		}

		int subj = 0;

		for(int i = 1; i < rows_split.length; i++)
		{
			String predmetFull = rows_split[i].get(0).text();

			Matcher matcher = Pattern.compile("\\((.*)\\)").matcher(predmetFull);
			
			String predmet = matcher.find() ? matcher.group(1) : predmetFull;
			addSubject(predmet);
			
			for(Element znamkaElement : rows_split[i].get(1).select("a.score"))
			{
				if(znamkaElement == null)
				{
					break;
				}

				String zn = znamkaElement.select("span.value").text();
				int znamka;
				if(zn.toLowerCase().equals("n") || zn.toLowerCase().equals("u"))
				{
					znamka = -1;
				}else{
					znamka = Integer.parseInt(znamkaElement.select("span.value").text());
				}

				// Mala znamka se bude pocitat jako polovicni vaha
				if(znamkaElement.hasClass("scoreSmall"))
				{
					addGrade(subj, predmet, znamka, 0.5);
				}else{
					addGrade(subj, predmet, znamka, 1);
				}
			}

			grades.get(subj).getValue1().setValue1(getAverage(grades.get(subj).getValue1().getValue0()));
			subj++;
		}

		
/*
		Elements roky = znamkyDoc.select("select[name=schoolYearId]");
		Elements pololetiSelect = znamkyDoc.select("select[name=schoolYearHalfId]");

		for(Element e : roky)
		{
			boolean jeCelyRok = false;
	
			if(pololetiSelect.size() == 2)
			{
				jeCelyRok = true;
			}

			int rok = Integer.parseInt(e.attr("value"));

			options.add(new Pair<Integer, Boolean>(rok, jeCelyRok));
		}*/

		wasDownloaded = true;

	}

	private void addGrade(int index, String subject, int grade, double weight)
	{
		Pair<Integer, Double> znamka = new Pair<>(grade, weight);

		grades.get(index).getValue1().getValue0().add(znamka);
	}

	private void addSubject(String subject)
	{
		Pair<ArrayList<Pair<Integer, Double>>, Double> p = new Pair<>(new ArrayList<Pair<Integer, Double>>(), 0.0);

		grades.add(new Pair<>(subject, p));
	}

	private double getAverage(ArrayList<Pair<Integer, Double>> a)
	{
		try{
			double divident = 0;
			double divisor = 0;
			for(Pair<Integer, Double> p : a)
			{
				if(p.getValue0() == -1)
				{
					continue;
				}
				
				divident += p.getValue0() * p.getValue1();
				divisor += p.getValue1();
			}

			double prumer = (double) divident / divisor;
			return (double) Math.round(prumer * 100) / 100;

		}catch(ArithmeticException e)
		{
			return 0;
		}
	}

	
	public ArrayList<Pair<String, Pair<ArrayList<Pair<Integer, Double>>,Double>>> getGrades()
	{
		return grades;
	}

	public ArrayList<Pair<Integer, Boolean>> getOptions()
	{
		return options;
	}

	@Override
	public String toString()
	{
		if(wasDownloaded)
		{
			String s = "";
	
			for(Pair<String, Pair<ArrayList<Pair<Integer, Double>>,Double>> p : grades)
			{
				s += p.getValue0() + " | " + p.getValue1().getValue0().toString() + " { " + p.getValue1().getValue1() + " } ";
			}
			return s;
		}else{
			return "Nothing was downloaded";
		}
	}
}