
package de.ivu.elect.presentation.wahl.menu;

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

import javax.enterprise.inject.Specializes;
import javax.inject.Inject;

import de.ivu.elect.business.security.control.ElectCommonPrincipal;
import de.ivu.elect.business.wahl.boundary.WahlExtendedDAO;
import de.ivu.elect.business.wahl.boundary.WahlSessionSelect;
import de.ivu.elect.business.wahl.control.WahlByWahldatumDescAndPositionAscComparator;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.jee.presentation.menu.MenuEntry;
import de.ivu.elect.presentation.dokumente.menu.DokumentVorlageLeerformularSearchMenuItemEntry;
import de.ivu.elect.presentation.dokumente.menu.DokumentVorlageVerwaltenMenuItemEntry;
import de.ivu.elect.presentation.personenpruefung.menu.PersonPruefungKonfigurationSearchMenuItemEntry;
import de.ivu.elect.presentation.staat.menu.StaatenGruppeVerwaltenMenuItemEntry;
import de.ivu.elect.presentation.wahl.action.WahlZurBearbeitungAuswaehlenAction;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry.WahlSelect10MenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry.WahlSelect1MenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry.WahlSelect2MenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry.WahlSelect3MenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry.WahlSelect4MenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry.WahlSelect5MenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry.WahlSelect6MenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry.WahlSelect7MenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry.WahlSelect8MenuItemEntry;
import de.ivu.elect.presentation.wahl.menu.dynamic.AbstractWahlSelectMenuItemEntry.WahlSelect9MenuItemEntry;
import de.ivu.elect.presentation.wertelisten.menu.WertelistenVerwaltenMenuItemEntry;

@Specializes
public class CoreWahlMainMenuEntry extends WahlMainMenuEntry {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient WahlSessionSelect wahlSelect;

  @Inject
  private transient WahlterminDokumentMenuItemEntry wahlterminDokumentMenuItemEntry;

  @Inject
  private transient WahlExtendedDAO wahlExtendedDAO;

  @Inject
  protected transient WahlEditMenuItemEntry wahlEditMenuItemEntry;

  @Inject
  protected transient WahlSearchMenuItemEntry wahlSearchMenuItemEntry;

  @Inject
  protected transient DokumentVorlageVerwaltenMenuItemEntry dokumentVorlageVerwaltenMenuItemEntry;

  @Inject
  protected transient DokumentVorlageLeerformularSearchMenuItemEntry dokumentVorlageLeerformularSearchMenuItemEntry;

  @Inject
  private transient PersonPruefungKonfigurationSearchMenuItemEntry personPruefungKonfigurationSearchMenuItemEntry;

  @Inject
  private transient StaatenGruppeVerwaltenMenuItemEntry staatenGruppeVerwaltenMenuItemEntry;

  @Inject
  private transient WahlSelect1MenuItemEntry wahlSelect1MenuItemEntry;

  @Inject
  private transient WahlSelect2MenuItemEntry wahlSelect2MenuItemEntry;

  @Inject
  private transient WahlSelect3MenuItemEntry wahlSelect3MenuItemEntry;

  @Inject
  private transient WahlSelect4MenuItemEntry wahlSelect4MenuItemEntry;

  @Inject
  private transient WahlSelect5MenuItemEntry wahlSelect5MenuItemEntry;

  @Inject
  private transient WahlSelect6MenuItemEntry wahlSelect6MenuItemEntry;

  @Inject
  private transient WahlSelect7MenuItemEntry wahlSelect7MenuItemEntry;

  @Inject
  private transient WahlSelect8MenuItemEntry wahlSelect8MenuItemEntry;

  @Inject
  private transient WahlSelect9MenuItemEntry wahlSelect9MenuItemEntry;

  @Inject
  private transient WahlSelect10MenuItemEntry wahlSelect10MenuItemEntry;

  @Inject
  private transient WahlartSearchMenuItemEntry wahlartSearchMenuItemEntry;

  @Inject
  private transient WahlDokumentplatzhalterEditMenuItemEntry wahlDokumentplatzhalterEditMenuItemEntry;

  @Inject
  private transient WahlParameterSearchMenuItemEntry wahlParameterSearchMenuItemEntry;

  @Inject
  private transient WahlParameterExportMenuItemEntry wahlParameterExportMenuItemEntry;

  @Inject
  private transient WahlParameterImportMenuItemEntry wahlParameterImportMenuItemEntry;

  @Inject
  private transient ExterneLinks externeLinks;

  @Inject
  protected transient WahlCreateMenuItemEntry wahlCreateMenuItemEntry;

  @Inject
  private transient WahlImportMenuItemEntry wahlImportMenuItemEntry;

  @Inject
  protected transient WahlExportMenuItemEntry wahlExportMenuItemEntry;

  @Inject
  private transient WahlKonfigurationImportMenuItemEntry wahlKonfigurationImportMenuItemEntry;

  @Inject
  private transient WahlKonfigurationExportMenuItemEntry wahlKonfigurationExportMenuItemEntry;

  @Inject
  private transient WahlZurBearbeitungAuswaehlenAction wahlZurBearbeitungAuswaehlenAction;

