
package de.ivu.elect.business.stimmeingabe.boundary;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeGruppeStimmen;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeGruppeStimmenErfassenModel;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeStimmen;

public class StimmeingabeGruppeStimmenErfassenModelLayout implements Serializable {

  private static final long serialVersionUID = 1L;

  public StimmeingabeGruppeStimmenErfassenModelLayout() {
    super();
  }

  /**
   * Reihenfolge IMMER: Ungültige + Gültige
   */
  public List<StimmeingabeGruppeStimmen> layoutSystemGruppeStimmenGueltigeUngueltigeConfiguredOrDefault(StimmeingabeGruppeStimmenErfassenModel model,
      StimmeingabeGruppeStimmenErfassenModelContext context, Function<StimmeingabeGruppeStimmenErfassenModelLayout, List<StimmeingabeGruppeStimmen>> fallbackFct) {
    if (context.isTblStimmeingabenSystemGruppeStimmenConfigured()) {
      return layoutSystemGruppeStimmenUngueltigeGueltige(model, context);
    }

    if (context.isTblStimmeingabenGruppeStimmenConfigured()) {
      return new ArrayList<>(); // ELECT-8664, Ungültige + Gültige werden in Tabelle mit den Gruppen angezeigt...
    }

    return fallbackFct.apply(this);
  }

  /**
   * Reihenfolge IMMER: Gruppen || Ungültige + Gültige + Gruppen || Gruppen + Gültige + Ungültige
   */
  public List<StimmeingabeGruppeStimmen> layoutPolitischeGruppeStimmenMitSystemGruppeStimmenGueltigeUngueltigeConfiguredOrDefault(StimmeingabeGruppeStimmenErfassenModel model,
      StimmeingabeGruppeStimmenErfassenModelContext context, Function<StimmeingabeGruppeStimmenErfassenModelLayout, List<StimmeingabeGruppeStimmen>> fallbackFct) {
    if (context.isTblStimmeingabenGruppeStimmenConfigured()) {
      if (context.isTblStimmeingabenGruppeStimmenMitStimmeingabenSystemGruppeStimmenAlsErsteZeilen()) {
        return layoutPolitischeGruppeStimmenMitSystemGruppeStimmenUngueltigeGueltigeAlsErsteZeilen(model, context);
      }

      if (context.isTblStimmeingabenGruppeStimmenMitStimmeingabenSystemGruppeStimmenAlsLetzteZeilen()) {
        return layoutPolitischeGruppeStimmenMitSystemGruppeStimmenGueltigeUngueltigeAlsLetzteZeilen(model, context);
      }

      return layoutPolitischeGruppeStimmenOhneSystemGruppeStimmen(model, context);
    }

    return fallbackFct.apply(this);
  }

  public List<StimmeingabeGruppeStimmen> layoutPolitischeGruppeStimmenOhneSystemGruppeStimmen(StimmeingabeGruppeStimmenErfassenModel model, StimmeingabeGruppeStimmenErfassenModelContext context) {
    List<StimmeingabeGruppeStimmen> result = new ArrayList<>();

    result.addAll(model.getStimmenPolitischeGruppen());

    return result;
  }

  public List<StimmeingabeGruppeStimmen> layoutPolitischeGruppeStimmenKeine(StimmeingabeGruppeStimmenErfassenModel model, StimmeingabeGruppeStimmenErfassenModelContext context) {
    return new ArrayList<>();
  }

  public List<StimmeingabeGruppeStimmen> layoutPolitischeGruppeStimmenMitSystemGruppeStimmenUngueltigeGueltigeAlsErsteZeilen(StimmeingabeGruppeStimmenErfassenModel model,
      StimmeingabeGruppeStimmenErfassenModelContext context) {
    return layoutPolitischeGruppeStimmenMitSystemGruppeStimmenUngueltigeGueltigeAlsErsteZeilen(model, context, context.isTblStimmeingabenGruppeStimmenMitStimmeingabenSystemGruppeStimmenAbgesetzt());
  }

  public List<StimmeingabeGruppeStimmen> layoutPolitischeGruppeStimmenMitSystemGruppeStimmenUngueltigeGueltigeAlsErsteZeilen(StimmeingabeGruppeStimmenErfassenModel model,
      StimmeingabeGruppeStimmenErfassenModelContext context, boolean stimmeingabenSystemGruppeStimmenAbgesetzt) {
    List<StimmeingabeGruppeStimmen> result = new ArrayList<>();

    boolean systemGruppeGueltigeRendered = model.hasStimmenGruppeGueltige();
    boolean systemGruppeUngueltigeRendered = model.hasStimmenGruppeUngueltige();

    if (systemGruppeUngueltigeRendered) {
      result.add(model.getStimmenGruppeUngueltige());
    }

    if (systemGruppeGueltigeRendered) {
      result.add(model.getStimmenGruppeGueltige());
    }

    if (stimmeingabenSystemGruppeStimmenAbgesetzt && (systemGruppeGueltigeRendered || systemGruppeUngueltigeRendered)) {
      result.add(createLeerzeileGruppeStimmen());
    }

    result.addAll(model.getStimmenPolitischeGruppen());

    return result;
  }

  public List<StimmeingabeGruppeStimmen> layoutPolitischeGruppeStimmenMitSystemGruppeStimmenGueltigeUngueltigeAlsLetzteZeilen(StimmeingabeGruppeStimmenErfassenModel model,
      StimmeingabeGruppeStimmenErfassenModelContext context) {
    return layoutPolitischeGruppeStimmenMitSystemGruppeStimmenGueltigeUngueltigeAlsLetzteZeilen(model, context, context.isTblStimmeingabenGruppeStimmenMitStimmeingabenSystemGruppeStimmenAbgesetzt());
  }

