
package de.ivu.elect.was.exchange.wahl;

import java.io.Serializable;
import java.util.List;
import java.util.function.Supplier;

import javax.annotation.Nullable;
import javax.inject.Inject;

import de.ivu.elect.business.gebietsbaum.boundary.NlGebietDarstellungNummerFormatter;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.NlGebietsart;
import de.ivu.elect.business.wahl.entity.NlWahlCustomData;
import de.ivu.elect.business.wahl.entity.NlWahlart;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.nl.eml.readable.AbstractEmlElectionWrapper;
import de.ivu.wahl.wus.oasis.eml.ElectionIdentifierStructure;
import de.ivu.wahl.wus.oasis.eml.kiesraad.ElectionDomain;

public class EmlCommonMapper implements Serializable {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient NlWahlartEmlMapper nlWahlartEmlMapper;

  @Inject
  private transient NlGebietDarstellungNummerFormatter nlGebietDarstellungNummerFormatter;

  public EmlCommonMapper() {
    super();
  }

  public void mappeWahldaten(Wahl wahl, AbstractEmlElectionWrapper emlElectionWrapper, @Nullable Gebiet gebiet, @Nullable Supplier<List<Gebiet>> alleGebiete) {
    ElectionIdentifierStructure electionIdentifierStructure = emlElectionWrapper.getElectionIdentifierStructure();
    electionIdentifierStructure.setElectionName(wahl.getName());
    electionIdentifierStructure.setId(wahl.getKennzeichen());
    electionIdentifierStructure.setElectionCategory(nlWahlartEmlMapper.bestimmeElectionCategory(wahl.getWahlart()).name());
    // ELECTVAPP-399 ELECTVAPP-1115
    emlElectionWrapper.addElectionSubcategory(nlWahlartEmlMapper.bestimmeElectionSubcategory(wahl, gebiet, alleGebiete));

    ElectionDomain electionDomain = bestimmeElectionDomain(wahl, gebiet);
    if (electionDomain != null) {
      emlElectionWrapper.addElectionDomain(electionDomain.getId(), electionDomain.getValue());
    }

    // ELECTVAPP-277
    emlElectionWrapper.addElectionDate(wahl.getWahldatum());
  }

  @Nullable
  public ElectionDomain bestimmeElectionDomain(Wahl wahl, Gebiet gebiet) {
    if (isElectionDomainInEmlAusgaben(wahl, gebiet)) {
      ElectionDomain electionDomain = new ElectionDomain();

      if ((NlWahlart.PROVINCIALE_STATEN1.equalsWahlart(wahl) /*ELECTVAPP-1832*/ || NlWahlart.WATERSCHAP.equalsWahlart(wahl)) && !gebiet.isWahlgebiet()) {
        // ELECT-14229
        electionDomain.setId(wahl.getCustomData(NlWahlCustomData.class).getElectionDomainId());
        electionDomain.setValue(wahl.getCustomData(NlWahlCustomData.class).getElectionDomain());
      } else {
        if (NlWahlart.valueOf(wahl).isElectionDomainIdInEmlAusgaben()) {
          electionDomain.setId(nlGebietDarstellungNummerFormatter.formatiereNummer(gebiet));
        }
        electionDomain.setValue(gebiet.getName());
      }
      return electionDomain;
    }
    return null;
  }

  protected boolean isElectionDomainInEmlAusgaben(Wahl wahl, Gebiet gebiet) {
    if (gebiet == null) {
      return false;
    }

    return (gebiet.isWahlgebiet() && !NlGebietsart.from(gebiet).isStaat() /* Bei GR ja, bei TK nein... */) ||
        NlWahlart.valueOf(wahl).isElectionDomainImmerInEmlAusgeben()/*ELECT-13753*/;

  }

}
