
package de.ivu.elect.core.exchange.stimmen.csv;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import de.ivu.elect.business.ergebnis.control.StimmenImportContext;
import de.ivu.elect.business.ergebnis.entity.Stimmen;
import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.exchange.csv.CsvMarshaller;

public class ZweiStimmenCsvImportMapper extends AbstractStimmenCsvImportMapper<ZweiStimmenCsvDTO> {

  public static final String FORMAT_NAME = "file.format.direktstimmen.und.listenstimmen";

  @Inject
  private transient CsvMarshaller csvMarshaller;

  public ZweiStimmenCsvImportMapper() {
    super();
  }

  @Override
  protected CsvMarshaller getCsvMarshaller() {
    return csvMarshaller;
  }

  @Override
  protected Class<ZweiStimmenCsvDTO> getStimmenCsvDTOClass() {
    return ZweiStimmenCsvDTO.class;
  }

  @Override
  protected String getFormatName() {
    return FORMAT_NAME;
  }

  @Override
  public boolean isAcceptContext(StimmenImportContext context) {
    if (!super.isAcceptContext(context)) {
      return false;
    }
    if (context != null && context.getWahl() != null) {
      return context.getWahl().isWahlMitDirektkandidatengebieten() && context.getWahl().isWahlMitListengebieten();
    }
    return true;
  }

  @Override
  protected void addGueltigeStimmen(List<Stimmen> result, Gebiet gebiet, ZweiStimmenCsvDTO importStimmen) {
    Gruppe gruppeGueltige = createSystemGruppeGueltige();

    GruppeImGebiet gruppeImGebietGueltige = createGruppeImGebietFor(gebiet, gruppeGueltige);

    if (importStimmen.getAnzahlDirektstimmenGueltig() != null) {
      Stimmen gueltigeErststimmen = new Stimmen();
      gueltigeErststimmen.setStimmenart(Stimmenart.DIREKTSTIMME);
      gueltigeErststimmen.setGruppe(gruppeImGebietGueltige.getGruppe());
      gueltigeErststimmen.setGebiet(gruppeImGebietGueltige.getGebiet());
      gueltigeErststimmen.setAnzahl(importStimmen.getAnzahlDirektstimmenGueltig());
      result.add(gueltigeErststimmen);
    }

    if (importStimmen.getAnzahlListenstimmenGueltig() != null) {
      Stimmen gueltigeZweitstimmen = new Stimmen();
      gueltigeZweitstimmen.setStimmenart(Stimmenart.LISTENSTIMME);
      gueltigeZweitstimmen.setGruppe(gruppeImGebietGueltige.getGruppe());
      gueltigeZweitstimmen.setGebiet(gruppeImGebietGueltige.getGebiet());
      gueltigeZweitstimmen.setAnzahl(importStimmen.getAnzahlListenstimmenGueltig());
      result.add(gueltigeZweitstimmen);
    }
  }

  @Override
  protected void addUngueltigeStimmen(List<Stimmen> result, Gebiet gebiet, ZweiStimmenCsvDTO importStimmen) {
    Gruppe gruppeUngueltige = createSystemGruppeUngueltige();

    GruppeImGebiet gruppeImGebietUngueltige = createGruppeImGebietFor(gebiet, gruppeUngueltige);

    if (importStimmen.getAnzahlDirektstimmenUngueltig() != null) {
      Stimmen ungueltigeErststimmen = new Stimmen();
      ungueltigeErststimmen.setStimmenart(Stimmenart.DIREKTSTIMME);
      ungueltigeErststimmen.setGruppe(gruppeImGebietUngueltige.getGruppe());
      ungueltigeErststimmen.setGebiet(gruppeImGebietUngueltige.getGebiet());
      ungueltigeErststimmen.setAnzahl(importStimmen.getAnzahlDirektstimmenUngueltig());
      result.add(ungueltigeErststimmen);
    }

    if (importStimmen.getAnzahlListenstimmenUngueltig() != null) {
      Stimmen ungueltigeZweitstimmen = new Stimmen();
      ungueltigeZweitstimmen.setStimmenart(Stimmenart.LISTENSTIMME);
      ungueltigeZweitstimmen.setGruppe(gruppeImGebietUngueltige.getGruppe());
      ungueltigeZweitstimmen.setGebiet(gruppeImGebietUngueltige.getGebiet());
      ungueltigeZweitstimmen.setAnzahl(importStimmen.getAnzahlListenstimmenUngueltig());
      result.add(ungueltigeZweitstimmen);
    }
  }

  @Override
  protected List<Stimmen> createStimmenForPolitischeGruppen(StimmenImportContext context, ZweiStimmenCsvDTO importStimmen) {
    List<Stimmen> result = new ArrayList<>();

    if (importStimmen.getPolitischeGruppenStimmen() != null) {
      for (ZweiGruppeStimmenDTO gruppeStimmen : importStimmen.getPolitischeGruppenStimmen()) {

        GruppeImGebiet gruppeImGebiet = mappeGruppeImGebietForGebiet(context, importStimmen.getGebietsart(), importStimmen.getGebietsnummer(), gruppeStimmen.getGruppeSchluessel());

        createStimmenIfAnzahlNotZero(result, gruppeStimmen, gruppeImGebiet);
      }
    }

    return result;
  }

  private void createStimmenIfAnzahlNotZero(List<Stimmen> result, ZweiGruppeStimmenDTO gruppeStimmen, GruppeImGebiet gruppeImGebiet) {
    if (gruppeStimmen.getAnzahlDirektstimmen() != null) {
      result.add(createDirektstimmen(gruppeStimmen, gruppeImGebiet));
    }

    if (gruppeStimmen.getAnzahlListenstimmen() != null) {
      result.add(createListenstimmen(gruppeStimmen, gruppeImGebiet));
    }
  }

  private Stimmen createDirektstimmen(ZweiGruppeStimmenDTO parteiStimmen, GruppeImGebiet gruppeImGebiet) {
    return createStimmen(parteiStimmen.getAnzahlDirektstimmen(), Stimmenart.DIREKTSTIMME, gruppeImGebiet);
  }

  private Stimmen createListenstimmen(ZweiGruppeStimmenDTO parteiStimmen, GruppeImGebiet gruppeImGebiet) {
    return createStimmen(parteiStimmen.getAnzahlListenstimmen(), Stimmenart.LISTENSTIMME, gruppeImGebiet);
  }
}
