
package de.ivu.elect.business.wahl.entity;

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

import org.apache.commons.lang3.StringUtils;

import de.ivu.elect.business.security.Customer;


import static de.ivu.elect.business.security.Customer.BASE;
import static de.ivu.elect.business.security.Customer.CORE;
import static de.ivu.elect.business.security.Customer.DD_COMMON;
import static de.ivu.elect.business.security.Customer.DESTATIS_COMMON;
import static de.ivu.elect.business.security.Customer.KOM_BE_WAS;
import static de.ivu.elect.business.security.Customer.KOM_BY_WAS;
import static de.ivu.elect.business.security.Customer.KOM_MV_WAS;
import static de.ivu.elect.business.security.Customer.KOM_NI_WAS;
import static de.ivu.elect.business.security.Customer.KOM_RP_WAS;
import static de.ivu.elect.business.security.Customer.MUC_COMMON;
import static de.ivu.elect.business.security.Customer.NL_WAS;
import static de.ivu.elect.business.security.Customer.SL_COMMON;
import static java.util.Arrays.asList;

public enum WahlartSitzberechnungsalgorithmus {

  /**
   * WERTE NICHT LÖSCHEN ODER UMBENNEN, WERDEN IN EXPORTEN VERWENDET(!)
   */

  KEIN(BASE, "de.ivu.elect.business.sitzberechnung.control.KeinSitzberechnungsalgorithmus", "KeinSitzberechnungsalgorithmus") {

    @Override
    public boolean isKeinSitzberechnungsalgorithmus() {
      return true;
    }
  },

  ELECT_BUNDESTAGSWAHL(CORE, "de.ivu.elect.business.sitzberechnung.control.btw.BTWSitzberechnungsalgorithmus",
      "de.ivu.elect.business.sitzberechnung.control.btw2013.BTW2013Sitzberechnungsalgorithmus",
      "de.ivu.elect.business.sitzberechnung.control.btw2013.BTW2013Sitzberechnungsalgorithmus"),
  
  ELECT_DIREKTWAHL(CORE, "de.ivu.elect.business.sitzberechnung.control.direktwahl.StandardDirektwahlSitzberechnungsalgorithmus"),
  ELECT_DIREKTWAHL_MIT_QUORUM(CORE, "de.ivu.elect.business.sitzberechnung.control.direktwahl.StandardDirektwahlMitQuorumSitzberechnungsalgorithmus"), // ELECT-13228

  ELECT_ABSOLUTE_MEHRHEITSWAHL(CORE, "de.ivu.elect.business.sitzberechnung.control.absolutemehrheitswahl.AbsoluteMehrheitswahlSitzberechnungsalgorithmus"),
  ELECT_ABSOLUTE_MEHRHEITSWAHL_MIT_QUORUM(CORE, "de.ivu.elect.business.sitzberechnung.control.absolutemehrheitswahl.AbsoluteMehrheitswahlMitQuorumSitzberechnungsalgorithmus"), // ELECT-13228

  // DESTATIS
  DESTATIS_BUNDESTAGSWAHL(DESTATIS_COMMON, "DestatisBTW2013Sitzberechnungsalgorithmus"),
  DESTATIS_BUNDESTAGSWAHL_2021(DESTATIS_COMMON, "DestatisBTW2021Sitzberechnungsalgorithmus"),
  DESTATIS_EUROPAWAHL(DESTATIS_COMMON, "DestatisEUW2014Sitzberechnungsalgorithmus"),

  // BE
  BB_ABGEORDNETENHAUSWAHL(Collections.singletonList(KOM_BE_WAS), "AGH2016Sitzberechnungsalgorithmus"),
  BB_BEZIRKSVERORDNETENVERSAMMLUNG(Collections.singletonList(KOM_BE_WAS), "BVV2016Sitzberechnungsalgorithmus"),

  // SL
  SL_KOMMUNALWAHL(SL_COMMON, "Kommunalwahl2018Sitzberechnungsalgorithmus"),
  SL_LANDTAGSWAHL(SL_COMMON, "LTW2008Sitzberechnungsalgorithmus"),

  // BY
  BY_GEMEINDERATSWAHL_2020(asList(KOM_BY_WAS, MUC_COMMON), "ByGrw2020Sitzberechnungsalgorithmus"),
  BY_KREISTAGSWAHL_2020(KOM_BY_WAS, "ByKtw2020Sitzberechnungsalgorithmus"),

  // MV
  MV_KOMMUNALWAHL(KOM_MV_WAS, "MvKommunalwahl2019Sitzberechnungsalgorithmus"),

  // NI
  NI_KOMMUNALWAHL_2021(KOM_NI_WAS, "NiKommunalwahl2021Sitzberechnungsalgorithmus"),
  NI_KOMMUNALWAHL_2021_LOSENTSCHEIDE_BESCHRAENKT(KOM_NI_WAS, "NiKommunalwahl2021SitzberechnungsalgorithmusLosentscheideBeschraenkt"),

  // RP
  RP_KOMMUNALWAHL_2019(KOM_RP_WAS, "RpKommunalwahl2019Sitzberechnungsalgorithmus"),

  // DD UND MUC
  CUSTOMER_STADTRATSWAHL(asList(DD_COMMON, MUC_COMMON), "SRW2014SitzberechnungsalgorithmusKonfiguration"),

