package com.slodon.b2b2c.model.video;

import com.slodon.b2b2c.core.constant.VideoConst;
import com.slodon.b2b2c.core.exception.MallException;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.dao.read.video.SvideoCommentLikeReadMapper;
import com.slodon.b2b2c.dao.read.video.SvideoCommentReadMapper;
import com.slodon.b2b2c.dao.read.video.SvideoVideoReadMapper;
import com.slodon.b2b2c.dao.write.video.SvideoCommentLikeWriteMapper;
import com.slodon.b2b2c.dao.write.video.SvideoCommentWriteMapper;
import com.slodon.b2b2c.dao.write.video.SvideoReplyWriteMapper;
import com.slodon.b2b2c.dao.write.video.SvideoVideoWriteMapper;
import com.slodon.b2b2c.video.example.SvideoCommentExample;
import com.slodon.b2b2c.video.example.SvideoCommentLikeExample;
import com.slodon.b2b2c.video.example.SvideoReplyExample;
import com.slodon.b2b2c.video.pojo.Author;
import com.slodon.b2b2c.video.pojo.SvideoComment;
import com.slodon.b2b2c.video.pojo.SvideoCommentLike;
import com.slodon.b2b2c.video.pojo.SvideoVideo;
import com.slodon.b2b2c.vo.video.VideoMessageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 短视频评论表model
 */
@Component
@Slf4j
public class SvideoCommentModel {

    @Resource
    private SvideoCommentReadMapper svideoCommentReadMapper;
    @Resource
    private SvideoCommentWriteMapper svideoCommentWriteMapper;
    @Resource
    private SvideoVideoReadMapper svideoVideoReadMapper;
    @Resource
    private SvideoVideoWriteMapper svideoVideoWriteMapper;
    @Resource
    private SvideoCommentLikeReadMapper svideoCommentLikeReadMapper;
    @Resource
    private SvideoCommentLikeWriteMapper svideoCommentLikeWriteMapper;
    @Resource
    private SvideoReplyWriteMapper svideoReplyWriteMapper;

    /**
     * 新增短视频评论表
     *
     * @param svideoComment
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SvideoComment saveSvideoComment(SvideoComment svideoComment) {
        SvideoVideo svideoVideo = svideoVideoReadMapper.getByPrimaryKey(svideoComment.getVideoId());
        AssertUtil.notNull(svideoVideo, "视频不存在");
        AssertUtil.isTrue(svideoVideo.getState() == VideoConst.STATE_1 || svideoVideo.getState() == VideoConst.STATE_3, "该作品还未审核通过，不允许该操作");
        AssertUtil.isTrue(svideoVideo.getState() == VideoConst.STATE_4, "该作品已被下架，不允许该操作");

        svideoComment.setVideoImage(StringUtil.isEmpty(svideoVideo.getVideoThemeImage())
                ? svideoVideo.getVideoImage() : svideoVideo.getVideoThemeImage());
        svideoComment.setToAuthorId(svideoVideo.getAuthorId());
        svideoComment.setToAuthorName(StringUtil.isEmpty(svideoVideo.getMemberNickname()) ? svideoVideo.getMemberName() : svideoVideo.getMemberNickname());
        svideoComment.setLikeNum(0);
        svideoComment.setIsRead(0);
        int count = svideoCommentWriteMapper.insert(svideoComment);
        AssertUtil.isTrue(count == 0, "添加评论失败，请重试");

        //更新视频评论数
        SvideoVideo video = new SvideoVideo();
        video.setVideoId(svideoVideo.getVideoId());
        video.setCommentNum(svideoVideo.getCommentNum() + 1);
        video.setUpdateTime(new Date());
        count = svideoVideoWriteMapper.updateByPrimaryKeySelective(video);
        AssertUtil.isTrue(count == 0, "更新视频评论数失败，请重试");
        return svideoComment;
    }

    /**
     * 根据commentId删除短视频评论表
     *
     * @param commentId commentId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteSvideoComment(Integer commentId) {
        if (StringUtils.isEmpty(commentId)) {
            throw new MallException("请选择要删除的数据");
        }
        //查询评论信息
        SvideoComment svideoComment = this.getSvideoCommentByCommentId(commentId);
        AssertUtil.notNull(svideoComment, "评论不存在");
        //修改视频评论数
        SvideoVideo svideoVideoDb = svideoVideoReadMapper.getByPrimaryKey(svideoComment.getVideoId());
        AssertUtil.notNull(svideoVideoDb, "评论的视频不存在");
        SvideoVideo video = new SvideoVideo();
        video.setVideoId(svideoVideoDb.getVideoId());
        video.setCommentNum(svideoVideoDb.getCommentNum() - 1);
        svideoVideoWriteMapper.updateByPrimaryKeySelective(video);

        int count = svideoCommentWriteMapper.deleteByPrimaryKey(commentId);
        if (count == 0) {
            log.error("根据commentId：" + commentId + "删除评论表失败");
            throw new MallException("删除评论表失败,请重试");
        }
        //删除评论下的点赞
        SvideoCommentLikeExample example = new SvideoCommentLikeExample();
        example.setCommentId(commentId);
        svideoCommentLikeWriteMapper.deleteByExample(example);
        //删除评论下的回复
        SvideoReplyExample replyExample = new SvideoReplyExample();
        replyExample.setCommentId(commentId);
        svideoReplyWriteMapper.deleteByExample(replyExample);
        return count;
    }

    /**
     * 根据查询条件信息删除评论表
     *
     * @param example 查询条件信息
     * @return
     */
    public Integer deleteSvideoCommentByExample(SvideoCommentExample example) {
        return svideoCommentWriteMapper.deleteByExample(example);
    }

