package de.ivu.elect.presentation.internet.form;

import java.util.Comparator;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import de.ivu.elect.business.gebietsbaum.boundary.GebietExtendedDAO;
import de.ivu.elect.business.gebietsbaum.boundary.GebietsartExtendedDAO;
import de.ivu.elect.business.gebietsbaum.control.GebietByBreadthFirstComparator;
import de.ivu.elect.business.internet.control.InternetSeiteCustomDataFactory;
import de.ivu.elect.business.internet.entity.InternetSeite;
import de.ivu.elect.business.internet.entity.InternetSeiteCustomData;
import de.ivu.elect.business.internet.entity.InternetSeitePropertyContext;
import de.ivu.elect.business.internet.entity.InternetSeiteStatus;
import de.ivu.elect.business.internet.entity.InternetSeiteTyp;
import de.ivu.elect.business.internet.entity.InternetSeiteTypCustomDataKategorie;
import de.ivu.elect.business.wahl.boundary.WahlExtendedDAO;
import de.ivu.elect.business.wahl.boundary.WahlartExtendedDAO;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.jee.faces.FacesMessageUtil;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.LambdaEnumProperty;
import de.ivu.elect.jee.presentation.dynamicform.Property;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;


import static java.util.stream.Collectors.toList;

public class InternetSeiteViewFormBuilder {

  @Inject
  private transient InternetSeiteCustomDataFactory internetSeiteCustomDataFactory;

  @Inject
  private transient GebietNummerFormatter gebietNummerFormatter;

  @Inject
  private transient Messages messages;

  @Inject
  private transient WahlExtendedDAO wahlExtendedDAO;

  @Inject
  private transient WahlartExtendedDAO wahlartExtendedDAO;

  @Inject
  private transient GebietExtendedDAO gebietExtendedDAO;

  @Inject
  private transient GebietsartExtendedDAO gebietsartExtendedDAO;

  public void addProperties(FormBuilder formBuilder, InternetSeite internetSeite) {

    InternetSeiteCustomData internetSeiteCustomData = null;

    if (internetSeite.getCustomData() instanceof InternetSeiteCustomData) {
      internetSeiteCustomData = (InternetSeiteCustomData) internetSeite.getCustomData();
    }
    LambdaEnumProperty<InternetSeiteTyp> seitenTypMitLeererAuswahlProperty = internetSeite.getProperties().getSeitenTypMitLeererAuswahlProperty();
    seitenTypMitLeererAuswahlProperty.setItemIconMapper((icons, internetSeiteTyp) -> internetSeiteTyp.getIcon());
    seitenTypMitLeererAuswahlProperty.setValueFilter(internetSeiteCustomDataFactory::isSupported);

    formBuilder.addProperty(seitenTypMitLeererAuswahlProperty).withReadonly(internetSeiteCustomData != null);
    if (internetSeiteCustomData != null && internetSeite.getStatus().isKonfigurationNotwendig()) {
      internetSeite.setStatus(InternetSeiteStatus.AKTIV);
    }
    LambdaEnumProperty<InternetSeiteStatus> statusProperty = internetSeite.getProperties().getStatusProperty();
    statusProperty.setValueFilter(InternetSeiteStatus::isManuellAuswaehlbar);
    formBuilder.addProperty(statusProperty).withReadonly(internetSeiteCustomData == null);

    formBuilder.addProperty(internetSeite.getProperties().getTitelProperty()).required();
    formBuilder.addProperty(internetSeite.getProperties().getPositionProperty());
    formBuilder.addProperty(internetSeite.getProperties().getBeschreibungProperty());

    if (internetSeiteCustomData != null) {

      Wahl wahl = internetSeite.getWahl();
      InternetSeitePropertyContext context = new InternetSeitePropertyContext(messages, wahlExtendedDAO.attach(wahl),
          internetSeite.getSeitenTyp(), gebietNummerFormatter,
          () -> gebietExtendedDAO.findByWahl(wahl).stream().sorted(new GebietByBreadthFirstComparator()).collect(toList()),
          () -> wahlartExtendedDAO.findByAllOrderByName(wahl.getMandant()), ()->gebietsartExtendedDAO.findByAll(wahl.getMandant()));

      Map<InternetSeiteTypCustomDataKategorie, List<Property>> seiteProperties = internetSeiteCustomData
          .getProperties(context);

      seiteProperties.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEach(e -> {
        formBuilder.addSeparator(FacesMessageUtil.getEnumMessageKey(e.getKey()));
        for (Property kriteriumProperty : e.getValue()) {
          formBuilder.addProperty(kriteriumProperty);
        }
      });
    }
  }
}
