package de.ivu.elect.presentation.wahlvorschlag;

import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.NlGebiet;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;
import de.ivu.elect.business.wahlrechtspruefung.boundary.WahlrechtspruefungExtendedDAO;
import de.ivu.elect.business.wahlrechtspruefung.entity.NlPruefkriteriumAuswirkung;
import de.ivu.elect.business.wahlrechtspruefung.entity.Pruefkriterium;
import de.ivu.elect.business.wahlrechtspruefung.entity.WahlrechtspruefStatus;
import de.ivu.elect.business.wahlrechtspruefung.entity.Wahlrechtspruefung;
import de.ivu.elect.business.wahlvorschlag.boundary.ListeExtendedDAO;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import de.ivu.elect.business.wahlvorschlag.entity.StelInformationen;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nullable;
import javax.inject.Inject;
import java.io.Serializable;
import java.util.Collection;

public class NlListeActionHelper implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private transient ListeExtendedDAO listeExtendedDAO;

    @Inject
    private transient WahlrechtspruefungExtendedDAO wahlrechtspruefungExtendedDAO;

    @Inject
    private transient NlListeStelInformationCache nlListeStelInformationCache;

    public ActionHelperResult isRendered(@Nullable Liste liste, @Nullable Gebiet gebiet, @Nullable Pruefkriterium pruefkriterium) {
        return new ActionHelperResult(
                isButtonConfirmedWahlkreisRendered(liste, pruefkriterium),
                isButtonConfirmedStelRendered(liste, pruefkriterium),
                isButtonConfirmedGruppeRendered(liste, pruefkriterium));
    }


    public boolean isButtonConfirmedWahlkreisRendered(@Nullable Liste liste, @Nullable Pruefkriterium pruefkriterium) {
        return isAbgelehnt(liste) || isEinzelliste(liste) || (isIdentischeListe(liste) || isEchterStel(liste)) && isKriteriumFuerWahlkreisMoeglich(pruefkriterium) ||
                isUnechterStel(liste) && (isKriteriumFuerWahlkreisMoeglich(pruefkriterium) || isKriteriumFuerStelMoeglich(pruefkriterium));
    }

    public boolean isButtonConfirmedStelRendered(@Nullable Liste liste, @Nullable Pruefkriterium pruefkriterium) {
        return isEchterStel(liste) && (isKriteriumFuerWahlkreisMoeglich(pruefkriterium) || isKriteriumFuerStelMoeglich(pruefkriterium));
    }

    public boolean isButtonConfirmedGruppeRendered(@Nullable Liste liste, @Nullable Pruefkriterium pruefkriterium) {
        return isIdentischeListe(liste) || isEchterStel(liste) || isUnechterStel(liste);
    }

    public boolean isButtonConfirmedWahlkreisRendered(@Nullable Liste liste, @Nullable Gebiet gebiet) {
        if (isListenwahlgebietenUebergeordnetesGebiet(gebiet)) {
            return false;
        }
        return isButtonConfirmedWahlkreisRendered(liste, (Pruefkriterium) null);
    }

    public boolean isButtonConfirmedStelRendered(@Nullable Liste liste, @Nullable Gebiet gebiet) {
        if (isListenwahlgebietenUebergeordnetesGebiet(gebiet) && (isEchterStel(liste) || isUnechterStel(liste))) {//ELECT-11636
            return true;
        }
        return isButtonConfirmedStelRendered(liste, (Pruefkriterium) null);
    }

    public boolean isButtonConfirmedGruppeRendered(@Nullable Liste liste, @Nullable Gebiet gebiet) {
        if (isListenwahlgebietenUebergeordnetesGebiet(gebiet)) {
            return true;
        }
        return isButtonConfirmedGruppeRendered(liste, (Pruefkriterium) null);
    }


    private StelInformationen getStelInformationen(@Nullable Liste liste) {
        return nlListeStelInformationCache.getStelInformationen(liste);
    }

    public boolean isIdentischeListe(Liste liste) {
        return getStelInformationen(liste).getNlPolitischeGruppeArt().isIdentischeListe();
    }

    public boolean isEinzelliste(Liste liste) {
        return getStelInformationen(liste).getNlPolitischeGruppeArt().isEinzelliste();
    }

    private boolean isAbgelehnt(Liste liste) {
        return getStelInformationen(liste).getNlPolitischeGruppeArt().isAbgelehnt();
    }

    public boolean isListengruppe(Liste liste) {
        return getStelInformationen(liste).getNlPolitischeGruppeArt().isListengruppe();
    }

    public boolean isListenwahlgebietenUebergeordnetesGebiet(Gebiet gebiet) {
        return NlGebiet.isListenwahlgebietenUebergeordnetesGebiet(gebiet);
    }

    public boolean isUnechterStel(Liste liste) {
        return getStelInformationen(liste).isUnechterStel();
    }

    public boolean isEchterStel(Liste liste) {
        return getStelInformationen(liste).isEchterStel();
    }

    protected boolean isKriteriumFuerStelMoeglich(Pruefkriterium pruefkriterium) {
        if (pruefkriterium == null) {
            return true;
        }
        return !getNlPruefkriteriumAuswirkung(pruefkriterium).isGruppe();
    }

    protected boolean isKriteriumFuerWahlkreisMoeglich(Pruefkriterium pruefkriterium) {
        if (pruefkriterium == null) {
            return true;
        }
        return getNlPruefkriteriumAuswirkung(pruefkriterium).isListe();
    }

    private NlPruefkriteriumAuswirkung getNlPruefkriteriumAuswirkung(Pruefkriterium pruefkriterium) {
        return NlPruefkriteriumAuswirkung.from(pruefkriterium);

    }

    public Collection<Wahlrechtspruefung> getWahlrechtspruefungStatusBemerkungFuerAlleBenoetigtenKanidaturen(NlPruefkriteriumAuswirkung nlPruefkriteriumAuswirkung, WahlrechtspruefStatus wahlrechtspruefStatus, Wahlrechtspruefung wahlrechtspruefung, String alteBemerkung) {
        Collection<Wahlrechtspruefung> wahlrechtspruefungAllerKandidaturen;

        Pruefkriterium pruefkriterium = wahlrechtspruefung.getPruefkriterium();
        WahlrechtspruefStatus versaeumnisstatus = wahlrechtspruefStatus;
        PolitischeGruppe politischeGruppe = wahlrechtspruefung.getKandidatur().getGruppe();

        if (StringUtils.isBlank(alteBemerkung)) {
            wahlrechtspruefungAllerKandidaturen = wahlrechtspruefungExtendedDAO
                    .findByKandidaturNotNullAndPruefkriteriumAndBemerkungIsBlank(pruefkriterium, versaeumnisstatus, politischeGruppe);
        } else {
            wahlrechtspruefungAllerKandidaturen = wahlrechtspruefungExtendedDAO
                    .findByKandidaturNotNullAndPruefkriteriumAndBemerkung(pruefkriterium, versaeumnisstatus, alteBemerkung, politischeGruppe);
        }

        if (nlPruefkriteriumAuswirkung.equals(NlPruefkriteriumAuswirkung.STEL) || nlPruefkriteriumAuswirkung.equals(NlPruefkriteriumAuswirkung.LISTE)) {
            Listenkandidatur listenkandidatur = wahlrechtspruefung.getKandidatur().castTo(Listenkandidatur.class).getEntity();
            wahlrechtspruefungAllerKandidaturen = nlPruefkriteriumAuswirkung
                    .bestimmeKandidaturen(wahlrechtspruefungAllerKandidaturen, wahlrechtspruefung, () -> getStelInformationen(listenkandidatur.getListe()),
                            listeExtendedDAO);
        }

        return wahlrechtspruefungAllerKandidaturen;
    }
}
