package no.valg.valgnatt.database.geografi;

import no.valg.valgnatt.database.domene.Valg;
import no.valg.valgnatt.database.domene.ValgtingForhand;

public class PartiStemmer implements Comparable<PartiStemmer> {

    private String partikode;
    private String partinavn;
    private String partikategori;
    private String visningssekvens;

    private boolean stillerliste;
    private int vts;
    private int fhs;
    private int listestemmer;
    private int sisteVts;
    private int sisteFhs;
    private int nestsisteVts;
    private int nestsisteFhs;

    // Settes bare når vi aggregerer opp totalt antall stemmer
    private PartiStemmer blankePartistemmer;

    public PartiStemmer(String partikode, String partinavn, String partikategori, String visningssekvens, boolean stillerliste) {
        this.partikode = partikode;
        this.partinavn = partinavn;
        this.partikategori = partikategori;
        this.visningssekvens = visningssekvens;
        this.stillerliste = stillerliste;
    }

    public String getPartikode() {
        return partikode;
    }

    public String getPartinavn() {
        return partinavn;
    }

    public String getPartikategori() {
        return partikategori;
    }

    public String getVisningssekvens() {
        return visningssekvens;
    }

    public int getVts() {
        return vts;
    }

    public int getFhs() {
        return fhs;
    }

    public int getStemmer() {
        return fhs + vts;
    }

    public int getStemmerBK() {
        if (blankePartistemmer != null) {
            return getStemmer() - blankePartistemmer.getStemmer();
        }
        return getStemmer();
    }
    
    public int getStemmerFhsBK() {
        if (blankePartistemmer != null) {
            return getFhs() - blankePartistemmer.getFhs();
        }
        return getFhs();
    }
    

    public int getStemmer(Valg valg, ValgtingForhand vf) {
        if (valg == Valg.DETTE) {
            return getStemmerDetteValg(vf);
        } else if (valg == Valg.SISTE) {
            return getStemmerSisteValg(vf);
        } else {
            return getStemmerNestSisteValg(vf);
        }
    }

    private int getStemmerNestSisteValg(ValgtingForhand vf) {
        return vf == null ? nestsisteFhs + nestsisteVts : vf == ValgtingForhand.F ? nestsisteFhs : nestsisteVts;
    }

    private int getStemmerSisteValg(ValgtingForhand vf) {
        return vf == null ? sisteFhs + sisteVts : vf == ValgtingForhand.F ? sisteFhs : sisteVts; // ingen listestemmer i siste valg
    }

    private int getStemmerDetteValg(ValgtingForhand vf) {
        return vf == null ? fhs + vts : vf == ValgtingForhand.F ? fhs : vf == ValgtingForhand.V ? vts : (int) listestemmer;
    }

    public int getSisteVts() {
        return sisteVts;
    }

    private int getSisteFhs() {
        return sisteFhs;
    }

    public int getSisteStemmer() {
        return sisteFhs + sisteVts;
    }

    public int getSisteStemmerBK() {
        if (blankePartistemmer != null) {
            return getSisteStemmer() - blankePartistemmer.getSisteStemmer();
        }
        return getSisteStemmer();
    }

    public int getNestsisteVts() {
        return nestsisteVts;
    }

    private int getNestsisteFhs() {
        return nestsisteFhs;
    }

    public int getNestsisteStemmer() {
        return nestsisteFhs + nestsisteVts;
    }

    public int getNestsisteStemmerBK() {
        if (blankePartistemmer != null) {
            return getNestsisteStemmer() - blankePartistemmer.getNestsisteStemmer();
        }
        return getNestsisteStemmer();
    }

    public void setVts(int vts) {
        this.vts = vts;
    }

    public void setFhs(int fhs) {
        this.fhs = fhs;
    }

    public int getListestemmer() {
        return listestemmer;
    }

    public void setListestemmer(int listestemmer) {
        this.listestemmer = listestemmer;
    }

    public void add(PartiStemmer parti) {
        this.vts += parti.getVts();
        this.fhs += parti.getFhs();
        this.listestemmer += parti.getListestemmer();
        this.sisteVts += parti.getSisteVts();
        this.sisteFhs += parti.getSisteFhs();
        this.nestsisteVts += parti.getNestsisteVts();
        this.nestsisteFhs += parti.getNestsisteFhs();
    }

    @Override
    public int compareTo(PartiStemmer o) {
        return visningssekvens.compareTo(o.getVisningssekvens());
    }

    @Override
    public boolean equals(Object o) {
        return o == null || getClass() != o.getClass() ? false : ((PartiStemmer) o).getPartikode().equals(this.getPartikode());
    }

    @Override
    public int hashCode() {
        return getPartikode().hashCode();
    }

    public void addSisteFhs(int sisteforhstemmer) {
        this.sisteFhs += sisteforhstemmer;
    }

    public void addSisteVts(int sistevalgstemmer) {
        this.sisteVts += sistevalgstemmer;
    }

    public void addNestsisteFhs(int nestsisteforhstemmer) {
        this.nestsisteFhs += nestsisteforhstemmer;
    }

    public void addNestsisteVts(int nestsistevalgstemmer) {
        this.nestsisteVts += nestsistevalgstemmer;
    }

    boolean isStillerliste() {
        return stillerliste;
    }

    void setBlankePartistemmer(PartiStemmer blankePartistemmer) {
        this.blankePartistemmer = blankePartistemmer;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder(String.format("%10s", partikode) + ", " + partikategori + ", " + visningssekvens + ", " + String.format("%5s", "" + stillerliste) + ", ");
        sb.append(String.format("%13s", fhs + "+" + vts) + "=" + String.format("%-7s", "" + (fhs + vts)) + String.format("%-20s", " (liste:" + listestemmer + "), "));
        sb.append(String.format("%13s", sisteFhs + "+" + sisteVts) + "=" + String.format("%-7s", "" + (sisteFhs + sisteVts)) + ", ");
        sb.append(String.format("%13s", nestsisteFhs + "+" + nestsisteVts) + "=" + String.format("%-7s", "" + (nestsisteFhs + nestsisteVts)));
        return sb.toString();
    }

    public void setSisteVts(int sisteVts) {
        this.sisteVts = sisteVts;
    }

    public void setSisteFhs(int sisteFhs) {
        this.sisteFhs = sisteFhs;
    }

    public void setNestsisteVts(int nestsisteVts) {
        this.nestsisteVts = nestsisteVts;
    }

    public void setNestsisteFhs(int nestsisteFhs) {
        this.nestsisteFhs = nestsisteFhs;
    }
}
