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

import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import javax.ejb.Stateless;
import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.staat.entity.Staat;
import de.ivu.elect.jee.entity.customdata.EmptyCustomData;
import de.ivu.elect.jee.exception.ElectCommonException;

@Stateless
public class StaatCreator {

  private static final Logger LOG = LoggerFactory.getLogger(StaatCreator.class);

  protected static final String DESTATIS_BEV_CSV = "01-01-2013-staaten-destatis-bev.csv";
  protected static final String DESTATIS_BEV_CSV_ERWEITERT = "28-01-2021-erweiterte-staaten-liste.csv"; // die ursprüngliche Liste durch Vorgaben von NL erweitert (ELECTVAPP-1232)

  protected static final String STAATEN_MUC = "11-04-2013-staatsangehoerigkeiten_muc_ewo.csv";

  @Inject
  protected StaatFactory staatFactory;

  @Inject
  protected StaatDAO staatDao;

  public StaatCreator() {
    super();
  }

  public void initStaaten() {
    if (!existsAnyStaat()) {
      LOG.info("Keine Staaten vorhanden - anlegen");

      for (Staat staat : getStaaten()) {
        save(staat);

        LOG.info("Staat " + staat.getNameStaat() + " angelegt");
      }

      LOG.info("Staaten angelegt");
    } else {
      LOG.info("Staaten bereits vorhanden");
    }
  }

  private boolean existsAnyStaat() {
    return !staatDao.findByAllOrderedByNameStaat().isEmpty();
  }

  protected List<Staat> getStaaten() {
    return getStaatenCustomCodeDestatisBev();
  }

  // Aktuell nicht genutzt, aber zum Vergleich der Listen implementiert
  private List<Staat> getStaatenCustomCodeMuc() {
    List<Staat> staatenMuc = new ArrayList<>();

    try (Scanner scanner = new Scanner(getClass().getClassLoader().getResourceAsStream(STAATEN_MUC), Charset.forName("UTF-8").name())) {
      String header = scanner.nextLine();
      while (scanner.hasNextLine()) {
        String next = scanner.nextLine();
        staatenMuc.add(createStaatFromMucData(next));
      }
    }
    return staatenMuc;
  }

  private Staat createStaatFromMucData(String next) {
    Staat staat = new Staat(EmptyCustomData.INSTANCE);

    String[] split = next.split(";");
    for (int i = 0; i < split.length; i++) {
      split[i] = StringUtils.normalizeSpace(split[i]);
    }

    // Stag Schlüssel;Staatsgebiet;Staatsangehörigkeit
    // 000;Deutschland;deutsch
    staat.setCustomCodeStaatsangehoerigkeit(split[0]);
    staat.setNameStaat(split[1]);
    staat.setNameStaatsangehoerigkeit(split[2]);

    return staat;
  }

  protected List<Staat> getStaatenCustomCodeDestatisBev() {
    try (Scanner scanner = new Scanner(getDestatisBevFileInputStream(), Charset.forName("UTF-8").name())) {
      List<Staat> result = new ArrayList<>();

      // Skip the first line containing the column names!
      scanner.nextLine();

      while (scanner.hasNextLine()) {
        result.add(createStaat(scanner.nextLine().split(",")));
      }

      return result;
    } catch (Exception ex) {
      throw new ElectCommonException("Die Liste der Staaten kann nicht geparst werden: " + ex.getMessage(), ex);
    }
  }

  private InputStream getDestatisBevFileInputStream() {
    return getClassLoader().getResourceAsStream(StaatCreator.DESTATIS_BEV_CSV_ERWEITERT);
  }

  private ClassLoader getClassLoader() {
    return Thread.currentThread().getContextClassLoader();
  }

  private Staat createStaat(String[] values) {
    return createStaat(values[0], values[1], values[2], values[3], values[4], values[5], values[6]);
  }

  protected Staat createStaat(String iso3166Numerisch, String iso3166Alpha2, String customCodeStaat, String customCodeStaatsangehoerigkeit,
      String nameStaat, String nameStaatsangehoerigkeit, String euStaat) {
    Staat staat = staatFactory.create();

    staat.setIso3166Numerisch(iso3166Numerisch);
    staat.setIso3166Alpha2(iso3166Alpha2);

    staat.setCustomCodeStaat(customCodeStaat);
    staat.setCustomCodeStaatsangehoerigkeit(customCodeStaatsangehoerigkeit);

    staat.setNameStaat(nameStaat);
    staat.setNameStaatsangehoerigkeit(nameStaatsangehoerigkeit);

    staat.setEuStaat("1".equals(euStaat));

    return staat;
  }

  private void save(Staat staat) {
    staatDao.persist(staat);
  }
}
