package com.apobates.forum.core.entity;

import com.apobates.forum.utils.DateTimeUtils;
import java.io.Serializable;
import java.time.LocalDateTime;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;

/**
 * 话题
 *
 * @author xiaofanku
 * @since 20200510
 */
@Entity
@Table(name = "apo_topic", uniqueConstraints = {@UniqueConstraint(columnNames = {"boardId","title"})})
public class Topic implements Serializable, Comparable<Topic> {
    private static final long serialVersionUID = -6074411597983125551L;
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;
    //主题
    private String title;
    //发布日期
    private LocalDateTime entryDateTime;
    //作者:会员的ID
    private long memberId;
    private String memberNickname;
    private String ipAddr;
    //卷的ID
    private int volumesId;
    //版块的ID
    private long boardId;
    //置顶(时效),true(1)置顶,false(0)不置顶
    @Column(columnDefinition="tinyint(1) default 0")
    private boolean tops;
    //加精,true(1)精华,false(0)非精华
    @Column(columnDefinition="tinyint(1) default 0")
    private boolean goods;
    //火贴,true(1)火,false(0)没火
    @Column(columnDefinition="tinyint(1) default 0")
    private boolean hots;
    //是否有像册@20190412
    private long albumId;
    //状态
    @Basic
    @Enumerated(EnumType.STRING)
    private ForumEntityStatusEnum status;
    //显示顺序:普通话题是1,置顶的依次++
    private int ranking;
    //排序的日期
    //没有回复时为entryDateTime
    //有回复时为最近的回复日期
    private LocalDateTime rankingDateTime;
    //话题类型的参数名,年代
    private String topicCategoryName;
    //话题类型的参数值,year
    private String topicCategoryValue;
    //简述|举报和投拆不要设置此值
    private String summary;
    //是否推荐|不想被索引可以设置此值false
    //举报和投拆此值等于false|原生版块的话题此值等于false
    @Column(columnDefinition="tinyint(1) default 0")
    private boolean suggest = true;
    //是否是文章|原生版块的话题此值等于true
    @Column(columnDefinition="tinyint(1) default 0")
    private boolean article;
    //是否匿名,true是,false不是
    @Column(columnDefinition="tinyint(1) default 0")
    private boolean anony;
    
    //empty constructor for JPA instantiation
    public Topic() {
        super();
    }
    //普通话题
    public Topic(
            String title,
            long memberId,
            String memberNickname,
            int volumesId,
            long boardId,
            String ipAddr) {
        this.id = 0L;
        this.title = title;
        this.entryDateTime = LocalDateTime.now();
        this.memberId = memberId;
        this.memberNickname = memberNickname;
        this.ipAddr = ipAddr;
        this.volumesId = volumesId;
        this.boardId = boardId;
        this.tops = false;
        this.goods = false;
        this.hots = false;
        this.status = ForumEntityStatusEnum.ACTIVE;
        this.ranking = 1;
        //
        this.rankingDateTime = LocalDateTime.now();
        TopicCategory tc = TopicCategory.empty(); //普通
        this.topicCategoryName = tc.getNames();
        this.topicCategoryValue = tc.getValue();
        //
        this.suggest = true;
        this.article = false;
        this.anony = false;
    }
    //含有分类的话题
    public Topic(
            String title,
            long memberId,
            String memberNickname,
            int volumesId,
            long boardId,
            String ipAddr,
            String topicCategoryName,
            String topicCategoryValue) {
        this.id = 0L;
        this.title = title;
        this.entryDateTime = LocalDateTime.now();
        this.memberId = memberId;
        this.memberNickname = memberNickname;
        this.ipAddr = ipAddr;
        this.volumesId = volumesId;
        this.boardId = boardId;
        this.tops = false;
        this.goods = false;
        this.hots = false;
        this.status = ForumEntityStatusEnum.ACTIVE;
        this.ranking = 1;
        //
        this.rankingDateTime = LocalDateTime.now();
        this.topicCategoryName = topicCategoryName;
        this.topicCategoryValue = topicCategoryValue;
        //
        this.suggest = true;
        this.article = false;
        this.anony = false;
    }
    
    public long getId() {
        return id;
    }
    
    public String getTitle() {
        return title;
    }
    
    public LocalDateTime getEntryDateTime() {
        return entryDateTime;
    }
    
    public long getMemberId() {
        return (memberId <= 0)?0L:memberId;
    }
    
    public String getMemberNickname() {
        return memberNickname;
    }
    
    public String getIpAddr() {
        return ipAddr;
    }
    
    public int getVolumesId() {
        return volumesId;
    }
    
    public long getBoardId() {
        return boardId;
    }
    
