
package de.ivu.elect.dokumente.wahlvorschlag;

import java.util.Date;

import javax.annotation.Nullable;

import de.ivu.document.generator.template.annotations.DocumentComplexField;
import de.ivu.document.generator.template.annotations.DocumentSimpleField;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.kandidatur.entity.WaehlerBenannteKandidaturen;
import de.ivu.elect.business.stimmzettel.entity.EntityAufStimmzettelDaten;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;
import de.ivu.elect.business.wahlvorschlag.entity.WahlvorschlagStimmzettelPosition;
import de.ivu.elect.dokumente.CoreElectContext;
import de.ivu.elect.dokumente.CoreElectContextBuilder;
import de.ivu.elect.dokumente.ElectDocument;
import de.ivu.elect.dokumente.ParameterKey;
import de.ivu.elect.dokumente.gebiet.GebietDokument;

public class CoreWahlvorschlagsdatenDocument extends ElectDocument {

  private static final long serialVersionUID = 1L;

  public static final CoreWahlvorschlagsdatenDocument EMPTY_OBJECT = new CoreWahlvorschlagsdatenDocument();

  @DocumentSimpleField("ID")
  public final Long id;

  @DocumentSimpleField("DatumDerEinreichung (Date-Objekt)")
  public final Date datumDerEinreichungAlsDate;

  @DocumentSimpleField("DatumDerEinreichung-Formatiert (Standardformat)")
  public final String datumDerEinreichung;

  @DocumentSimpleField("UhrzeitDerEinreichung")
  public final String uhrzeitDerEinreichung;

  @DocumentSimpleField("Kennwort")
  public final String kennwort;

  @DocumentSimpleField("Kurzname")
  public final String kurzname;

  @DocumentSimpleField("KurznameOderKennwort")
  public final String kurznameOderKennwort;

  @DocumentSimpleField("Zusatzbezeichnung")
  public final String zusatzbezeichnung; // ELECT-11233

  @DocumentComplexField("Wahlvorschlagstraeger")
  public final WahlvorschlagstraegerDokument wahlvorschlagstraeger;

  @DocumentComplexField("Gruppe")
  public final GruppeDokument gruppe;

  @DocumentSimpleField("IstListe")
  public final boolean isListe;

  @DocumentSimpleField("IstDirektkandidat")
  public final boolean isDirektkandidat;

  @DocumentSimpleField("IstReferendumOption")
  public final boolean isReferendumOption;

  @DocumentSimpleField("IstWaehlerBenannt")
  public final boolean isWaehlerBenannt; // ELECT-14303

  @DocumentSimpleField("LaufendeNummer")
  public final Long laufendeNummer;

  @DocumentSimpleField("Ordnungszahl-Vorgegeben")
  public final Long ordnungszahlVorgegeben;

  @DocumentSimpleField("Ordnungszahl-Vorgegeben-Formatiert")
  public final String ordnungszahlVorgegebenFormatted;

  @DocumentSimpleField("Ordnungszahl")
  public final Long ordnungszahl;

  @DocumentSimpleField("Ordnungszahl-Formatiert")
  public final String ordnungszahlFormatted;

  @DocumentSimpleField("Kennzahl-Formatiert")
  public final String kennzahlFormatted;

  @DocumentSimpleField("IstZugelassen")
  public final boolean zugelassen;

  @DocumentSimpleField("IstAufStimmzettel")
  public final boolean istAufStimzettel;

  @DocumentSimpleField("Zulassungsstatus")
  public final String zulassungsStatus;

  @DocumentComplexField("Gebiet")
  public final GebietDokument gebiet;

  private CoreWahlvorschlagsdatenDocument() {
    this(CoreElectContextBuilder.EMPTY);
  }

  public CoreWahlvorschlagsdatenDocument(CoreElectContext coreElectContext) {
    super(coreElectContext);

    this.id = null;

    this.datumDerEinreichungAlsDate = null;
    this.datumDerEinreichung = "";
    this.uhrzeitDerEinreichung = "";

    this.kennwort = "";
    this.kurzname = "";
    this.kurznameOderKennwort = "";
    this.zusatzbezeichnung = "";

    this.wahlvorschlagstraeger = new WahlvorschlagstraegerDokument(coreElectContext);
    this.gruppe = new GruppeDokument();

    this.isWaehlerBenannt = false;
    this.isListe = false;
    this.isDirektkandidat = false;
    this.isReferendumOption = false;

    this.laufendeNummer = null;

    this.ordnungszahlVorgegeben = null;
    this.ordnungszahlVorgegebenFormatted = "";

    this.ordnungszahl = null;
    this.ordnungszahlFormatted = "";

    this.kennzahlFormatted = "";

    this.zugelassen = false;
    this.istAufStimzettel = false;
    this.zulassungsStatus = "";

    this.gebiet = GebietDokument.EMPTY_OBJECT;
  }