  @Inject
  private transient WertelistenVerwaltenMenuItemEntry wertelistenVerwaltenMenuItemEntry;

  @Inject
  private transient ElectCommonPrincipal electCommonPrincipal;

  public CoreWahlMainMenuEntry() {
    super();
  }

  @Override
  protected List<MenuEntry> getSubMenuEntriesSorted() {
    List<MenuEntry> result = new ArrayList<>(super.getSubMenuEntriesSorted());

    addWahlMenuEntries(result);
    result.add(separator);
    result.add(wahlParameterSearchMenuItemEntry);
    result.add(wahlParameterImportMenuItemEntry);
    result.add(wahlParameterExportMenuItemEntry);
    if (isAndereWahlenEinhaengen()) {
      addAuszuwaehlendeWahlenMenuEntries(result, true);
    }

    result.add(separator);
    addEntitaetenVerwaltenMenuEntries(result);

    result.add(separator);
    result.add(wahlartSearchMenuItemEntry);
    result.add(wahlKonfigurationExportMenuItemEntry);
    result.add(wahlKonfigurationImportMenuItemEntry);

    addExterneLinks(result);

    return result;
  }

  protected boolean isAndereWahlenEinhaengen() {
    return true;
  }

  protected void addEntitaetenVerwaltenMenuEntries(List<MenuEntry> result) {
    result.add(dokumentVorlageVerwaltenMenuItemEntry);
    result.add(personPruefungKonfigurationSearchMenuItemEntry);
    result.add(staatenGruppeVerwaltenMenuItemEntry);
    result.add(wertelistenVerwaltenMenuItemEntry);
  }

  protected void addExterneLinks(List<MenuEntry> result) {
    result.add(separator);
    externeLinks.addExterneLinks(result);
  }

  protected void addWahlMenuEntries(List<MenuEntry> result) {
    result.add(wahlEditMenuItemEntry);
    result.add(wahlSearchMenuItemEntry);
    // ELECT-6886
    result.add(wahlCreateMenuItemEntry);
    result.add(wahlImportMenuItemEntry);
    result.add(wahlExportMenuItemEntry);
    result.add(wahlterminDokumentMenuItemEntry);
    result.add(dokumentVorlageLeerformularSearchMenuItemEntry);

    result.add(wahlDokumentplatzhalterEditMenuItemEntry); // ELECTKOM-191 Position: ELECTKOM-297
  }

  @Override
  public void addAuszuwaehlendeWahlenMenuEntries(List<MenuEntry> result, boolean addSeparator) {
    super.addAuszuwaehlendeWahlenMenuEntries(result, addSeparator);
    var wahlen = bestimmeAuszuwaehlendeWahlen();

    if (!wahlen.isEmpty()) {
      if (addSeparator) {
        result.add(separator);
      }
      for (int i = 0; i < wahlen.size(); i++) {
        addWahlAuswahl(result, wahlen.get(i), i + 1);
      }

      if (addSeparator) {
        result.add(separator);
      }
    }
  }

  private void addWahlAuswahl(List<MenuEntry> result, Wahl wahl, int count) {
    AbstractWahlSelectMenuItemEntry menuItemEntry;

    switch (count) {
      case 1:
        menuItemEntry = wahlSelect1MenuItemEntry;
        break;
      case 2:
        menuItemEntry = wahlSelect2MenuItemEntry;
        break;
      case 3:
        menuItemEntry = wahlSelect3MenuItemEntry;
        break;
      case 4:
        menuItemEntry = wahlSelect4MenuItemEntry;
        break;
      case 5:
        menuItemEntry = wahlSelect5MenuItemEntry;
        break;
      case 6:
        menuItemEntry = wahlSelect6MenuItemEntry;
        break;
      case 7:
        menuItemEntry = wahlSelect7MenuItemEntry;
        break;
      case 8:
        menuItemEntry = wahlSelect8MenuItemEntry;
        break;
      case 9:
        menuItemEntry = wahlSelect9MenuItemEntry;
        break;
      case 10:
        menuItemEntry = wahlSelect10MenuItemEntry;
        break;
      default:
        menuItemEntry = null;
    }

    if (menuItemEntry != null) {
      menuItemEntry.setWahl(wahl);

      result.add(menuItemEntry);
    }
  }

  protected List<Wahl> bestimmeAuszuwaehlendeWahlen() {
    if (electCommonPrincipal.isLoggedIn() && electCommonPrincipal.getMandant() != null) {
      List<Wahl> result;
      var selectedWahl = wahlSelect.getEntity();

      result = wahlExtendedDAO.findByAll(electCommonPrincipal.getMandant()).stream()
          .filter(wahl -> wahl.getStatus().isAuswaehlbar() && !wahl.equals(selectedWahl))
          .filter(wahltermin -> wahltermin.getStatus().isCrontabErstellbar()) // nur aktive Wahlen einblenden
          .filter(wahl -> wahlZurBearbeitungAuswaehlenAction.isActionPossible(wahl)) // ELECT-7407
          .filter(wahl -> wahl.isRechtZumEinsehenVorhanden(electCommonPrincipal)) // ELECT-7407
          .sorted(new WahlByWahldatumDescAndPositionAscComparator()).collect(Collectors.toList());

      return result;
    }
    return Collections.emptyList();
  }
}