    /**
     * 根据commentId更新短视频评论表
     *
     * @param svideoComment
     * @return
     */
    public Integer updateSvideoComment(SvideoComment svideoComment) {
        if (StringUtils.isEmpty(svideoComment.getCommentId())) {
            throw new MallException("请选择要修改的数据");
        }
        int count = svideoCommentWriteMapper.updateByPrimaryKeySelective(svideoComment);
        if (count == 0) {
            log.error("根据commentId：" + svideoComment.getCommentId() + "更新短视频评论表失败");
            throw new MallException("更新短视频评论表失败,请重试");
        }
        return count;
    }

    /**
     * 根据条件更新短视频评论表
     *
     * @param svideoComment
     * @param example
     * @return
     */
    public Integer updateComment(SvideoComment svideoComment, SvideoCommentExample example) {
        return svideoCommentWriteMapper.updateByExampleSelective(svideoComment, example);
    }

    /**
     * 根据commentId获取短视频评论表详情
     *
     * @param commentId commentId
     * @return
     */
    public SvideoComment getSvideoCommentByCommentId(Integer commentId) {
        return svideoCommentReadMapper.getByPrimaryKey(commentId);
    }

    /**
     * 根据条件获取短视频评论表列表
     *
     * @param example 查询条件信息
     * @param pager   分页信息
     * @return
     */
    public List<SvideoComment> getSvideoCommentList(SvideoCommentExample example, PagerInfo pager) {
        List<SvideoComment> svideoCommentList;
        if (pager != null) {
            pager.setRowsCount(svideoCommentReadMapper.countByExample(example));
            svideoCommentList = svideoCommentReadMapper.listPageByExample(example, pager.getStart(), pager.getPageSize());
        } else {
            svideoCommentList = svideoCommentReadMapper.listByExample(example);
        }
        return svideoCommentList;
    }

    /**
     * 获取符合条件的数量
     *
     * @param example 查询条件
     * @return
     */
    public Integer getSvideoCommentCount(SvideoCommentExample example) {
        return svideoCommentReadMapper.countByExample(example);
    }

    /**
     * 查看评论或回复
     *
     * @param example
     * @param pager
     * @return
     */
    public List<VideoMessageVO> getMessageList(SvideoCommentExample example, PagerInfo pager) {
        pager.setRowsCount(svideoCommentReadMapper.getMessageCount(example));
        List<VideoMessageVO> list = svideoCommentReadMapper.getMessageList(example, pager.getStart(), pager.getPageSize());
        return list;
    }

    /**
     * 评论点赞
     *
     * @param commentId
     * @param author
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer clickPraise(Integer commentId, Author author) {
        //查询是否有历史点赞记录
        SvideoCommentLikeExample example = new SvideoCommentLikeExample();
        example.setAuthorId(author.getAuthorId());
        example.setCommentId(commentId);
        List<SvideoCommentLike> commentLikeList = svideoCommentLikeReadMapper.listByExample(example);
        //根据评论id查询评论信息
        SvideoComment svideoComment = this.getSvideoCommentByCommentId(commentId);
        AssertUtil.notNull(svideoComment, "获取评论信息为空，请重试！");
        Integer count = 0;
        if (CollectionUtils.isEmpty(commentLikeList)) {
            //没有点赞历史 直接插入
            SvideoCommentLike record = new SvideoCommentLike();
            record.setCommentId(commentId);
            record.setAuthorId(author.getAuthorId());
            record.setVideoId(svideoComment.getVideoId());
            count = svideoCommentLikeWriteMapper.insert(record);
            AssertUtil.isTrue(count == 0, "点赞失败，请重试！");

            //更新评论点赞数量
            SvideoComment comment = new SvideoComment();
            comment.setCommentId(commentId);
            comment.setLikeNum(svideoComment.getLikeNum() + 1);
            count = svideoCommentWriteMapper.updateByPrimaryKeySelective(comment);
            AssertUtil.isTrue(count == 0, "更新评论点赞数量失败，请重试！");
        } else {
            SvideoCommentLike like = commentLikeList.get(0);
            //点赞两次相当于直接取消
            count = svideoCommentLikeWriteMapper.deleteByPrimaryKey(like.getCommentLikeId());
            AssertUtil.isTrue(count == 0, "取消点赞失败，请重试！");

            //更新评论点赞数量
            SvideoComment comment = new SvideoComment();
            comment.setCommentId(commentId);
            comment.setLikeNum(svideoComment.getLikeNum() - 1);
            count = svideoCommentWriteMapper.updateByPrimaryKeySelective(comment);
            AssertUtil.isTrue(count == 0, "更新评论点赞数量失败，请重试！");
        }
        example.setAuthorId(null);
        return svideoCommentLikeReadMapper.countByExample(example);
    }
}