package no.valg.valgnatt.database.hibernate;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import no.valg.valgnatt.database.Konstanter;
import no.valg.valgnatt.database.geografi.Kommune;
import no.valg.valgnatt.database.geografi.MandatData;
import no.valg.valgnatt.database.geografi.PartiMandater;

import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;

@Entity
@Table(name = "valgdistrikter")
@NoArgsConstructor //Hibernate-krav
@AllArgsConstructor //Builder-krav
@Builder
public class Valgdistrikt implements java.io.Serializable {

    @Getter
    @Setter
    @EmbeddedId
    private ValgdistriktId id;

    @Getter
    @Setter
    @Column(name = "navn", nullable = false, length = 140)
    private String navn;

    @Getter
    @Setter
    @Column(name = "antallmandater", nullable = false)
    private Integer antallmandater;

    private final transient Map<String, PartiMandater> partiMap = new TreeMap<>();
    private final transient Map<String, Kommune> kommuneMap = new TreeMap<>();
	
	public void addPartiMandater(PartiMandater partiMandater) {
		partiMap.put(partiMandater.getPartikode(), partiMandater);
	}

	public PartiMandater getPartiMandater(String partikode) {
		return partiMap.get(partikode);
	}

	public void putKommune(Kommune kommune) {
		kommuneMap.put(kommune.getNr(), kommune);
	}

	public Kommune getKommune(String kommnr) {
		return kommuneMap.get(kommnr);
	}

	// Disse stemmene er ikke nødvendigvis opptalte stemmer (som man finner under PartiStemmer-objektene i Stemmekretsene),
	// men kan også være prognostiserte stemmer. Man kan også hente ut listestemmer her (for kommuner i KO-valg), da det er
	// disse som skal benyttes i mandatberegningen om de finnes.
	// Vi logger blanke stemmer, men bruker dem aldri i mandatberegninger (derav fjernBlanke-boolean)
	public Map<String, Integer> getStemmerPrPartiTilMandatberegning(boolean børBenytteListestemmer, boolean fjernBlanke, boolean prognose) {
		Map<String, Integer> stemmerPrParti = new TreeMap<>();
		for (PartiMandater pm : this.getPartiMandater()) {
			if (pm.getPartikode().equals(Konstanter.BLANKE) && fjernBlanke) {
				continue;
			}
			MandatData md = prognose ? pm.getPrognoseData() : pm.getResultatData();
			if (pm.isStillerliste()) {
				stemmerPrParti.put(pm.getPartikode(), børBenytteListestemmer && listestemmerFinnes(md) ? md.getListestemmer() : md.getStemmer());
			}
		}
		return stemmerPrParti;
	}

	public Collection<PartiMandater> getPartiMandater() {
		return partiMap.values();
	}

	// Selv om man ønsker å benytte listestemmer så kan det være at det mangler (se Sør-Fron i KO-2011). Dersom liste-
	// stemmer er 0, så skyldes dette enten at stemmer også er 0, eller at man mangler listestemmer. I begge tilfeller
	// skal man da benytte vanlige stemmer.
	private boolean listestemmerFinnes(MandatData md) {
		return md.getListestemmer() > 0;
	}

}
