
package de.ivu.elect.business.stimmeingabe.control.plausi;

import static org.apache.commons.lang3.StringUtils.isNotBlank;

import javax.annotation.Nullable;

import de.ivu.elect.business.stimmeingabe.entity.*;

public class StimmeingabePlausiResult {

  public static final StimmeingabePlausiFiktiveWerteFehlerBeheber KEIN_FIKTIVE_WERTE_FEHLER_BEHEBER = null;

  public static final StimmeingabePlausiResult KEIN_FEHLER = new StimmeingabePlausiResult(null, StimmeingabePlausiTyp.UNBEKANNT, StimmeingabePlausiFehlerart.UNBEKANNT, StimmeingabePlausiStatus.DEAKTIVIERT, null, null, null, null, false,
      KEIN_FIKTIVE_WERTE_FEHLER_BEHEBER);

  private final Stimmeingabe stimmeingabe;

  private final StimmeingabePlausiTyp stimmeingabePlausiTyp;

  private final StimmeingabePlausiFehlerart stimmeingabePlausiFehlerart;

  private final StimmeingabePlausiStatus stimmeingabePlausiStatus;

  private final Stimmeingabefehlerart stimmeingabefehlerFehlerart;

  private final String stimmeingabefehlerFehlerschluessel;

  private final String stimmeingabefehlerBeschreibung;

  private final String anzahlSollEingabe;

  private final Number anzahlSoll;

  private final boolean anzahlSollAutomatischUebernehmbar;

  private final StimmeingabePlausiFiktiveWerteFehlerBeheber fiktiveWerteFehlerBeheber;

  public StimmeingabePlausiResult(Stimmeingabe stimmeingabe, StimmeingabePlausiTyp stimmeingabePlausiTyp, StimmeingabePlausiFehlerart stimmeingabePlausiFehlerart, StimmeingabePlausiStatus stimmeingabePlausiStatus,
      @Nullable String stimmeingabefehlerFehlerschluessel, String stimmeingabefehlerBeschreibung, String anzahlSollEingabe, Number anzahlSoll, boolean anzahlSollAutomatischUebernehmbar,
      @Nullable StimmeingabePlausiFiktiveWerteFehlerBeheber fiktiveWerteFehlerBeheber) {
    super();

    this.stimmeingabe = stimmeingabe;

    this.stimmeingabePlausiTyp = stimmeingabePlausiTyp;
    this.stimmeingabePlausiFehlerart = stimmeingabePlausiFehlerart;
    this.stimmeingabePlausiStatus = stimmeingabePlausiStatus;

    this.stimmeingabefehlerFehlerart = Stimmeingabefehlerart.of(stimmeingabePlausiFehlerart);
    this.stimmeingabefehlerFehlerschluessel = stimmeingabefehlerFehlerschluessel;
    this.stimmeingabefehlerBeschreibung = stimmeingabefehlerBeschreibung;

    this.anzahlSollEingabe = anzahlSollEingabe;
    this.anzahlSoll = anzahlSoll;
    this.anzahlSollAutomatischUebernehmbar = anzahlSollAutomatischUebernehmbar;

    this.fiktiveWerteFehlerBeheber = fiktiveWerteFehlerBeheber;
  }

  public boolean hasStimmeingabe() {
    return getStimmeingabe() != null;
  }

  public Stimmeingabe getStimmeingabe() {
    return stimmeingabe;
  }

  public StimmeingabePlausiTyp getStimmeingabePlausiTyp() {
    return stimmeingabePlausiTyp;
  }

  public StimmeingabePlausiFehlerart getStimmeingabePlausiFehlerart() {
    return stimmeingabePlausiFehlerart;
  }

  public StimmeingabePlausiStatus getStimmeingabePlausiStatus() {
    return stimmeingabePlausiStatus;
  }

  @Nullable
  public Stimmeingabefehlerart getStimmeingabefehlerFehlerart() {
    return stimmeingabefehlerFehlerart;
  }

  @Nullable
  public String getStimmeingabefehlerFehlerschluessel() {
    return stimmeingabefehlerFehlerschluessel;
  }

  public String getStimmeingabefehlerBeschreibung() {
    return stimmeingabefehlerBeschreibung;
  }

  public boolean hasAnzahlSollEingabe() {
    return isNotBlank(getAnzahlSollEingabe());
  }

  public String getAnzahlSollEingabe() {
    return anzahlSollEingabe;
  }

  public boolean hasAnzahlSollAutomatischUebernehmbar() {
    return anzahlSollAutomatischUebernehmbar && hasAnzahlSoll() && getAnzahlSoll().longValue() > 0;
  }

  public boolean hasAnzahlSoll() {
    return getAnzahlSoll() != null;
  }

  public Number getAnzahlSoll() {
    return anzahlSoll;
  }

  public boolean isFehler() {
    return !this.equals(KEIN_FEHLER);
  }

  public boolean isMussFehler() {
    return isFehler() && StimmeingabePlausiFehlerart.ERROR.equals(getStimmeingabePlausiFehlerart());
  }

  public boolean isKannFehler() {
    return isFehler() && StimmeingabePlausiFehlerart.WARNING.equals(getStimmeingabePlausiFehlerart());
  }

  public boolean hasFiktiveWerteFehlerBeheber() {
    return fiktiveWerteFehlerBeheber != null;
  }

  public StimmeingabePlausiFiktiveWerteFehlerBeheber getFiktiveWerteFehlerBeheber() {
    return fiktiveWerteFehlerBeheber;
  }

  public void behebeFiktiveWerteFehler() throws StimmeingabePlausiFiktiveWerteFehlerNichtBehebbarException {
    if (fiktiveWerteFehlerBeheber == null) {
      throw new IllegalStateException("Kein Fehlerbeheber! " + this.toString());
    }

    fiktiveWerteFehlerBeheber.behebeFehler(getStimmeingabe());
  }

  @Override
  public String toString() {
    return "StimmeingabePlausiResult{" + "stimmeingabe=" + stimmeingabe + ", fehlerart=" + stimmeingabePlausiFehlerart + ", status=" + stimmeingabePlausiStatus + ", fehlerschluessel='" + stimmeingabefehlerFehlerschluessel + '\''
        + ", beschreibung='" + stimmeingabefehlerBeschreibung + '\'' + ", anzahlSollEingabe='" + anzahlSollEingabe + '\'' + ", anzahlSoll=" + anzahlSoll + ", anzahlSollAutomatischUebernehmbar="
        + anzahlSollAutomatischUebernehmbar + ", fiktiveWerteFehlerBeheber=" + fiktiveWerteFehlerBeheber + ", typ=" + stimmeingabePlausiTyp + '}';
  }
}