    public boolean isTops() {
        return tops;
    }
    
    public boolean isGoods() {
        return goods;
    }
    
    public boolean isHots() {
        return hots;
    }
    
    public long getAlbumId() {
        return albumId;
    }
    
    public ForumEntityStatusEnum getStatus() {
        return status;
    }
    
    public int getRanking() {
        return ranking;
    }
    
    public String getTopicCategoryName() {
        return topicCategoryName;
    }
    
    public String getTopicCategoryValue() {
        return topicCategoryValue;
    }
    
    public String getSummary() {
        return summary;
    }
    
    public boolean isSuggest() {
        return suggest;
    }
    
    public boolean isArticle() {
        return article;
    }
    
    public LocalDateTime getRankingDateTime() {
        return rankingDateTime;
    }
    
    public void setId(long id) {
        this.id = id;
    }
    
    public void setTitle(String title) {
        this.title = title;
    }
    
    public void setEntryDateTime(LocalDateTime entryDateTime) {
        this.entryDateTime = entryDateTime;
    }
    
    public void setMemberId(long memberId) {
        this.memberId = memberId;
    }
    
    public void setMemberNickname(String memberNickname) {
        this.memberNickname = memberNickname;
    }
    
    public void setIpAddr(String ipAddr) {
        this.ipAddr = ipAddr;
    }
    
    public void setVolumesId(int volumesId) {
        this.volumesId = volumesId;
    }
    
    public void setBoardId(long boardId) {
        this.boardId = boardId;
    }
    
    public void setTops(boolean tops) {
        this.tops = tops;
    }
    
    public void setGoods(boolean goods) {
        this.goods = goods;
    }
    
    public void setHots(boolean hots) {
        this.hots = hots;
    }
    
    public void setAlbumId(long albumId) {
        this.albumId = albumId;
    }
    
    public void setStatus(ForumEntityStatusEnum status) {
        this.status = status;
    }
    
    public void setRanking(int ranking) {
        this.ranking = ranking;
    }
    
    public void setRankingDateTime(LocalDateTime rankingDateTime) {
        this.rankingDateTime = rankingDateTime;
    }
    
    public void setTopicCategoryName(String topicCategoryName) {
        this.topicCategoryName = topicCategoryName;
    }
    
    public void setTopicCategoryValue(String topicCategoryValue) {
        this.topicCategoryValue = topicCategoryValue;
    }
    
    public void setSummary(String summary) {
        this.summary = summary;
    }
    
    public void setSuggest(boolean suggest) {
        this.suggest = suggest;
    }
    
    public void setArticle(boolean article) {
        this.article = article;
    }
    
    public boolean isAnony() {
        return anony;
    }
    
    public void setAnony(boolean anony) {
        this.anony = anony;
    }
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + (int) (boardId ^ (boardId >>> 32));
        result = prime * result + ((title == null) ? 0 : title.hashCode());
        return result;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Topic other = (Topic) obj;
        if (boardId != other.boardId) {
            return false;
        }
        if (title == null) {
            if (other.title != null) {
                return false;
            }
        } else if (!title.equals(other.title)) {
            return false;
        }
        return true;
    }
    
    @Override
    public int compareTo(Topic o) {
        return rankingDateTime.compareTo(o.getRankingDateTime());
    }
    
    @Transient
    public static Topic buildArticle(String title, long author, String authorNickname, int sectionId, long termId, String ipAdd) {
        Topic article = new Topic(title, author, authorNickname, sectionId, termId, ipAdd);
        article.setStatus(ForumEntityStatusEnum.ACTIVE);
        article.setSuggest(false);
        article.setArticle(true);
        return article;
    }
    
    @Transient
    public boolean isImage() {
        return this.getAlbumId() > 0;
    }
    
    @Transient
    public boolean isNormal() {
        return ForumEntityStatusEnum.ACTIVE == status;
    }
    
    @Transient
    public boolean isOneDay(){
        return DateTimeUtils.isSameDay(getEntryDateTime());
    }
    
    @Transient
    public String getIcoStatus() {
        if (ForumEntityStatusEnum.LOCKED == getStatus()) {
            return "locked"; //锁定
        }
        if (ForumEntityStatusEnum.DELETE == getStatus()) {
            return "read"; //删除
        }
        return "normal"; //正常
    }
    
    @Transient
    public static Topic empty(int volumesId, long boardId) {
        Topic topic = new Topic();
        topic.setBoardId(boardId);
        topic.setVolumesId(volumesId);
        return topic;
    }
    
    @Transient
    public static Topic empty(long topicId) {
        Topic topic = new Topic();
        topic.setId(topicId);
        return topic;
    }
}