package info.bukova.isspst.data;

import info.bukova.isspst.Constants;
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.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "ORDERS")
@Indexed
public class Order extends BaseData implements Cloneable, SeasonsAware
{

	@Column(name = "NUMSER")
	private String numser;

	@Column(name = "ORDER_DATE")
	private Date orderDate;

	@Embedded
	@AttributeOverrides({
			@AttributeOverride(name = "id", column = @Column(name = "SUPPLIER_ID")),
			@AttributeOverride(name = "city", column = @Column(name = "SUPPLIER_CITY")),
			@AttributeOverride(name = "company", column = @Column(name = "SUPPLIER_COMPANY")),
			@AttributeOverride(name = "contactName", column = @Column(name = "SUPPLIER_CONTACT_NAME")),
			@AttributeOverride(name = "department", column = @Column(name = "SUPPLIER_DEPARTMENT")),
			@AttributeOverride(name = "description", column = @Column(name = "SUPPLIER_DESCRIPTION", length = Constants.LEN_DESCRIPTION)),
			@AttributeOverride(name = "dic", column = @Column(name = "SUPPLIER_DIC")),
			@AttributeOverride(name = "email", column = @Column(name = "SUPPLIER_EMAIL")),
			@AttributeOverride(name = "houseNumber", column = @Column(name = "SUPPLIER_HOUSENUMBER")),
			@AttributeOverride(name = "ic", column = @Column(name = "SUPPLIER_IC")),
			@AttributeOverride(name = "phone", column = @Column(name = "SUPPLIER_PHONE")),
			@AttributeOverride(name = "state", column = @Column(name = "SUPPLIER_STATE")),
			@AttributeOverride(name = "street", column = @Column(name = "SUPPLIER_STREET")),
			@AttributeOverride(name = "web", column = @Column(name = "SUPPLIER_WEB")),
			@AttributeOverride(name = "zipCode", column = @Column(name = "SUPPLIER_ZIP_CODE")) })
	@IndexedEmbedded
	private AddressEmb suplier;

	@Embedded
	@AttributeOverrides({
			@AttributeOverride(name = "id", column = @Column(name = "INVOICE_ID")),
			@AttributeOverride(name = "city", column = @Column(name = "INVOICE_CITY")),
			@AttributeOverride(name = "company", column = @Column(name = "INVOICE_COMPANY")),
			@AttributeOverride(name = "contactName", column = @Column(name = "INVOICE_CONTACT_NAME")),
			@AttributeOverride(name = "department", column = @Column(name = "INVOICE_DEPARTMENT")),
			@AttributeOverride(name = "description", column = @Column(name = "INVOICE_DESCRIPTION", length = Constants.LEN_DESCRIPTION)),
			@AttributeOverride(name = "dic", column = @Column(name = "INVOICE_DIC")),
			@AttributeOverride(name = "email", column = @Column(name = "INVOICE_EMAIL")),
			@AttributeOverride(name = "houseNumber", column = @Column(name = "INVOICE_HOUSENUMBER")),
			@AttributeOverride(name = "ic", column = @Column(name = "INVOICE_IC")),
			@AttributeOverride(name = "phone", column = @Column(name = "INVOICE_PHONE")),
			@AttributeOverride(name = "state", column = @Column(name = "INVOICE_STATE")),
			@AttributeOverride(name = "street", column = @Column(name = "INVOICE_STREET")),
			@AttributeOverride(name = "web", column = @Column(name = "INVOICE_WEB")),
			@AttributeOverride(name = "zipCode", column = @Column(name = "INVOICE_ZIP_CODE")) })
	private AddressEmb address;

	@Embedded
	@AttributeOverrides({
			@AttributeOverride(name = "id", column = @Column(name = "DELIVERY_ID")),
			@AttributeOverride(name = "city", column = @Column(name = "DELIVERY_CITY")),
			@AttributeOverride(name = "company", column = @Column(name = "DELIVERY_COMPANY")),
			@AttributeOverride(name = "contactName", column = @Column(name = "DELIVERY_CONTACT_NAME")),
			@AttributeOverride(name = "department", column = @Column(name = "DELIVERY_DEPARTMENT")),
			@AttributeOverride(name = "description", column = @Column(name = "DELIVERY_DESCRIPTION", length = Constants.LEN_DESCRIPTION)),
			@AttributeOverride(name = "dic", column = @Column(name = "DELIVERY_DIC")),
			@AttributeOverride(name = "email", column = @Column(name = "DELIVERY_EMAIL")),
			@AttributeOverride(name = "houseNumber", column = @Column(name = "DELIVERY_HOUSENUMBER")),
			@AttributeOverride(name = "ic", column = @Column(name = "DELIVERY_IC")),
			@AttributeOverride(name = "phone", column = @Column(name = "DELIVERY_PHONE")),
			@AttributeOverride(name = "state", column = @Column(name = "DELIVERY_STATE")),
			@AttributeOverride(name = "street", column = @Column(name = "DELIVERY_STREET")),
			@AttributeOverride(name = "web", column = @Column(name = "DELIVERY_WEB")),
			@AttributeOverride(name = "zipCode", column = @Column(name = "DELIVERY_ZIP_CODE")) })
	private AddressEmb deliveryAddress;

