
package de.ivu.elect.presentation.stimmeingabe.status;

import java.util.Comparator;

import javax.annotation.Nullable;

import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingang;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingangsart;
import de.ivu.elect.jee.presentation.charts.PieChartModelBuilder;
import de.ivu.elect.jee.presentation.status.OutputSeverity;

public enum GebietErfassungsstatus {

  NOCH_KEIN_EINGANG(PieChartModelBuilder.GRAU, OutputSeverity.EMPTY),

  AUSBLEIBEND(PieChartModelBuilder.DUNKEL_GRAU, OutputSeverity.EMPTY),

  MUSS_FEHLER_VORHANDEN(PieChartModelBuilder.ROT, OutputSeverity.ERROR),

  KANN_FEHLER_VORHANDEN(PieChartModelBuilder.GELB, OutputSeverity.WARN),

  FIKTIV(PieChartModelBuilder.BLAU, OutputSeverity.INFO),

  /**
   * Bedeutet, dass das Ergebnis gültig ist, aber keine Erststimmen oder keine Zweitstimmen umfasst. UNVOLLSTAENDIG spielt eine Sonderrolle, weil dies zu ermitteln aufwändig ist und dies nur für die
   * AGH-Wahl in Berlin erforderlich ist. Bei anderen Wahlen wird ein solcher Ergebniseingang als GUELTIG betrachtet oder das Fehlern von bestimmen Angaben fürht zu einem Fehler.
   */
  UNVOLLSTAENDIG(PieChartModelBuilder.PINK, OutputSeverity.ERROR),

  GUELTIG(PieChartModelBuilder.GRUEN, OutputSeverity.SUCCESS);

  public static final Comparator<GebietErfassungsstatus> DEFAULT_COMPARATOR = GebietErfassungsstatus::compareTo;

  private final String pieChartColor;

  private final OutputSeverity outputSeverity;

  GebietErfassungsstatus(String pieChartColor, OutputSeverity outputSeverity) {
    this.pieChartColor = pieChartColor;
    this.outputSeverity = outputSeverity;
  }

  public String getPieChartColor() {
    return pieChartColor;
  }

  public OutputSeverity getSeverity() {
    return outputSeverity;
  }

  public boolean isFehlerVorhanden() {
    return this.equals(KANN_FEHLER_VORHANDEN) || this.equals(MUSS_FEHLER_VORHANDEN);
  }

  /**
   * @param vollstaendigkeitPruefen wenn dies true ist, werden gültige Ergebniseingänge zusätzlich darauf geprüft, dass die Erst- und Zweitstimmen enthalten - und sind andernfalls UNVOLLSTAENDIG.
   */
  public static GebietErfassungsstatus fromErgebniseingang(@Nullable Ergebniseingang neuesterErgebniseingang,
                                                           boolean vollstaendigkeitPruefen, Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet,
                                                           Ergebniseingangsart ergebniseingangsart) {
    if (neuesterErgebniseingang == null) {
      if (wahldurchfuehrungsgebiet.getErgebniseingabestatus(ergebniseingangsart.korrespondierendeErgebnisart()).isAusbleibend()) {
        return AUSBLEIBEND;
      }
      return NOCH_KEIN_EINGANG;
    }

    if (neuesterErgebniseingang.isUngueltigMussFehler()) {
      return MUSS_FEHLER_VORHANDEN;
    }

    if (neuesterErgebniseingang.isUngueltigKannFehler()) {
      return KANN_FEHLER_VORHANDEN;
    }

    if (neuesterErgebniseingang.isGueltig()) {
      if (neuesterErgebniseingang.isFiktiv()) {
        return FIKTIV;
      } else {
        if (vollstaendigkeitPruefen && !GebietErfassungsstatusVollstaendigCache.isVollstaendig(neuesterErgebniseingang)) {
          return UNVOLLSTAENDIG;
        } else {
          return GUELTIG;
        }
      }
    }

    throw new IllegalArgumentException(
        "Zum gegebenen Gebiet und Ergebniseingang konnte kein Erfassungsstatus ermittelt werden. [neuesterErgebniseingang = " + neuesterErgebniseingang + "]");
  }

  public boolean isAusbleibend() {
    return AUSBLEIBEND.equals(this); // nicht als Vorlage verwenden
  }
}
