package de.ivu.elect.stimmzettel.ergebnis;

import java.io.StringReader;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nullable;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;

import org.apache.commons.lang3.StringUtils;

public class StimmzettelErgebnis {

  private final String erfassteStimmzettelDatenJson;

  public StimmzettelErgebnis(String erfassteStimmzettelDatenJson) {
    this.erfassteStimmzettelDatenJson = erfassteStimmzettelDatenJson;
  }

  public boolean isGueltig() {
    if (StringUtils.isNotBlank(erfassteStimmzettelDatenJson)) {

      try {
        JsonReader reader = Json.createReader(new StringReader(erfassteStimmzettelDatenJson));
        JsonObject jsonObject = reader.readObject();
        return jsonObject.getBoolean("g");
      } catch (Exception e) {
        // ignore
      }
    }
    return false;
  }

  public StimmzettelUngueltigGrund getStimmzettelUngueltigGrund() {
    if (StringUtils.isNotBlank(erfassteStimmzettelDatenJson)) {
      try {
        JsonReader reader = Json.createReader(new StringReader(erfassteStimmzettelDatenJson));
        JsonObject jsonObject = reader.readObject();
        int grund = jsonObject.getInt("b");
        return StimmzettelUngueltigGrund.values()[grund - 1];
      } catch (Exception e) {
        // ignore
      }
    }
    return StimmzettelUngueltigGrund.GRUND_1; // Im Zweifel der erste Grund (Wählerwille...)
  }

  public Map<String, Long> getStimmenFuerKandidaten() {
    if (StringUtils.isBlank(erfassteStimmzettelDatenJson)) {
      return Collections.emptyMap();
    }
    Map<String, Long> result = new HashMap<>();

    try {
      JsonReader reader = Json.createReader(new StringReader(erfassteStimmzettelDatenJson));
      JsonObject jsonObject = reader.readObject();
      for (Map.Entry<String, JsonValue> entry : jsonObject.getJsonObject("s").entrySet()) {
        result.put(entry.getKey(), parseLong(entry.getValue()));
      }
    } catch (Exception e) {
      // ignore e.printStackTrace();
    }

    return result;
  }

  @Nullable
  public String getUnveraendertGekennzeichnetenWahlvorschlag() {
    if (StringUtils.isBlank(erfassteStimmzettelDatenJson)) {
      return null;
    }
    try {
      JsonReader reader = Json.createReader(new StringReader(erfassteStimmzettelDatenJson));
      JsonObject jsonObject = reader.readObject();
      return jsonObject.getString("u");
    } catch (Exception e) {
      return null;
    }
  }

  /**
   * ELECTKOM-875 und ELECTKOM-950
   */
  public boolean isGueltigkeitPerBeschlusspruefungNotwendig() {
    return isGueltig() && (isUngueltigeStimmenVorhanden() || isZuVieleBewerberFuerReststimmenzuteilung() || isNennungMarkiertUndGestrichen());
  }

  // ELECTKOM-950
  public boolean isNennungMarkiertUndGestrichen(){
    return StimmzettelUngueltigGrund.GRUND_5.equals(getStimmzettelUngueltigGrund());
  }

  public boolean isUngueltigeStimmenVorhanden() {
    if (StringUtils.isNotBlank(erfassteStimmzettelDatenJson)) {
      try {
        JsonReader reader = Json.createReader(new StringReader(erfassteStimmzettelDatenJson));
        JsonObject jsonObject = reader.readObject();
        JsonValue us = jsonObject.get("us");
        return parseLong(us) > 0;
      } catch (Exception e) {
        // ignore
      }
    }
    return false;
  }

  public boolean isZuVieleBewerberFuerReststimmenzuteilung() {
    if (StringUtils.isNotBlank(erfassteStimmzettelDatenJson)) {
      try {
        JsonReader reader = Json.createReader(new StringReader(erfassteStimmzettelDatenJson));
        JsonObject jsonObject = reader.readObject();
        return jsonObject.getBoolean("ls");
      } catch (Exception e) {
        // ignore
      }
    }
    return false;
  }

  @Nullable
  public String getInnerhalbVeraendertenWahlvorschlag() {
    if (StringUtils.isBlank(erfassteStimmzettelDatenJson)) {
      return null;
    }
    try {
      JsonReader reader = Json.createReader(new StringReader(erfassteStimmzettelDatenJson));
      JsonObject jsonObject = reader.readObject();
      return jsonObject.getString("v");
    } catch (Exception e) {
      return null;
    }
  }

  private Long parseLong(JsonValue value) {
    if (value == null || StringUtils.isBlank(value.toString())) {
      return 0L;
    }
    try {
      return Long.parseLong(value.toString());
    } catch (Exception e) {
      return 0L;
    }
  }

}
