package me.qwq.doghouse.entity;

import com.baomidou.mybatisplus.annotation.IdType;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.util.CollectionUtils;
import org.springframework.web.util.UriUtils;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.annotation.TableField;

import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;

import com.fasterxml.jackson.annotation.JsonFormat;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import me.qwq.doghouse.enums.PostStatusEnum;
import me.qwq.doghouse.enums.PostTypeEnum;
import me.qwq.doghouse.interfaces.IAvatarUrl;
import me.qwq.doghouse.interfaces.IFriendlyName;
import me.qwq.doghouse.interfaces.IPostPassMess;
import me.qwq.doghouse.validator.FriendlyNameValid;

/**
 * <p>
 * 文章/页面/Wiki
 * </p>
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@FriendlyNameValid
public class Post extends Model<Post> implements Serializable, IPostPassMess<Post>, ITreeView<Post>, IAvatarUrl, IFriendlyName {

    private static final long serialVersionUID = 1L;

    public static final String URI_ID_TAG = "p";
    public static final String URI_PAGENAME_TAG = "n";
    
    public static final String URL_ID_FORMAT = "/" + URI_ID_TAG + "/%s";
    public static final String URL_PAGENAME_FORMAT = "/" + URI_PAGENAME_TAG + "/%s";
    public static final String URL_INDIVIDUAL_PAGE_FORMAT = "/%s.html";

    /**
     *表主键id
     */
    @TableId(value = "post_id", type = IdType.AUTO)
    private Long postId;
    
    /**
     * 类型，0 - 文章，1 - 独立页面
     */
    @TableField("type")
    private PostTypeEnum type;
    
    /**
     * 模板
     */
    @TableField("template")
    private String template;

    /**
     * 标题
     */
    @TableField("post_title")
    private String postTitle;

    /**
     * 自定义路径url
     */
    @TableField("post_page_name")
    private String postPageName;

    /**
     * 前言
     */
    @TableField("post_preface")
    private String postPreface;

    /**
     * 内容
     */
    @TableField("post_content")
    private String postContent;
    
    /**
     * 关键词
     */
    @TableField("keywords")
    private String keywords;
    
    /**
     * 描述
     */
    @TableField("description")
    private String description;

    /**
     * 分类id(冗余字段)
     */
    @TableField(value = "categories_id", exist = false)
    private String categoriesId;

    /**
     * 分类(冗余字段)
     */
    @TableField(value = "categories_name", exist = false)
    private String categoriesName;
    
    /**
     * 分类友好名称(冗余字段)
     */
    @TableField(value = "categories_friendly_name", exist = false)
    private String categoriesFriendlyName;
    
    /**
     * 前端遍历用
     * @return
     */
    public List<String> getCategoriesFriendlyNamesEncoded() {
        if (categoriesFriendlyName == null) {
            return new ArrayList<>();
        }
        return Arrays.asList(
                categoriesFriendlyName.split(","))
                .stream().map(i -> UriUtils.encode(i, StandardCharsets.UTF_8))
                .collect(Collectors.toList());
    }

    /**
     * 标签id
     */
    @TableField(value = "tags_id", exist = false)
    private String tagsId;
    

    /**
     * 标签名(冗余字段)
     */
    @TableField(value = "tags_name", exist = false)
    private String tagsName;
    
    /**
     * 标签友好名称(冗余字段)
     */
    @TableField(value = "tags_friendly_name", exist = false)
    private String tagsFriendlyName;
    
    /**
     * 前端遍历用
     * @return
     */
    public List<String> getTagsFriendlyNamesEncoded() {
        if (tagsFriendlyName == null) {
            return new ArrayList<>();
        }
        return Arrays.asList(
                tagsFriendlyName.split(","))
                .stream().map(i -> UriUtils.encode(i, StandardCharsets.UTF_8))
                .collect(Collectors.toList());
    }
    
    /**
     * 创建者的用户 ID
     */
    @TableField(value = "created_by")
    private Integer createdBy;
    
    /**
     * 创建者昵称
     */
    @TableField(value = "creator_nickname", exist = false)
    private String creatorNickname;

    /**
     * 创建者邮箱地址
     */
    @TableField(value = "email", exist = false)
    private String email;
    
    @TableField("password")
    private String password;

    
    @TableField("post_status")
    private PostStatusEnum postStatus;

    /**
     * 阅读量
     */
    @TableField("post_views")
    private Long postViews;
    
    /**
     * 评论量
     */
    @TableField(value = "comment_count", exist=false)
    private Long commentCount = 0L;

    /**
     * 0-允许评论 1-不允许评论
     */
    @TableField("enable_comment")
    private Boolean enableComment;

    /**
     * 是否删除 0=否 1=是
     */
    @TableField("is_deleted")
    private Boolean isDeleted;

    /**
     * 添加时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField("create_time")
    private LocalDateTime createTime;

    /**
     * 修改时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField("update_time")
    private LocalDateTime updateTime;
    
    /**
     * 获取相对链接
     */
    public String getLink() {
        return getLink(type, postId, postPageName);
    }
    
    public static String getLink(PostTypeEnum type, Long postId, String postPageName) {
        if (StringUtils.isBlank(postPageName)) {
            return String.format(URL_ID_FORMAT, postId);
        }
        else {
            postPageName = UriUtils.encode(postPageName, StandardCharsets.UTF_8);
            if (type == PostTypeEnum.PAGE) {
                return String.format(URL_INDIVIDUAL_PAGE_FORMAT, postPageName);
            }
            else {
                return String.format(URL_PAGENAME_FORMAT, postPageName);
            }
        }
    }
    
    /**
     * FOR WIKI
     */
    @TableField(value="parent_id")
    private Long parentId = -1L;
    
    @TableField(value="no")
    private Integer no;
    
    @TableField(value="level")
    private Integer level;
    
    @TableField(value="searchable")
    private Boolean searchable;

    /* 
     * FOR TREEVIEW USE.
     */
    
    @TableField(exist=false)
    private List<Post> children;
    
    public String getTitle() {
        return getPostTitle();
    }
    
    public Long getId() {
        return getPostId();
    }
    
    public Boolean getHasChildren() {
        return childrenCount > 0 || !CollectionUtils.isEmpty(children);
    }

    @TableField(exist=false)
    private Boolean checked = false;
    
    @TableField(exist=false)
    private Boolean spread = false;
    
    @TableField(value = "post_count", exist = false)
    private Long postCount = 0L;

    @TableField(value = "children_count", exist = false)
    private Long childrenCount = 0L;
    
    public String getFriendlyName() {
        return getPostPageName();
    }

}
