package it.micegroup.gestioneferie.pianificazioneferie.entity;

import java.io.Serializable;

import javax.validation.constraints.NotNull;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Id;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.FetchType;
import java.util.Collection;
import java.util.ArrayList;
import javax.persistence.OneToMany;
import javax.persistence.CascadeType;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.ToString;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonProperty.Access;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.annotation.JsonBackReference;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;

import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.Getter;
import lombok.AllArgsConstructor;

import javax.persistence.Table;

import org.apache.commons.lang3.StringUtils;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Hibernate;
import java.util.Objects;

import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiPianoFerieKey;

import it.micegroup.gestioneferie.libs.entity.BaseEntity;
import it.micegroup.voila2runtime.utils.EntityUtils;

@NoArgsConstructor

@Getter
@Setter
@Entity
@Table(name = "D_PIANI_FERIE")
public class DpianiFerie extends BaseEntity implements Serializable {

	// Generated SERIAL VERSION UID
	private static final long serialVersionUID = 3542956910L;

	@SuppressWarnings("unused")
	private static final Logger LOGGER = LogManager.getLogger(DpianiFerie.class);

	// ATTRIBUTES
	@Id

	@Column(name = "SEQU_ID_PIANO_FERIE", columnDefinition = "NUMBER(15)")
	private Long sequIdPianoFerie;
	@NotNull

	@Column(name = "CODI_PIANO_FERIE", columnDefinition = "VARCHAR(50)")
	private String codiPianoFerie;
	@NotNull

	@Column(name = "DESC_PIANO_FERIE", columnDefinition = "VARCHAR(250)")
	private String descPianoFerie;
	@NotNull

	@Column(name = "NUME_MIN_GG_PRESENZA", columnDefinition = "NUMBER(15)")
	private Long numeMinGgPresenza;
	@NotNull

	@Column(name = "NUME_MIN_GG_FERIE", columnDefinition = "NUMBER(15)")
	private Long numeMinGgFerie;
	@NotNull

	@Column(name = "NUME_MIN_GG_DA_PIANIFICARE", columnDefinition = "NUMBER(15)")
	private Long numeMinGgDaPianificare;
	@NotNull

	@Column(name = "NUME_MAX_GG_DA_PIANIFICARE", columnDefinition = "NUMBER(15)")
	private Long numeMaxGgDaPianificare;
	@NotNull

	@Column(name = "DATA_SCADENZA_PRESENTAZIONE", columnDefinition = "DATE")
	private Date dataScadenzaPresentazione;
	@NotNull

	@Column(name = "DATA_INIZIO_PERIODO", columnDefinition = "DATE")
	private Date dataInizioPeriodo;
	@NotNull

	@Column(name = "DATA_FINE_PERIODO", columnDefinition = "DATE")
	private Date dataFinePeriodo;
	@NotNull

	@Column(name = "FK_AMMINISTRAZIONE_PK", columnDefinition = "NUMBER(15)")
	private Long fkAmministrazionePk;
	@NotNull

	@Column(name = "FK_REGOLA_PIANO_FERIE_PK", columnDefinition = "NUMBER(15)")
	private Long fkRegolaPianoFeriePk;
	@NotNull

	@Column(name = "FK_STATO_PIANO_FERIE", columnDefinition = "NUMBER(15)")
	private Long fkStatoPianoFerie;
	@NotNull

	@Column(name = "FK_TIPO_ORGANIGRAMMA", columnDefinition = "NUMBER(15)")
	private Long fkTipoOrganigramma;
	@Column(name = "FK_UNITA_FUNZIONALE", columnDefinition = "NUMBER(15)")
	private Long fkUnitaFunzionale;
	@Column(name = "FK_UNITA_ORGANIZZATIVA_PK", columnDefinition = "NUMBER(15)")
	private Long fkUnitaOrganizzativaPk;
	@NotNull

	@Column(name = "FLAG_ELIMINATO", columnDefinition = "VARCHAR(1)")
	private String flagEliminato;
	@NotNull

	@Column(name = "UTENTE_ULTIMA_MODIFICA", columnDefinition = "VARCHAR(50)")
	private String utenteUltimaModifica;
	@NotNull

	@Column(name = "DATA_ULTIMA_MODIFICA", columnDefinition = "DATE")
	private Date dataUltimaModifica;
	@NotNull

	@Column(name = "DATA_INIZIO_RECORD", columnDefinition = "DATE")
	private Date dataInizioRecord;
	@NotNull

