package com.infinite.focus.server.resourcelibrary;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;

import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.infinite.focus.server.categories.Category;
import com.infinite.focus.server.contents.Content;
import com.infinite.focus.server.moods.Mood;
import com.infinite.focus.server.standard.Standard;

@Entity
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
public class Post {

	// PK
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private long post_id;

	private String post_title;

	@Column(length = 65555)
	private String post_description;

	private String post_cover_image_url;

	private Long post_duration;

	private String post_video_url;

	@ManyToMany(targetEntity = Category.class, fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
	@JoinTable(name = "post_category", joinColumns = { @JoinColumn(nullable = false, name = "post_id")}, inverseJoinColumns = { @JoinColumn(nullable = false, name = "category_id")})
	private Set<Category> categories = new HashSet<>();

	@ManyToMany(targetEntity = Content.class, fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
	@JoinTable(name = "post_content", joinColumns = { @JoinColumn(nullable = false, name = "post_id")}, inverseJoinColumns = { @JoinColumn(nullable = false, name = "content_id")})
	private Set<Content> contents = new HashSet<>();
	
	@ManyToMany(targetEntity = Mood.class, fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
	@JoinTable(name = "post_mood", joinColumns = { @JoinColumn(nullable = false, name = "post_id")}, inverseJoinColumns = { @JoinColumn(nullable = false, name = "mood_id")})
	private Set<Mood> moods = new HashSet<>();

	@Enumerated(EnumType.STRING)
	@Column(name = "post_type", columnDefinition = "enum('VIDEO','ARTICLE')")
	private PostType post_type;

	@Column(name = "created_at", nullable = false)
	@CreationTimestamp
	public Date createdAt;

	@Column(name = "updated_at")
	@UpdateTimestamp
	public Date updatedAt;

	public Post() {
		super();
	}

	public long getPost_id() {
		return post_id;
	}

	public void setPost_id(long post_id) {
		this.post_id = post_id;
	}

	public String getPost_title() {
		return post_title;
	}

	public void setPost_title(String post_title) {
		this.post_title = post_title;
	}

	public String getPost_description() {
		return post_description;
	}

	public void setPost_description(String post_description) {
		this.post_description = post_description;
	}

	public String getPost_cover_image_url() {
		return post_cover_image_url;
	}

	public void setPost_cover_image_url(String post_cover_image_url) {
		this.post_cover_image_url = post_cover_image_url;
	}

	public Long getPost_duration() {
		return post_duration;
	}

	public void setPost_duration(Long post_duration) {
		this.post_duration = post_duration;
	}

	public String getPost_video_url() {
		return post_video_url;
	}

	public void setPost_video_url(String post_video_url) {
		this.post_video_url = post_video_url;
	}

	public PostType getPost_type() {
		return post_type;
	}

	public void setPost_type(PostType post_type) {
		this.post_type = post_type;
	}
	
	public Set<Category> getCategories() {
		return categories;
	}

	public void setCategories(Set<Category> categories) {
		this.categories = categories;
	}

	public Set<Content> getContents() {
		return contents;
	}

	public void setContents(Set<Content> contents) {
		this.contents = contents;
	}

	public Set<Mood> getMoods() {
		return moods;
	}

	public void setMoods(Set<Mood> moods) {
		this.moods = moods;
	}

	public Date getCreatedAt() {
		return createdAt;
	}

	public void setCreatedAt(Date createdAt) {
		this.createdAt = createdAt;
	}

	public Date getUpdatedAt() {
		return updatedAt;
	}

	public void setUpdateAt(Date updatedAt) {
		this.updatedAt = updatedAt;
	}
}