  public List<StimmeingabeGruppeStimmen> layoutPolitischeGruppeStimmenMitSystemGruppeStimmenGueltigeUngueltigeAlsLetzteZeilen(StimmeingabeGruppeStimmenErfassenModel model,
      StimmeingabeGruppeStimmenErfassenModelContext context, boolean stimmeingabenSystemGruppeStimmenAbgesetzt) {
    List<StimmeingabeGruppeStimmen> result = new ArrayList<>();

    boolean systemGruppeGueltigeRendered = model.hasStimmenGruppeGueltige();
    boolean systemGruppeUngueltigeRendered = model.hasStimmenGruppeUngueltige();

    result.addAll(model.getStimmenPolitischeGruppen());

    if (stimmeingabenSystemGruppeStimmenAbgesetzt && (systemGruppeGueltigeRendered || systemGruppeUngueltigeRendered)) {
      result.add(createLeerzeileGruppeStimmen());
    }

    if (systemGruppeGueltigeRendered) {
      result.add(model.getStimmenGruppeGueltige());
    }

    if (systemGruppeUngueltigeRendered) {
      result.add(model.getStimmenGruppeUngueltige());
    }

    return result;
  }

  /**
   * @deprecated MUC-spezifisch bei EUW
   * @see AbstractStimmeingabeGruppeStimmenModelBuilder#layoutSystemGruppeStimmenUngueltige
   */
  @Deprecated
  public List<StimmeingabeGruppeStimmen> layoutPolitischeGruppeStimmenMitSystemGruppeStimmenGueltigeAlsLetzteZeile(StimmeingabeGruppeStimmenErfassenModel model,
      StimmeingabeGruppeStimmenErfassenModelContext context) {
    List<StimmeingabeGruppeStimmen> result = new ArrayList<>();

    result.addAll(model.getStimmenPolitischeGruppen());

    if (model.hasStimmenGruppeGueltige()) {
      result.add(model.getStimmenGruppeGueltige());
    }

    return result;
  }

  public List<StimmeingabeGruppeStimmen> layoutSystemGruppeStimmenKeine(StimmeingabeGruppeStimmenErfassenModel model, StimmeingabeGruppeStimmenErfassenModelContext context) {
    return new ArrayList<>();
  }

  public List<StimmeingabeGruppeStimmen> layoutSystemGruppeStimmenUngueltigeGueltige(StimmeingabeGruppeStimmenErfassenModel model, StimmeingabeGruppeStimmenErfassenModelContext context) {
    List<StimmeingabeGruppeStimmen> result = new ArrayList<>();

    if (model.hasStimmenGruppeUngueltige()) {
      result.add(model.getStimmenGruppeUngueltige());
    }

    if (model.hasStimmenGruppeGueltige()) {
      result.add(model.getStimmenGruppeGueltige());
    }

    return result;
  }

  public List<StimmeingabeGruppeStimmen> layoutSystemGruppeStimmenUngueltigeCustomGueltige(StimmeingabeGruppeStimmenErfassenModel model, StimmeingabeGruppeStimmenErfassenModelContext context) {
    List<StimmeingabeGruppeStimmen> result = new ArrayList<>();

    if (model.hasStimmenGruppeUngueltige()) {
      result.add(model.getStimmenGruppeUngueltige());
    }

    if (model.hasStimmenGruppeCustom()) {
      result.add(model.getStimmenGruppeCustom()); // Bspw. "Gültige Stimmzettel"...
    }

    if (model.hasStimmenGruppeGueltige()) {
      result.add(model.getStimmenGruppeGueltige());
    }

    return result;
  }

  /**
   * @deprecated MUC-spezifisch bei EUW (in SystemGruppe-Stimmen-Tabelle ÜBER der Gruppe-Stimmen-Tabelle) und Kommunalwahl (in SystemGruppe-Stimmen-Tabelle UNTER der Gruppe-Stimmen-Tabelle)
   * @see src/main/resources/META-INF/contracts/elect/stimmeingabe/by-kommunal-listenwahl-stimmeingabe-gruppe-stimmen-erfassen.xhtml
   */
  @Deprecated
  public List<StimmeingabeGruppeStimmen> layoutSystemGruppeStimmenUngueltige(StimmeingabeGruppeStimmenErfassenModel model, StimmeingabeGruppeStimmenErfassenModelContext context) {
    List<StimmeingabeGruppeStimmen> result = new ArrayList<>();

    if (model.hasStimmenGruppeUngueltige()) {
      result.add(model.getStimmenGruppeUngueltige());
    }

    return result;
  }

  // ELECT-12178
  private StimmeingabeGruppeStimmen createLeerzeileGruppeStimmen() {
    StimmeingabeGruppeStimmen stimmeingabeGruppeStimmen = StimmeingabeGruppeStimmen.empty();
    stimmeingabeGruppeStimmen.addStimmeingabeDirektstimmeStyleClass(StimmeingabeStimmen.STYLE_CLASS_EMPTY);
    stimmeingabeGruppeStimmen.addStimmeingabeListenstimmeStyleClass(StimmeingabeStimmen.STYLE_CLASS_EMPTY);
    stimmeingabeGruppeStimmen.addRowStyleClass(StimmeingabeStimmen.STYLE_CLASS_EMPTY);

    return stimmeingabeGruppeStimmen;
  }
}