	@Column(name = "DATA_FINE_RECORD", columnDefinition = "DATE")
	private Date dataFineRecord;

	// IMPORTED PARENTS

	// CONSTRUCTORS
	public DpianiFerie(String objectKey) {
		super();
		setObjectKey(objectKey);
	}

	public DpianiFerie(String codiPianoFerie, String descPianoFerie, Long numeMinGgPresenza, Long numeMinGgFerie,
			Long numeMinGgDaPianificare, Long numeMaxGgDaPianificare, Date dataScadenzaPresentazione,
			Date dataInizioPeriodo, Date dataFinePeriodo, Long fkAmministrazionePk, Long fkRegolaPianoFeriePk,
			Long fkStatoPianoFerie, Long fkTipoOrganigramma, Long fkUnitaFunzionale, Long fkUnitaOrganizzativaPk,
			String flagEliminato, String utenteUltimaModifica, Date dataUltimaModifica, Date dataInizioRecord,
			Date dataFineRecord, Long sequIdPianoFerie) {
		super();

		this.codiPianoFerie = codiPianoFerie;
		this.descPianoFerie = descPianoFerie;
		this.numeMinGgPresenza = numeMinGgPresenza;
		this.numeMinGgFerie = numeMinGgFerie;
		this.numeMinGgDaPianificare = numeMinGgDaPianificare;
		this.numeMaxGgDaPianificare = numeMaxGgDaPianificare;
		this.dataScadenzaPresentazione = dataScadenzaPresentazione;
		this.dataInizioPeriodo = dataInizioPeriodo;
		this.dataFinePeriodo = dataFinePeriodo;
		this.fkAmministrazionePk = fkAmministrazionePk;
		this.fkRegolaPianoFeriePk = fkRegolaPianoFeriePk;
		this.fkStatoPianoFerie = fkStatoPianoFerie;
		this.fkTipoOrganigramma = fkTipoOrganigramma;
		this.fkUnitaFunzionale = fkUnitaFunzionale;
		this.fkUnitaOrganizzativaPk = fkUnitaOrganizzativaPk;
		this.flagEliminato = flagEliminato;
		this.utenteUltimaModifica = utenteUltimaModifica;
		this.dataUltimaModifica = dataUltimaModifica;
		this.dataInizioRecord = dataInizioRecord;
		this.dataFineRecord = dataFineRecord;
		this.sequIdPianoFerie = sequIdPianoFerie;
	}