  // DD
  DD_AUSLAENDERBEIRATSWAHL(DD_COMMON, "de.ivu.elect.business.sitzberechnung.control.ausbw2014.AuslBW2014Sitzberechnungsalgorithmus"),
  DD_LANDTAGSWAHL(DD_COMMON, "de.ivu.elect.business.sitzberechnung.control.ltw2014.LTW2014Sitzberechnungsalgorithmus"),
  DD_OBERBUERGERMEISTERWAHL(DD_COMMON, "de.ivu.elect.business.sitzberechnung.control.obw2015.OBW2015Sitzberechnungsalgorithmus"),
  DD_ORTSCHAFTSRATSWAHL(DD_COMMON, "de.ivu.elect.business.sitzberechnung.control.orw2014.ORW2014SitzberechnungsalgorithmusKonfiguration"),

  // MUC
  MUC_AUSLAENDERBEIRATSWAHL(MUC_COMMON, "de.ivu.elect.business.sitzberechnung.control.auslbw2014.AuslBW2014Sitzberechnungsalgorithmus"),

  // Cf. CUSTOMER_STADTRATSWAHL -> SRW2014Sitzberechnungsalgorithmus
  // Cf. BY_GEMEINDERATSWAHL_2020 -> SRW2020Sitzberechnungsalgorithmus

  MUC_BEZIRKSAUSSCHUSSWAHL(MUC_COMMON, "de.ivu.elect.business.sitzberechnung.control.baw2014.BAW2014Sitzberechnungsalgorithmus"),
  MUC_BEZIRKSAUSSCHUSSWAHL_2020(MUC_COMMON, "BAW2020Sitzberechnungsalgorithmus"),

  MUC_OBERBUERGERMEISTERWAHL(MUC_COMMON, "de.ivu.elect.business.sitzberechnung.control.obw2014.OBW2014Sitzberechnungsalgorithmus"),

  MUC_SENIORENVERTRETUNGSWAHL(MUC_COMMON, "de.ivu.elect.business.sitzberechnung.control.senvw2013.SenVW2013Sitzberechnungsalgorithmus"),

  NL_EK(NL_WAS),
  NL_TK(NL_WAS),
  NL_EP(NL_WAS),
  NL_GR2(NL_WAS),
  NL_GR1(NL_WAS),
  NL_PS2(NL_WAS),
  NL_PS1(NL_WAS),
  NL_AB2(NL_WAS),
  NL_AB1(NL_WAS),
  NL_ER1(NL_WAS),
  NL_BC(NL_WAS),
  NL_GC(NL_WAS)

  //  // Standard
  //  STANDARD_EUROPAWAHL(STANDARD_COMMON, "DummyEUW2015Sitzberechnungsalgorithmus")

  ;

  private final List<Customer> customers;

  private final List<String> legcacyIds;

  WahlartSitzberechnungsalgorithmus(Customer customer, String... legcacyIds) {
    this(Collections.singletonList(customer), legcacyIds);
  }

  WahlartSitzberechnungsalgorithmus(List<Customer> customers, String... legcacyIds) {
    this.customers = customers;
    if (legcacyIds == null) {
      this.legcacyIds = Collections.emptyList();
    } else {
      this.legcacyIds = asList(legcacyIds);
    }
  }

  public List<String> getLegcacyIds() {
    return legcacyIds;
  }

  public static WahlartSitzberechnungsalgorithmus fromId(String id) {
    if (StringUtils.isBlank(id)) {
      return KEIN;
    }
    try {
      return valueOf(id);
    } catch (Exception e) {
      // ignore legacy
    }
    return Arrays.stream(values()).filter(value -> value.getLegcacyIds().stream().anyMatch(id::equalsIgnoreCase)).findFirst().orElse(KEIN);
  }

  public boolean isKeinSitzberechnungsalgorithmus() {
    return false;
  }

  public boolean isDeprecated() {
    return false;
  }

  public static void main(String[] args) {
    for (WahlartSitzberechnungsalgorithmus value : WahlartSitzberechnungsalgorithmus.values()) {

      for (String legcacyId : value.getLegcacyIds()) {
        System.out.println("UPDATE WAHLDURCHFUEHRUNG SET sitzberechnungsalgorithmus ='" + value.name() + "' WHERE sitzberechnungsalgorithmus = '" + legcacyId + "';");
      }
    }
    System.out.println("UPDATE WAHLDURCHFUEHRUNG SET sitzberechnungsalgorithmus = 'KEIN' WHERE sitzberechnungsalgorithmus NOT IN ('"
        + Arrays.stream(values()).map(Enum::name).collect(Collectors.joining("', '")) + "');");
    for (WahlartSitzberechnungsalgorithmus value : WahlartSitzberechnungsalgorithmus.values()) {
      for (String legcacyId : value.getLegcacyIds()) {
        System.out.println("UPDATE ERGEBNIS SET sitzberechnungsalgorithmus ='" + value.name() + "' WHERE sitzberechnungsalgorithmus = '" + legcacyId + "';");
      }
    }

    System.out.println(
        "UPDATE ERGEBNIS SET sitzberechnungsalgorithmus = 'KEIN' WHERE sitzberechnungsalgorithmus NOT IN ('" + Arrays.stream(values()).map(Enum::name).collect(Collectors.joining("', '")) + "');");

  }

  protected List<Customer> getCustomers() {
    return customers;
  }

  public String getResourceName() {
    return name().toLowerCase().replaceAll("_", "-") + ".zip";
  }

  public boolean isGeeignetFuer(Customer customer) {
    return customer != null && getCustomers().stream().anyMatch(c -> customer.contains(c));
  }
}