  public CoreWahlvorschlagsdatenDocument(CoreElectContext coreElectContext, CoreWahlvorschlagsdatenDocument source) {
    super(coreElectContext);

    this.id = source.id;

    this.datumDerEinreichungAlsDate = source.datumDerEinreichungAlsDate;
    this.datumDerEinreichung = source.datumDerEinreichung;
    this.uhrzeitDerEinreichung = source.uhrzeitDerEinreichung;

    this.kennwort = source.kennwort;
    this.kurzname = source.kurzname;
    this.kurznameOderKennwort = source.kurznameOderKennwort;
    this.zusatzbezeichnung = source.zusatzbezeichnung;

    this.wahlvorschlagstraeger = source.wahlvorschlagstraeger;
    this.gruppe = source.gruppe;

    this.isWaehlerBenannt = source.isWaehlerBenannt;
    this.isListe = source.isListe;
    this.isDirektkandidat = source.isDirektkandidat;
    this.isReferendumOption = source.isReferendumOption;

    this.laufendeNummer = source.laufendeNummer;

    this.ordnungszahlVorgegeben = source.ordnungszahlVorgegeben;
    this.ordnungszahlVorgegebenFormatted = source.ordnungszahlVorgegebenFormatted;

    this.ordnungszahl = source.ordnungszahl;
    this.ordnungszahlFormatted = source.ordnungszahlFormatted;

    this.kennzahlFormatted = source.kennzahlFormatted;

    this.zugelassen = source.zugelassen;
    this.istAufStimzettel = source.istAufStimzettel;
    this.zulassungsStatus = source.zulassungsStatus;

    this.gebiet = source.gebiet;
  }

  public CoreWahlvorschlagsdatenDocument(CoreElectContext coreElectContext, EntityAufStimmzettelDaten entityAufStimmzettelDaten, Wahlvorschlag wahlvorschlag, @Nullable Long laufendeNummer) {
    this(coreElectContext, entityAufStimmzettelDaten, wahlvorschlag.getGebiet(), wahlvorschlag, laufendeNummer);
  }

  public CoreWahlvorschlagsdatenDocument(CoreElectContext coreElectContext, EntityAufStimmzettelDaten entityAufStimmzettelDaten, Gebiet gebiet, Wahlvorschlag wahlvorschlag,
      @Nullable Long laufendeNummer) {
    super(coreElectContext);

    this.id = wahlvorschlag.getId();

    Date zeitpunktDerEinreichung = wahlvorschlag.getZeitpunktDerEinreichung();
    this.datumDerEinreichungAlsDate = zeitpunktDerEinreichung;
    this.datumDerEinreichung = coreElectContext.formatDateMedium(zeitpunktDerEinreichung);
    this.uhrzeitDerEinreichung = coreElectContext.formatTimeHHmm(zeitpunktDerEinreichung);

    this.kennwort = wahlvorschlag.getKennwort();
    this.kurzname = wahlvorschlag.getKurzname();
    this.kurznameOderKennwort = wahlvorschlag.getKurznameOderKennwort();
    this.zusatzbezeichnung = wahlvorschlag.getZusatzbezeichnung();

    this.wahlvorschlagstraeger = new WahlvorschlagstraegerDokument(coreElectContext, wahlvorschlag.getGruppeImGebiet());
    this.gruppe = new GruppeDokument(wahlvorschlag.getGruppe());

    this.isWaehlerBenannt = WaehlerBenannteKandidaturen.isWaehlerBenannterWahlvorschlag(wahlvorschlag);
    this.isListe = wahlvorschlag.isListe();
    this.isDirektkandidat = wahlvorschlag.isDirektkandidat();
    this.isReferendumOption = wahlvorschlag.isReferendumOption();

    this.laufendeNummer = laufendeNummer;

    WahlvorschlagStimmzettelPosition wahlvorschlagStimmzettelPosition = wahlvorschlag.getStimmzettelPosition(gebiet, entityAufStimmzettelDaten);

    this.ordnungszahlVorgegeben = wahlvorschlagStimmzettelPosition.getPositionVorgegeben();
    this.ordnungszahlVorgegebenFormatted = wahlvorschlagStimmzettelPosition.formatPositionVorgegeben();

    this.ordnungszahl = wahlvorschlagStimmzettelPosition.getPosition();
    this.ordnungszahlFormatted = wahlvorschlagStimmzettelPosition.formatPosition();

    this.kennzahlFormatted = wahlvorschlagStimmzettelPosition.formatKennzahl();

    this.istAufStimzettel = wahlvorschlag.isAufStimmzettel();
    this.zugelassen = wahlvorschlag.isZugelassen();
    this.zulassungsStatus = coreElectContext.getMessage(wahlvorschlag.getWahlvorschlagStatus());

    if (wahlvorschlag.getGebiet() == null) {
      this.gebiet = GebietDokument.EMPTY_OBJECT;
    } else {
      this.gebiet = GebietDokument.lookupOrCreate(coreElectContext, wahlvorschlag.getGebiet());
    }
  }

  public static CoreWahlvorschlagsdatenDocument lookupOrCreate(CoreElectContext coreElectContext, EntityAufStimmzettelDaten entityAufStimmzettelDaten, @Nullable Wahlvorschlag wahlvorschlag,
      @Nullable Long laufendeNummer) {
    if (wahlvorschlag == null) {
      return CoreWahlvorschlagsdatenDocument.EMPTY_OBJECT;
    }

    ParameterKey paremeterKey = new ParameterKey(wahlvorschlag, laufendeNummer);

    CoreWahlvorschlagsdatenDocument result = coreElectContext.lookupCachedDokument(CoreWahlvorschlagsdatenDocument.class, paremeterKey);

    if (result == null) {
      result = new CoreWahlvorschlagsdatenDocument(coreElectContext, entityAufStimmzettelDaten, wahlvorschlag, laufendeNummer);

      coreElectContext.cacheDokument(CoreWahlvorschlagsdatenDocument.class, paremeterKey, result);
    }

    return result;
  }
}
