
package de.ivu.elect.business.personenregister.control;

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import javax.inject.Inject;

import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.personenregister.entity.PersonenregisterPersonendaten;
import de.ivu.elect.business.staat.boundary.StaatFactory;
import de.ivu.elect.business.staat.entity.Staat;

// Cf. https://support.elect-it.com/wiki/display/ELECT/Personenregister-Abgleich
public class PersonendatenPersonenregisterPersonendatenMapper implements PersonenregisterPersonendatenMapper {

  private static final long serialVersionUID = 1L;

  @Inject
  protected transient PersonendatenAnschriftPersonenregisterAnschriftMapper personendatenAnschriftPersonenregisterAnschriftMapper;

  @Inject
  protected transient StaatFactory staatFactory;

  public PersonendatenPersonenregisterPersonendatenMapper() {
    super();
  }

  protected void mapDefaultPersonendaten(Personendaten personendaten, PersonenregisterPersonendaten template, List<Staat> templateStaatsangehoerigkeitenSorted) {
    personendaten.setOrdnungsmerkmal(template.getOrdnungsmerkmal());

    // NOTE ELECT-1688, dass der Matcher die Übernehmbarkeit positiv entscheidet, falls einer der Werte NICHT gesetzt
    // ist. Deshalb muss an dieser Stelle überprüft werden, ob denn tatsächlich eine Anrede im Personenregister
    // vorhanden ist!
    if (isNotBlank(template.getAnrede())) {
      personendaten.setAnrede(template.getAnrede());
    }

    personendaten.setTitel(template.getTitel());

    personendaten.setFamilienname(template.getFamilienname());
    personendaten.setFamiliennameBestandteil(template.getFamiliennameBestandteil());
    personendaten.setRufname(template.getRufname());
    personendaten.setVornamen(template.getVornamen());
    personendaten.setKuenstlername(template.getKuenstlername());
    personendaten.setOrdensname(template.getOrdensname());

    personendaten.setGeburtsdatum(template.getGeburtsdatum());
    personendaten.setGeschlecht(template.getGeschlecht());

    if (isNotBlank(template.getGeburtsort())) {
      personendaten.setGeburtsort(template.getGeburtsort());
    }

    personendaten.setStaatsangehoerigkeitenSorted(templateStaatsangehoerigkeitenSorted);

    personendaten.setSperrmerkmal(template.getSperrmerkmal());
    personendaten.setWahlrechtsausschluss(template.getWahlrechtsausschluss());
    personendaten.setStimmbezirkSchluessel(template.getStimmbezirkSchluessel());
  }

  @Override
  public void mapAutomatischerAbgleich(Personendaten personendaten, PersonenregisterPersonendaten template, Collection<Staat> templateStaatsangehoerigkeiten) {
    mapAutomatischerAbgleichPersonendaten(personendaten, template, templateStaatsangehoerigkeiten);
    mapAutomatischerAbgleichAnschrift(personendaten, template);
  }

  protected void mapAutomatischerAbgleichPersonendaten(Personendaten personendaten, PersonenregisterPersonendaten template, Collection<Staat> templateStaatsangehoerigkeiten) {
    String staatsangehoerigkeitenSortOrder = personendaten.getStaatsangehoerigkeitenSortOrder();

    mapDefaultPersonendaten(personendaten, template, new ArrayList<>(templateStaatsangehoerigkeiten));

    // NOTE, dass eine bestehende (manuelle) Sortierung NICHT (automatisch) überschrieben werden soll!
    if (isNotBlank(staatsangehoerigkeitenSortOrder)) {
      personendaten.setStaatsangehoerigkeitenSortOrder(staatsangehoerigkeitenSortOrder);
    }
  }

  protected void mapAutomatischerAbgleichAnschrift(Personendaten personendaten, PersonenregisterPersonendaten template) {
    personendatenAnschriftPersonenregisterAnschriftMapper.mapAutomatischerAbgleich(personendaten, template);
  }

  @Override
  public void mapManuelleAuswahl(Personendaten personendaten, PersonenregisterPersonendaten template) {
    mapManuelleAuswahlPersonendaten(personendaten, template);
    mapManuelleAuswahlAnschrift(personendaten, template);
  }

  protected void mapManuelleAuswahlPersonendaten(Personendaten personendaten, PersonenregisterPersonendaten template) {
    mapDefaultPersonendaten(personendaten, template, createStaatangehoerigkeiten(template.getStaatsangehoerigkeiten()));
  }

  protected void mapManuelleAuswahlAnschrift(Personendaten personendaten, PersonenregisterPersonendaten template) {
    personendatenAnschriftPersonenregisterAnschriftMapper.mapManuelleAuswahl(personendaten, template);
  }

  private List<Staat> createStaatangehoerigkeiten(List<String> staatsangehoerigkeiten) {
    return staatsangehoerigkeiten.stream().map(staatsangehoerigkeit -> {
      Staat staat = staatFactory.create();
      // NOTE, dass hier der Wert gesetzt werden muss, anhand dessen eine existierende Staatsangehörigkeit gefunden
      // werden kann.
      staat.setIso3166Alpha2(staatsangehoerigkeit);
      staat.setCustomCodeStaatsangehoerigkeit(staatsangehoerigkeit);

      return staat;
    }).collect(Collectors.toList());
  }
}