	// CHILDREN
	@JsonProperty(access = Access.WRITE_ONLY)
	@JsonManagedReference("theDpianiFerie")
	@OneToMany(mappedBy = "theDpianiFerie", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	@ToString.Exclude
	private Collection<DrichiesteApprovazPf> theDrichiesteApprovazPf = new ArrayList<>();

	@JsonProperty(access = Access.WRITE_ONLY)
	@JsonManagedReference("theDpianiFerie")
	@OneToMany(mappedBy = "theDpianiFerie", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	@ToString.Exclude
	private Collection<DrichAdesionePf> theDrichAdesionePf = new ArrayList<>();

	@JsonProperty(access = Access.WRITE_ONLY)
	@JsonManagedReference("theDpianiFerie")
	@OneToMany(mappedBy = "theDpianiFerie", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	@ToString.Exclude
	private Collection<DammtiPianiFerie> theDammtiPianiFerie = new ArrayList<>();

	// PARENTS
	@ManyToOne(fetch = FetchType.LAZY)
	@JsonBackReference("theDstatiPianoFerie")
	@JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" }, allowSetters = true)
	private DstatiPianoFerie theDstatiPianoFerie;

	// GETTER/SETTER
	/**
	 * @return the sequIdPianoFerie
	 */
	public Long getSequIdPianoFerie() {
		return this.sequIdPianoFerie;
	}

	/**
	 * @param sequIdPianoFerie to set
	 */
	public void setSequIdPianoFerie(Long sequIdPianoFerie) {
		this.sequIdPianoFerie = sequIdPianoFerie;
	}

	/**
	 * @return the codiPianoFerie
	 */
	public String getCodiPianoFerie() {
		return this.codiPianoFerie;
	}

	/**
	 * @param codiPianoFerie to set
	 */
	public void setCodiPianoFerie(String codiPianoFerie) {
		this.codiPianoFerie = codiPianoFerie;
	}

	/**
	 * @return the descPianoFerie
	 */
	public String getDescPianoFerie() {
		return this.descPianoFerie;
	}

	/**
	 * @param descPianoFerie to set
	 */
	public void setDescPianoFerie(String descPianoFerie) {
		this.descPianoFerie = descPianoFerie;
	}

	/**
	 * @return the numeMinGgPresenza
	 */
	public Long getNumeMinGgPresenza() {
		return this.numeMinGgPresenza;
	}

	/**
	 * @param numeMinGgPresenza to set
	 */
	public void setNumeMinGgPresenza(Long numeMinGgPresenza) {
		this.numeMinGgPresenza = numeMinGgPresenza;
	}

	/**
	 * @return the numeMinGgFerie
	 */
	public Long getNumeMinGgFerie() {
		return this.numeMinGgFerie;
	}

	/**
	 * @param numeMinGgFerie to set
	 */
	public void setNumeMinGgFerie(Long numeMinGgFerie) {
		this.numeMinGgFerie = numeMinGgFerie;
	}

	/**
	 * @return the numeMinGgDaPianificare
	 */
	public Long getNumeMinGgDaPianificare() {
		return this.numeMinGgDaPianificare;
	}

	/**
	 * @param numeMinGgDaPianificare to set
	 */
	public void setNumeMinGgDaPianificare(Long numeMinGgDaPianificare) {
		this.numeMinGgDaPianificare = numeMinGgDaPianificare;
	}

	/**
	 * @return the numeMaxGgDaPianificare
	 */
	public Long getNumeMaxGgDaPianificare() {
		return this.numeMaxGgDaPianificare;
	}

	/**
	 * @param numeMaxGgDaPianificare to set
	 */
	public void setNumeMaxGgDaPianificare(Long numeMaxGgDaPianificare) {
		this.numeMaxGgDaPianificare = numeMaxGgDaPianificare;
	}

	/**
	 * @return the dataScadenzaPresentazione
	 */
	public Date getDataScadenzaPresentazione() {
		return this.dataScadenzaPresentazione;
	}

	/**
	 * @param dataScadenzaPresentazione to set
	 */
	public void setDataScadenzaPresentazione(Date dataScadenzaPresentazione) {
		this.dataScadenzaPresentazione = dataScadenzaPresentazione;
	}

	/**
	 * @return the dataInizioPeriodo
	 */
	public Date getDataInizioPeriodo() {
		return this.dataInizioPeriodo;
	}

	/**
	 * @param dataInizioPeriodo to set
	 */
	public void setDataInizioPeriodo(Date dataInizioPeriodo) {
		this.dataInizioPeriodo = dataInizioPeriodo;
	}

	/**
	 * @return the dataFinePeriodo
	 */
	public Date getDataFinePeriodo() {
		return this.dataFinePeriodo;
	}

	/**
	 * @param dataFinePeriodo to set
	 */
	public void setDataFinePeriodo(Date dataFinePeriodo) {
		this.dataFinePeriodo = dataFinePeriodo;
	}

	/**
	 * @return the fkAmministrazionePk
	 */
	public Long getFkAmministrazionePk() {
		return this.fkAmministrazionePk;
	}

	/**
	 * @param fkAmministrazionePk to set
	 */
	public void setFkAmministrazionePk(Long fkAmministrazionePk) {
		this.fkAmministrazionePk = fkAmministrazionePk;
	}

	/**
	 * @return the fkRegolaPianoFeriePk
	 */
	public Long getFkRegolaPianoFeriePk() {
		return this.fkRegolaPianoFeriePk;
	}

	/**
	 * @param fkRegolaPianoFeriePk to set
	 */
	public void setFkRegolaPianoFeriePk(Long fkRegolaPianoFeriePk) {
		this.fkRegolaPianoFeriePk = fkRegolaPianoFeriePk;
	}

	/**
	 * @return the fkStatoPianoFerie
	 */
	public Long getFkStatoPianoFerie() {
		return this.fkStatoPianoFerie;
	}

	/**
	 * @param fkStatoPianoFerie to set
	 */
	public void setFkStatoPianoFerie(Long fkStatoPianoFerie) {
		this.fkStatoPianoFerie = fkStatoPianoFerie;
	}

	/**
	 * @return the fkTipoOrganigramma
	 */
	public Long getFkTipoOrganigramma() {
		return this.fkTipoOrganigramma;
	}

	/**
	 * @param fkTipoOrganigramma to set
	 */
	public void setFkTipoOrganigramma(Long fkTipoOrganigramma) {
		this.fkTipoOrganigramma = fkTipoOrganigramma;
	}

	/**
	 * @return the fkUnitaFunzionale
	 */
	public Long getFkUnitaFunzionale() {
		return this.fkUnitaFunzionale;
	}

	/**
	 * @param fkUnitaFunzionale to set
	 */
	public void setFkUnitaFunzionale(Long fkUnitaFunzionale) {
		this.fkUnitaFunzionale = fkUnitaFunzionale;
	}

	/**
	 * @return the fkUnitaOrganizzativaPk
	 */
	public Long getFkUnitaOrganizzativaPk() {
		return this.fkUnitaOrganizzativaPk;
	}

	/**
	 * @param fkUnitaOrganizzativaPk to set
	 */
	public void setFkUnitaOrganizzativaPk(Long fkUnitaOrganizzativaPk) {
		this.fkUnitaOrganizzativaPk = fkUnitaOrganizzativaPk;
	}

	/**
	 * @return the flagEliminato
	 */
	public String getFlagEliminato() {
		return this.flagEliminato;
	}

	/**
	 * @param flagEliminato to set
	 */
	public void setFlagEliminato(String flagEliminato) {
		this.flagEliminato = flagEliminato;
	}

	/**
	 * @return the utenteUltimaModifica
	 */
	public String getUtenteUltimaModifica() {
		return this.utenteUltimaModifica;
	}

	/**
	 * @param utenteUltimaModifica to set
	 */
	public void setUtenteUltimaModifica(String utenteUltimaModifica) {
		this.utenteUltimaModifica = utenteUltimaModifica;
	}

	/**
	 * @return the dataUltimaModifica
	 */
	public Date getDataUltimaModifica() {
		return this.dataUltimaModifica;
	}

	/**
	 * @param dataUltimaModifica to set
	 */
	public void setDataUltimaModifica(Date dataUltimaModifica) {
		this.dataUltimaModifica = dataUltimaModifica;
	}

	/**
	 * @return the dataInizioRecord
	 */
	public Date getDataInizioRecord() {
		return this.dataInizioRecord;
	}

	/**
	 * @param dataInizioRecord to set
	 */
	public void setDataInizioRecord(Date dataInizioRecord) {
		this.dataInizioRecord = dataInizioRecord;
	}

	/**
	 * @return the dataFineRecord
	 */
	public Date getDataFineRecord() {
		return this.dataFineRecord;
	}

	/**
	 * @param dataFineRecord to set
	 */
	public void setDataFineRecord(Date dataFineRecord) {
		this.dataFineRecord = dataFineRecord;
	}

	// CHILD GETTER/SETTER
	/**
	 * @return the DrichiesteApprovazPf
	 */
	public Collection<DrichiesteApprovazPf> getTheDrichiesteApprovazPf() {
		return theDrichiesteApprovazPf;
	}

	/**
	 * @param aDrichiesteApprovazPfList to set
	 */
	public void setTheDrichiesteApprovazPf(Collection<DrichiesteApprovazPf> aDrichiesteApprovazPfList) {
		theDrichiesteApprovazPf = aDrichiesteApprovazPfList;
	}

	/**
	 * @return the DrichAdesionePf
	 */
	public Collection<DrichAdesionePf> getTheDrichAdesionePf() {
		return theDrichAdesionePf;
	}

	/**
	 * @param aDrichAdesionePfList to set
	 */
	public void setTheDrichAdesionePf(Collection<DrichAdesionePf> aDrichAdesionePfList) {
		theDrichAdesionePf = aDrichAdesionePfList;
	}

	/**
	 * @return the DammtiPianiFerie
	 */
	public Collection<DammtiPianiFerie> getTheDammtiPianiFerie() {
		return theDammtiPianiFerie;
	}

	/**
	 * @param aDammtiPianiFerieList to set
	 */
	public void setTheDammtiPianiFerie(Collection<DammtiPianiFerie> aDammtiPianiFerieList) {
		theDammtiPianiFerie = aDammtiPianiFerieList;
	}

	/// ADD CHILD
	public void addDrichiesteApprovazPf(DrichiesteApprovazPf drichiesteApprovazPf) {
		theDrichiesteApprovazPf.add(drichiesteApprovazPf);
	}

	public void addDrichAdesionePf(DrichAdesionePf drichAdesionePf) {
		theDrichAdesionePf.add(drichAdesionePf);
	}

	public void addDammtiPianiFerie(DammtiPianiFerie dammtiPianiFerie) {
		theDammtiPianiFerie.add(dammtiPianiFerie);
	}

	// PARENT GETTER/SETTER
	/**
	 * @return the DstatiPianoFerie
	 */
	@JsonProperty(access = Access.WRITE_ONLY)
	public DstatiPianoFerie getTheDstatiPianoFerie() {
		return theDstatiPianoFerie;
	}

	/**
	 * @param aDstatiPianoFerieList to set
	 */
	public void setTheDstatiPianoFerie(DstatiPianoFerie aDstatiPianoFerie) {
		theDstatiPianoFerie = aDstatiPianoFerie;
	}

	// PARENT ID GETTER/SETTER
	/**
	 * Return the dstatiPianoFerieKey from theDstatiPianoFerie.
	 * 
	 * @return dstatiPianoFerieKey from theDstatiPianoFerie.
	 */
	@JsonProperty
	public DstatiPianoFerieKey getDstatiPianoFerieKey() {
		// If the parent entity object is null, then return null
		if (getTheDstatiPianoFerie() == null) {
			return null;
		}
		// Return requested attribute
		return theDstatiPianoFerie.getDstatiPianoFerieKey();
	}

	// PARENT OBJECT TITLE
	/**
	 * Return the object title of theDstatiPianoFerie.
	 * 
	 * @return the object title of theDstatiPianoFerie.
	 */
	@JsonProperty
	public String getTheDstatiPianoFerieObjectTitle() {
		return getTheDstatiPianoFerie() != null ? getTheDstatiPianoFerie().getObjectTitle() : null;
	}

	// PARENT OBJECT KEY
	/**
	 * Return the object key of theDstatiPianoFerie.
	 * 
	 * @return the object key of theDstatiPianoFerie.
	 */
	@JsonProperty
	public String getTheDstatiPianoFerieObjectKey() {
		return getTheDstatiPianoFerie() != null ? getTheDstatiPianoFerie().getObjectKey() : null;
	}

	/**
	 * Set object key of theDstatiPianoFerie.
	 * 
	 */
	@JsonProperty
	public void setTheDstatiPianoFerieObjectKey(String objectKey) {
		if (EntityUtils.isValueChanged(getTheDstatiPianoFerieObjectKey(), objectKey, false)) {
			DstatiPianoFerie dstatiPianoFerie = new DstatiPianoFerie();
			dstatiPianoFerie.setObjectKey(objectKey);
			setTheDstatiPianoFerie(dstatiPianoFerie);
		}
	}

	// IMPORTED PARENT OBJECT KEY

	// OPERATIONS

	// OBJECT KEY
	/**
	 * Restituisce l'identificativo della chiave in formato stringa. Ritorna
	 * conveniente nelle selezioni da lista.
	 * 
	 * @return L'identificativo della chiave in formato pk1||pk2||pk3...
	 */
	public String getObjectKey() {
		return getObjectKeyById(getSequIdPianoFerie());
	}

	public String getObjectKeyById(Long identification) {
		if (identification == null) {
			return null;
		}
		StringBuilder output = new StringBuilder();
		output.append(identification);
		return output.toString();
	}

	/**
	 * Inizializza la parte identificativa del bean in base alla stringa tokenizzata
	 * da "||" fornita in input.
	 * 
	 * @param key L'identificativo della chiave in formato pk1||pk2||pk3...
	 */
	public void setObjectKey(String key) {
		if (key == null || key.trim().length() == 0) {
			return;
		}
		String[] array = StringUtils.splitByWholeSeparatorPreserveAllTokens(key, getRowIdFieldDelimiter());
		int ctr = 0;

		setSequIdPianoFerie(getLongCheckedAgainstNullContent(array[ctr]));
	}

	// OBJECT TITLE
	public String getObjectTitle() {
		StringBuilder output = new StringBuilder();
		output.append(getCodiPianoFerie());
		return output.toString();
	}

	// PREPERSIST

	@PrePersist
	public void prePersist() {
	}

	@PreUpdate
	public void PreUpdate() {
	}

	// Equals / HashCode
	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o))
			return false;
		DpianiFerie that = (DpianiFerie) o;
		return sequIdPianoFerie != null && Objects.equals(sequIdPianoFerie, that.sequIdPianoFerie);
	}

	@Override
	public int hashCode() {
		return Objects.hash(sequIdPianoFerie);
	}
}
