package info.bukova.isspst.data;

import info.bukova.isspst.Constants;
import info.bukova.isspst.storage.EntityWithAttachment;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "TRIP_BILL")
@Indexed
public class TripBill extends BaseData implements EntityWithAttachment, SeasonsAware {

	@OneToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "REQUIREMENT_ID")
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	private TripRequirement requirement;
	@Column(name = "RESULT_MESSAGE_DATE")
	private Date resultMessageDate;
	@Column(name = "SIGN_DATE")
	private Date signDate;

	@Column(name = "RESULT_MESSAGE", length = Constants.LEN_RESULT_MESSAGE)
	@Field(index = Index.YES, analyze = Analyze.YES)
	private String resultMessage;

	@Column(name = "FREE_MEALS")
	private boolean freeMeals;
	@Column(name = "FREE_HOUSING")
	private boolean freeHousing;
	@Column(name = "FREE_CAREFARE")
	private boolean freeCarfare;
	@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
	@LazyCollection(LazyCollectionOption.TRUE)
	@JoinColumn(name = "TRIP_BILL_ID")
	private List<TripBillItem> billItems;
	@Column(name = "ATTACHEMENTS_COUNT")
	private int attachementsCount;
	@Column(name = "DOWN_PAYMENT", precision = 15, scale = 4)
	private BigDecimal downPayment;
	@Column(name = "TOTAL", precision = 15, scale = 4)
	private BigDecimal total;
	@OneToMany(cascade = CascadeType.ALL)
	@LazyCollection(LazyCollectionOption.TRUE)
	@IndexedEmbedded
	private List<FileMetainfo> attachedFiles;
	@OneToOne(fetch = FetchType.EAGER, orphanRemoval = true)
	@JoinColumn(name = "APPROVAL_ID")
	private TripBillApproval approval;
	@Column(name = "SAVED")
	private Boolean saved; // Nastaveno na true, pokud uživatel udělá změnu- nepřenáší se pak částky od žadatele
	@Column(name = "PAID")
	private Boolean paid;
	@Column(name = "PAID_DATE")
	private Date paidDate;
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "SEASON_ID")
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	private Season season;
	
	public TripBill() {
		billItems = new ArrayList<TripBillItem>();
		attachedFiles = new ArrayList<FileMetainfo>();
	}

	public TripRequirement getRequirement() {
		return requirement;
	}

	public void setRequirement(TripRequirement requirement) {
		this.requirement = requirement;
	}

	public Date getResultMessageDate() {
		return resultMessageDate;
	}

	public void setResultMessageDate(Date resultMessageDate) {
		this.resultMessageDate = resultMessageDate;
	}

	public Date getSignDate() {
		return signDate;
	}

	public void setSignDate(Date signDate) {
		this.signDate = signDate;
	}

	public String getResultMessage()
	{
		return resultMessage;
	}

	public void setResultMessage(String resultMessage)
	{
		this.resultMessage = resultMessage;
	}

	public boolean isFreeMeals() {
		return freeMeals;
	}

	public void setFreeMeals(boolean freeMeals) {
		this.freeMeals = freeMeals;
	}

	public boolean isFreeHousing() {
		return freeHousing;
	}

	public void setFreeHousing(boolean freeHousing) {
		this.freeHousing = freeHousing;
	}

	public boolean isFreeCarfare() {
		return freeCarfare;
	}

	public void setFreeCarfare(boolean freeCarfare) {
		this.freeCarfare = freeCarfare;
	}

	public List<TripBillItem> getBillItems() {
		return billItems;
	}

	public void setBillItems(List<TripBillItem> billItems) {
		this.billItems = billItems;
	}

	public BigDecimal getDownPayment() {
		return downPayment;
	}

	public void setDownPayment(BigDecimal downPayment) {
		this.downPayment = downPayment;
	}

	public BigDecimal getTotal() {
		return total;
	}

	public void setTotal(BigDecimal total) {
		this.total = total;
	}

	public List<FileMetainfo> getAttachedFiles() {
		return attachedFiles;
	}

	@Override
	public void addAttachment(FileMetainfo metaInfo) {
		attachedFiles.add(metaInfo);
	}

	@Override
	public void removeAttachment(FileMetainfo metainfo) {
		attachedFiles.remove(metainfo);
	}

	public void setAttachedFiles(List<FileMetainfo> attachedFiles) {
		this.attachedFiles = attachedFiles;
	}

	public TripBillApproval getApproval() {
		return approval;
	}

	public void setApproval(TripBillApproval approval) {
		this.approval = approval;
	}

	public Boolean getSaved() {
		return saved;
	}

	public void setSaved(Boolean saved) {
		this.saved = saved;
	}

	public Boolean getPaid() {
		return paid;
	}

	public void setPaid(Boolean paid) {
		this.paid = paid;
	}

	public Date getPaidDate() {
		return paidDate;
	}

	public void setPaidDate(Date paidDate) {
		this.paidDate = paidDate;
	}

	@Override
	public Season getSeason() {
		return season;
	}

	public void setSeason(Season season) {
		this.season = season;
	}
}
