package xyz.thastertyn.Scrape;

import java.io.IOException;
import java.util.ArrayList;
import java.util.regex.Pattern;

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

import xyz.thastertyn.Types.Choice;
import xyz.thastertyn.Types.FinalMark;
import xyz.thastertyn.Types.Option;
import xyz.thastertyn.Types.Options;
import xyz.thastertyn.Types.Subject;
import xyz.thastertyn.Types.Mark;

public class Marks extends JecnaScrape {

	// schoolYear, schoolYearId
	private ArrayList<Subject> subjects;

	// int znaci id roku, boolean jestli je jen prvni nebo i druhe pololeti
	private Options schoolYearOptions;
	private Options schoolHalfYearOptions;

	public void download() throws IOException
	{
		download("https://www.spsejecna.cz/score/student");
	}
	
	@Override
	public void download(Choice choice) throws IOException
	{
		download(String.format(
			"https://www.spsejecna.cz/score/student?schoolYearId=%s&schoolYearHalfId=%s", 
			choice.getChoices().get(0), 
			choice.getChoices().get(1)));
	}

	private void download(String url) throws IOException
	{
		schoolHalfYearOptions = new Options("Pololeti");
		schoolYearOptions = new Options("Skolni R.");
		
		subjects = new ArrayList<>();
		Document marksHTMLDocument = Downloader.download(url);

		// Subjects stored as <tr>
		Elements[] subjectRowsHTML = marksHTMLDocument
			.select("table.score")
			.select("tr")
			.stream()
			.map(Element::children)
			.toArray(Elements[]::new);

		int subjectIndex = 0;

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

			// Attempt to shorten the subject name to the string in brackets
			String shortSubjectName = Pattern
				.compile("\\((.*?)\\)")
				.matcher(fullSubjectName)
				.results()
				.findFirst()
				.map(m -> m.group(1))
				.orElse(fullSubjectName);

			if(subjectRowsHTML[i].get(2).childrenSize() == 0) // Subject doesn't have final mark yet
			{
				subjects.add(new Subject(shortSubjectName));
			}else{
				String finalMark = subjectRowsHTML[i].get(2).select("a.scoreFinal").text();
				subjects.add(new Subject(shortSubjectName, FinalMark.fromValue(finalMark)));
			}

			for(Element znamkaElement : subjectRowsHTML[i].get(1).select("a.score"))
			{
				int mark;
				boolean isSmall = false;

				String markText = znamkaElement.select("span.value").text();

				mark = markText.matches("\\d") ?
					Integer.parseInt(markText)
					:
					-1; // Most likely N (Nehodnocen)

				// Small mark will be counted with smaller weight, compared to normal one
				isSmall = znamkaElement.hasClass("scoreSmall");

				subjects.get(subjectIndex).addMark(new Mark(mark, isSmall, markText));
			}

			subjectIndex++;
		}

		Element optionsPanel = marksHTMLDocument.selectFirst("form.listConfigure");
		
		Elements schoolYears = optionsPanel.select("select[id=schoolYearId]").select("option");
		Elements halfYears = optionsPanel.select("select[id=schoolYearHalfId]").select("option");

		
		for(Element e : schoolYears)
		{
			boolean isDefault = e.hasAttr("selected");
			schoolYearOptions.addOption(new Option(e.text(), e.attr("value"), isDefault));
		}

		for(Element e : halfYears)
		{
			boolean isDefault = e.hasAttr("selected");
			schoolHalfYearOptions.addOption(new Option(e.text(), e.attr("value"), isDefault));
		}
	}
	
	public ArrayList<Subject> getSubjects()
	{
		return subjects;
	}

	public Options[] getOptions()
	{
		return new Options[] {schoolYearOptions, schoolHalfYearOptions};
	}
}