
package de.ivu.elect.presentation.person.action;

import static java.util.Arrays.asList;

import java.util.List;

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

import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.personenpruefung.boundary.PersonenKonfliktExtendedDAO;
import de.ivu.elect.business.personenpruefung.entity.PersonenKonflikt;
import de.ivu.elect.business.personenpruefung.entity.PersonenKonfliktArt;
import de.ivu.elect.business.personenpruefung.entity.PersonenKonfliktConstants;
import de.ivu.elect.jee.cdi.BeanManagerUtil;
import de.ivu.elect.jee.presentation.action.ActionEntry;
import de.ivu.elect.presentation.menu.AbstractActionEntry;
import de.ivu.elect.presentation.personenpruefung.action.PersonenKonfliktAufloesenActionBuilder;
import de.ivu.elect.presentation.security.AbstractGebietSecurity;

public abstract class AbstractPersonendatenPersonenKonfliktAufloesenAction<P extends Personendaten> extends AbstractActionEntry<P> {

  private static final long serialVersionUID = 1L;

  @Inject
  private PersonenKonfliktExtendedDAO personenKonfliktDao;

  public AbstractPersonendatenPersonenKonfliktAufloesenAction() {
    super();
  }

  @Override
  public AbstractGebietSecurity getGebietSecurity() {
    return getEinsehenGebietSecurity();
  }

  @Override
  public boolean isDisabledInternal(@Nonnull P personendaten) {
    return !personendaten.isPersonStatusManuellZuPruefenderKonflikt() || !isAnyPersonenKonfliktManuellZuPruefen(personendaten);
  }

  private boolean isAnyPersonenKonfliktManuellZuPruefen(P personendaten) {
    PersonenKonflikt personenKonfliktManuellZuPruefen = findFirstPersonenKonfliktManuellZuPruefen(personendaten);

    if (personenKonfliktManuellZuPruefen == null) {
      return false;
    }

    ActionEntry<PersonenKonflikt> personenKonfliktManuellZuPruefenAufloesenAction = findFirstPersonenKonfliktAufloesenActionEnabled(
        personenKonfliktManuellZuPruefen);

    if (personenKonfliktManuellZuPruefenAufloesenAction == null) {
      return false;
    }

    return true;
  }

  @Nullable
  @Override
  public String doIt(P personendaten) {
    PersonenKonflikt personenKonfliktManuellZuPruefen = findFirstPersonenKonfliktManuellZuPruefen(personendaten);

    if (personenKonfliktManuellZuPruefen == null) {
      return null;
    }

    ActionEntry<PersonenKonflikt> personenKonfliktManuellZuPruefenAufloesenAction = findFirstPersonenKonfliktAufloesenActionEnabled(
        personenKonfliktManuellZuPruefen);

    if (personenKonfliktManuellZuPruefenAufloesenAction == null) {
      return null;
    }

    return personenKonfliktManuellZuPruefenAufloesenAction.action(personenKonfliktManuellZuPruefen);
  }

  @Nullable
  private PersonenKonflikt findFirstPersonenKonfliktManuellZuPruefen(P personendaten) {
    for (PersonenKonflikt personenKonflikt : personenKonfliktDao.findByPersonAndKonfliktArt(personendaten,
        asList(PersonenKonfliktArt.values()))) {
      if (personenKonflikt.isKonfliktStatusManuellZuPruefen()) {
        return personenKonflikt;
      }
    }

    return null;
  }

  @Nullable
  private ActionEntry<PersonenKonflikt> findFirstPersonenKonfliktAufloesenActionEnabled(PersonenKonflikt personenKonflikt) {
    List<ActionEntry<PersonenKonflikt>> personenKonfliktAufloesenActions = BeanManagerUtil
        .getBeanByClass(PersonenKonfliktAufloesenActionBuilder.class).getAufloesenActions(personenKonflikt);

    for (ActionEntry<PersonenKonflikt> personenKonfliktAufloesenAction : personenKonfliktAufloesenActions) {
      if (!personenKonfliktAufloesenAction.isDisabled(personenKonflikt)) {
        return personenKonfliktAufloesenAction;
      }
    }

    return null;
  }

  @Override
  public boolean isFireChangeEvent() {
    return false;
  }

  @Override
  public void fireChangeEvent() {
    // nichts zu tun
  }

  @Override
  public String getLocalizedLabel() {
    return getMessage(getLabelKey(), getMessage(PersonenKonfliktConstants.MESSAGE_KEY_ENTITY_EINZAHL));
  }

  @Override
  public String getLabelKey() {
    return "entity.edit.menu.item.label";
  }

  @Override
  public String getIcon() {
    return appIcons.getIconAlert();
  }
}
