package org.lym.pom.repository.mongo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.lym.pom.repository.mongo.enums.CommentStatusEnum;
import org.shoulder.core.dto.response.PageResult;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.io.Serializable;
import java.util.List;

/**
 * 用户的评论 / 评论的回复
 * todo 用户评论级别：发表 评论总数、用户获赞数、用户被踩数、评论标签分布、风控敏感数；用于计算优先级以及风控
 *
 * @author lym
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = Comment.COLLECTION_NAME)
public class Comment implements Serializable {

    public static final String EMPTY_PARENT_ID = "0";

    public static final String COLLECTION_NAME = "comment";
    /**
     * id
     */
    @Id
    private String id;

    @Field
    private CommentStatusEnum xxx;

    /**
     * 所属对象 id，可以是文章的
     * 评论的评论，该值仍然为被评论对象id
     */
    @Indexed
    private String relatedId;
    /**
     * 所属对象类型，如文章、动态、视频等，冗余信息用于扩展与提高读性能，其实可以通过 relatedId 反解析
     * @see RelatedType
     */
    @Field
    private String relatedType;
    /**
     * 所属对象的创建人id，冗余信息用于提高读性能
     * 评论通知触发后，给对应人发被评论消息通知使用，减少查库
     */
    @Field
    private String relatedUserId;
    // ------------------

    /**
     * 父节点id，默认无；评论最多2级。
     * 评论A的评论B：commentA.id
     * 评论A的评论B的评论C：commentA.id，但 parentId = commentB.id && mentionedUserId 一定包含 commentB.userId
     */
    @Indexed
    private String rootCommentId;

    /**
     * 根节点的创建人id，冗余信息用于提高读性能
     * 评论通知触发后，给对应人发被评论消息通知使用，减少查库
     */
    @Field
    private String rootCommentUserId;

    /**
     * 直接父级评论id / 引用的评论 id
     * referUserId 在 mentionedUserIdList 中
     */
    @Field
    private String parentId;

    /**
     * 类型：content 类型
     * @see Type
     */
    @Field
    private String type;

    /**
     * 评论人
     */
    @Field
    private String creator;
    /**
     * 内容
     */
    @Field
    private String content;
    /**
     * 被@到的UserId
     */
    @Field
    private List<String> mentionedUserIdList;
    /**
     * 发布时的位置-经度
     */
    @Field
    private String longitude;
    /**
     * 发布时的位置-维度
     */
    @Field
    private String latitude;
    /**
     * 定位标签
     */
    @Field
    private String locationName;

    // ==========================热数据==========================
    /**
     * 冗余：赞数量
     */
    @Field
    private int likeNumber;

    /**
     * 冗余：踩数量
     */
    @Field
    private int dislikeNumber;

    /**
     * 冗余：阅读量
     */
    @Field
    private int readNumber;
    // ==========================热数据==========================
    /**
     * 状态
     * @see Status
     */
    @Field
    private String status;

    /**
     * relatedUser 发布者点赞了
     */
//    private boolean relatedUserLike;

    /**
     * 发布者回复了
     */
//    private boolean relatedUserReply;

    /**
     * 推荐评分（推荐系统打分，便于推荐优秀的评论）
     */
    @Indexed
    private Double score;

    /**
     * 创建时间
     */
    @Field
    private Long createTime;

    /**
     * 创建时间
     */
    @Field
    private Long updateTime;

    /**
     * 子评论
     */
    //@Field
    private transient PageResult<Comment> subComments;


    /**
     * 互动对象类型
     * 用户状态/分享
     * 视频
     * 照片
     */
    public interface RelatedType {
        String MOMENT = "M";
        String VIDEO = "V";
        String PHOTO = "P";
    }

    /**
     * 评论区展示类型：点赞倒排序、评论时间排序（强调时效性）、精选（上半区点赞倒排、下半区时间倒叙）- 查询参数控制
     * 评论查看类型：分页、下拉、点击加载更多                                               - UI、前端控制
     * 评论规则：单向（评论只读，不可回复）/ 双向一次（作者可回复一次）/讨论（任何人可互相评论）    - relatedType + 前端 + 权限控制
     * 可评规则：不可评论 / 好友可评论 / 白名单 / 黑名单                                    - relatedType + 前端 + 权限控制
     * 评论格式：短文本、markdown、带图片、带视频、带站内链接、带文件                          - 【commentType】这里！！
     * 修改权限：xxx天内修改x次                                                          - relatedType + 前端 + 权限控制
     * 引用格式：是否展示引用回复的内容、@用户可点跳转主页、@用户颜色不同、@用户是否提醒           - UI、前端控制
     * 内置表情                                                                        - UI、前端控制
     * 敏感词                                                                          - 风控
     * 管理：审核、精选、置顶、编辑、隐藏、删除                                              - 后台管理
     */
    public interface Type {
        String TEXT = "T";
        String MARKDOWN = "M";
        String WITH_IMAGE = "I";
        String FILE_ATTACH = "F";
        String SHARE_LINK = "L";
    }

    /**
     * 状态
     * 正常可见
     * 待作者精选，仅作者和发表人可见
     * 待审核，不可见
     * 管理移除，不可见
     * 用户删除，不可见
     */
    public interface Status {
        String NORMAL = "N";
        String REVIEW = "R";
        String AUDIT = "A";
        String DELETED = "D";
        String FORCE_REMOVE = "FR";
    }

}
