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

import static de.ivu.elect.jee.entity.EntityUtil.castTo;

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

import de.ivu.elect.business.kandidatur.boundary.DirektkandidaturChangeEvent;
import de.ivu.elect.business.kandidatur.boundary.DirektkandidaturExtendedDAO;
import de.ivu.elect.business.kandidatur.entity.Direktkandidatur;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.wahlvorschlag.boundary.DirektkandidatExtendedDAO;
import de.ivu.elect.business.wahlvorschlag.entity.Direktkandidat;

public abstract class AbstractDirektkandidaturAction extends AbstractKandidaturAction {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient DirektkandidatExtendedDAO direktkandidatExtendedDAO;

  @Inject
  private transient DirektkandidaturExtendedDAO direktkandidaturExtendedDAO;

  @Inject
  private transient DirektkandidaturChangeEvent direktkandidaturChangeEvent;

  protected AbstractDirektkandidaturAction() {
    super();
  }

  @Override
  public boolean isDisabledInternal(@Nonnull Kandidatur kandidatur) {
    return super.isDisabledInternal(kandidatur) || !isDirektkandidatur(kandidatur) || isDisabledInternal(asDirektkandidatur(kandidatur));
  }

  protected boolean isDisabledInternal(Direktkandidatur direktkandidatur) {
    return isEinzelbewerber(direktkandidatur) || isWaehlerBenannteDirektkandidatur(direktkandidatur); // Aktionen auf "Wähler benannten Personen" explizit zulassen!
  }

  @Override
  public String doIt(Kandidatur kandidatur) {
    if (isDirektkandidatur(kandidatur)) {
      Direktkandidatur direktkandidatur = asDirektkandidatur(kandidatur);

      if (direktkandidatur != null) {
        return doIt(direktkandidatur);
      }
    }

    throw new UnsupportedOperationException("Das Bearbeiten der uebergebenen Kandidatur [kandidatur = <" + kandidatur + ">] wird nicht unterstuetzt");
  }

  protected abstract String doIt(@Nonnull Direktkandidatur direktkandidatur);

  @Override
  protected void fireChangeEvent() {
    direktkandidaturChangeEvent.sendChangeEvent();
  }

  protected Direktkandidat attach(Direktkandidat direktkandidat) {
    return direktkandidatExtendedDAO.attach(direktkandidat);
  }

  @Override
  protected Kandidatur attach(Kandidatur kandidatur) {
    if (isDirektkandidatur(kandidatur)) {
      return asDirektkandidatur(kandidatur);
    }

    return super.attach(kandidatur);
  }

  private boolean isDirektkandidatur(Kandidatur kandidatur) {
    return kandidatur != null && kandidatur.isInstanceOf(Direktkandidatur.class);
  }

  @Nullable
  protected Direktkandidatur asDirektkandidatur(Kandidatur kandidatur) {
    if (isDirektkandidatur(kandidatur)) {
      return direktkandidaturExtendedDAO.attach(castTo(kandidatur, Direktkandidatur.class)); // ELECT-11362
    }

    return null;
  }

  @Nullable
  protected Direktkandidat asDirektkandidat(Kandidatur kandidatur) {
    Direktkandidatur direktkandidatur = asDirektkandidatur(kandidatur);

    if (direktkandidatur != null) {
      return direktkandidatur.getDirektkandidat();
    }

    return null;
  }
}
