package no.valg.valgnatt.backend.parser;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import no.valg.valgnatt.database.domene.OpptaltStatus;
import no.valg.valgnatt.database.domene.StemmeType;

class Stemmeresultater {

	/**
	 * Opptaltstatus for innrapportering har følgende verdier
	 * 0.	Ingen resultater innsendt
	 * 1.	Bare foreløpige fhs innsendt
	 * 2.	Bare endelige fhs innsendt
	 * 3.	Bare foreløpige vts innsendt
	 * 4.	Bare endelige vts innsendt
	 * 5.	Både foreløpige fhs og foreløpige vts innsendt
	 * 6.	Både endelige fhs og foreløpige vts innsendt
	 * 7.	Både foreløpige fhs og endelige vts innsendt
	 * 8.	Både endelige fhs og endelige vts innsendt
	 * 9.   Oppgjør er sendt inn
	 *
	 * NB! Se forøvrig OpptaltStatus-klassen, som er enum-representasjonen av disse statusene
	 * NB! Status 9 fremkommer ikke her, det håndteres i Skjemadata-klassen
	 */

	// 3x3 matrise for å konvertere fra vts/fhs-status til opptaltstatus
	private static final int[][] KONVERTERINGSTABELL = new int[][]{
			{OpptaltStatus.INGEN.getStatus(), OpptaltStatus.BARE_FHS_FORELØPIG.getStatus(), OpptaltStatus.BARE_FHS_ENDELIG.getStatus()},
			{OpptaltStatus.BARE_VTS_FORELØPIG.getStatus(), OpptaltStatus.ALLE_FORELØPIG.getStatus(), OpptaltStatus.FHS_END_VTS_FPG.getStatus()},
			{OpptaltStatus.BARE_VTS_ENDELIG.getStatus(), OpptaltStatus.FHS_FPG_VTS_END.getStatus(), OpptaltStatus.ALLE_ENDELIG.getStatus()},
	};
	private Map<String, Map<StemmeType, Integer>> stemmerPrStemmeTypePrParti = new TreeMap();
	// Disse settes til true dersom det oppdages en slik stemmetype gjennom oppdaterPartiStemmer()
	private boolean fhsForeløpig = false;
	private boolean vtsForeløpig = false;
	private boolean fhsEndelig = false;
	private boolean vtsEndelig = false;

	int getOpptaltStatus() {
		int vts = vtsEndelig ? 2 : vtsForeløpig ? 1 : 0;
		int fhs = fhsEndelig ? 2 : fhsForeløpig ? 1 : 0;
		return KONVERTERINGSTABELL[vts][fhs];
	}

	void oppdaterPartiStemmer(StemmeType type, String parti, int antallStemmer) {
		Map<StemmeType, Integer> stemmerPrStemmeType = stemmerPrStemmeTypePrParti.computeIfAbsent(parti, k -> new HashMap<>());
		stemmerPrStemmeType.put(type, antallStemmer);


		if (type == StemmeType.FHS_FPG) {
			fhsForeløpig = true;
		}
		if (type == StemmeType.VTS_FPG) {
			vtsForeløpig = true;
		}
		if (type == StemmeType.FHS_END) {
			fhsEndelig = true;
		}
		if (type == StemmeType.VTS_END) {
			vtsEndelig = true;
		}
	}

	List<String> getPartikoder() {
		return new ArrayList(stemmerPrStemmeTypePrParti.keySet());
	}


	int getFhs(String partikode) {
		// forutsetter at man bruker en partikode som man har fått fra metoden getPartikoder()
		Integer endFhs = stemmerPrStemmeTypePrParti.get(partikode).get(StemmeType.FHS_END);
		if (!fhsEndelig && endFhs == null) {
			return toInt(stemmerPrStemmeTypePrParti.get(partikode).get(StemmeType.FHS_FPG));
		} else {
			return toInt(endFhs);
		}
	}

	private int toInt(Integer i) {
		return i == null ? 0 : i;
	}

	int getVts(String partikode) {
		// forutsetter at man bruker en partikode som man har fått fra metoden getPartikoder()
		Integer endFhs = stemmerPrStemmeTypePrParti.get(partikode).get(StemmeType.VTS_END);
		if (!vtsEndelig && endFhs == null) {
			return toInt(stemmerPrStemmeTypePrParti.get(partikode).get(StemmeType.VTS_FPG));
		} else {
			return toInt(endFhs);
		}
	}

	int getListestemmer(String partikode) {
		return toInt(stemmerPrStemmeTypePrParti.get(partikode).get(StemmeType.END_LIST));
	}
}