	@Column(name = "DELIVERY_DATE")
	private Date deliveryDate;

	@Column(name = "DELIVERED_DATE")
	private Date deliveredDate;

	@Column(name = "DELIVERY_TYPE")
	private String deliveryType;

	@Column(name = "DESCRIPTION", length = Constants.LEN_DESCRIPTION)
	@Field(index = Index.YES, analyze = Analyze.YES)
	private String description;

	@OneToMany(cascade = CascadeType.ALL, mappedBy = "order", orphanRemoval = true)
	@LazyCollection(LazyCollectionOption.TRUE)
	@IndexedEmbedded
	private List<OrderItem> items;

	@Column(name = "TOTAL", precision = 15, scale = 4)
	private BigDecimal total;

	@Column(name = "ORDERED")
	private boolean ordered;

	@Column(name = "DELIVERED")
	private boolean delivered;

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "SEASON_ID")
	private Season season;

	public Order()
	{
		this.items = new ArrayList<OrderItem>();
		this.total = BigDecimal.ZERO;
	}

	public String getNumser()
	{
		return numser;
	}

	public void setNumser(String numser)
	{
		this.numser = numser;
	}

	public AddressEmb getSuplier()
	{
		return suplier;
	}

	public void setSuplier(AddressEmb suplier)
	{
		this.suplier = suplier;
	}

	public AddressEmb getAddress()
	{
		return address;
	}

	public void setAddress(AddressEmb address)
	{
		this.address = address;
	}

	public Date getDeliveryDate()
	{
		return deliveryDate;
	}

	public void setDeliveryDate(Date deliveryDate)
	{
		this.deliveryDate = deliveryDate;
	}

	public String getDeliveryType()
	{
		return deliveryType;
	}

	public void setDeliveryType(String deliveryType)
	{
		this.deliveryType = deliveryType;
	}

	public String getDescription()
	{
		return description;
	}

	public void setDescription(String description)
	{
		this.description = description;
	}

	public AddressEmb getDeliveryAddress()
	{
		return deliveryAddress;
	}

	public void setDeliveryAddress(AddressEmb deliveryAddress)
	{
		this.deliveryAddress = deliveryAddress;
	}

	public Date getDeliveredDate()
	{
		return deliveredDate;
	}

	public void setDeliveredDate(Date deliveredDate)
	{
		this.deliveredDate = deliveredDate;
	}

	public List<OrderItem> getItems()
	{
		return items;
	}

	public void addItem(OrderItem item)
	{
		item.setOrder(this);
		items.add(item);
	}

	public void setItems(List<OrderItem> items)
	{
		this.items = items;
	}

	public boolean isDelivered()
	{
		return delivered;
	}

	public void setDelivered(boolean delivered)
	{
		this.delivered = delivered;
	}

	public boolean isOrdered()
	{
		return ordered;
	}

	public void setOrdered(boolean ordered)
	{
		this.ordered = ordered;
	}

	public Date getOrderDate()
	{
		return orderDate;
	}

	public void setOrderDate(Date orderDate)
	{
		this.orderDate = orderDate;
	}

	public BigDecimal getTotal()
	{
		return total;
	}

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

	public boolean isIcludedRequirementItemFromAnotherOrder()
	{
		for (OrderItem oItem : this.getItems())
		{
			RequirementItem rItem = oItem.getReqItem();

			if (rItem != null)
			{
				String orderNum = rItem.getOrderNum();
				boolean isIncluded = ((orderNum != null) && !orderNum.isEmpty());
				boolean isFromAnotherOrder = (isIncluded && !this.numser.equals(orderNum));
				return isFromAnotherOrder;
			}
		}

		return false;
	}

	@Override
	public Object clone() throws CloneNotSupportedException
	{
		Order cloned = (Order) super.clone();
		cloned.setTotal(new BigDecimal(this.getTotal().toString()));
		return cloned;
	}

	public Season getSeason() {
		return season;
	}

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