package com.ruoyi.frequency.workscomment.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.code.PublicCommon;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.controller.req.DialoguePageReq;
import com.ruoyi.controller.req.WorksCommentPageReq;
import com.ruoyi.controller.req.WorksCommentReq;
import com.ruoyi.controller.resp.CommentNum;
import com.ruoyi.controller.resp.WorksCommentPageResp;
import com.ruoyi.controller.resp.WorksCommentResp;
import com.ruoyi.enums.message.InteractionMessageEnums;
import com.ruoyi.frequency.customer.service.UserService;
import com.ruoyi.frequency.works.entity.Works;
import com.ruoyi.frequency.works.mapper.WorksMapper;
import com.ruoyi.frequency.works.service.WorksService;
import com.ruoyi.frequency.workscomment.entity.WorksComment;
import com.ruoyi.frequency.workscomment.mapper.WorksCommentMapper;
import com.ruoyi.frequency.workscomment.service.WorksCommentService;
import com.ruoyi.message.frequency.interactionmessagerecord.service.InteractionMessageRecordService;
import com.ruoyi.post.controller.req.DeleteCommentReq;
import com.ruoyi.response.ResponseData;
import com.ruoyi.vo.UserInfo;
import com.ruoyi.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 作品评论Service业务层处理
 *
 * @author liwenlong
 * @date 2024-04-11
 */
@Service
public class WorksCommentServiceImpl extends ServiceImpl<WorksCommentMapper, WorksComment> implements WorksCommentService {
    @Autowired
    private WorksCommentMapper worksCommentMapper;

    /**
     * 查询作品评论
     *
     * @param id 作品评论主键
     * @return 作品评论
     */
    @Override
    public WorksComment selectWorksCommentById(Long id) {
        return worksCommentMapper.selectWorksCommentById(id);
    }

    /**
     * 查询作品评论列表
     *
     * @param worksComment 作品评论
     * @return 作品评论
     */
    @Override
    public List<WorksComment> selectWorksCommentList(WorksComment worksComment) {
        List<WorksComment> worksComments = worksCommentMapper.selectWorksCommentList(worksComment);
        if (!worksComments.isEmpty()) {
            Set<UserVo> userVoSet = worksComments.stream().map(s -> new UserVo(s.getUserType(), s.getUserId())).collect(Collectors.toSet());
            Set<UserVo> parentUserVoSet = worksComments.stream().map(s -> new UserVo(s.getParentUserType(), s.getParentUserId())).collect(Collectors.toSet());

            userVoSet.addAll(parentUserVoSet);

            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, null);

            worksComments.stream().forEach(s -> {
                s.setUserInfo(userMap.get(new UserVo(s.getUserType(), s.getUserId())));
                s.setParentUserInfo(userMap.get(new UserVo(s.getParentUserType(), s.getParentUserId())));
            });
        }
        return worksComments;
    }

    /**
     * 新增作品评论
     *
     * @param worksComment 作品评论
     * @return 结果
     */
    @Override
    public int insertWorksComment(WorksComment worksComment) {
        worksComment.setCreateData();
        return worksCommentMapper.insert(worksComment);
    }

    /**
     * 修改作品评论
     *
     * @param worksComment 作品评论
     * @return 结果
     */
    @Override
    public int updateWorksComment(WorksComment worksComment) {
        worksComment.setUpdateData();
        return worksCommentMapper.updateWorksComment(worksComment);
    }


    @Autowired
    private UserService userService;

    @Override
    public ResponseData<WorksCommentResp> worksComment(WorksCommentReq req, UserVo userVo) {
        //作品评论
        WorksComment worksComment = new WorksComment(req, userVo);

        //帖子-->评论
        if (ObjectUtil.isEmpty(req.getParentId()) || ObjectUtil.equal(0L, req.getParentId())) {
            //顶级评论id
            worksComment.setTopId(worksComment.getId());
        } else {
            //查询上级评论
            WorksComment parentWorksComment = this.getById(req.getParentId());

            //评论用户
            worksComment.setParentUserId(parentWorksComment.getUserId())
                    .setParentUserType(parentWorksComment.getUserType());

            worksComment.setTopId(parentWorksComment.getTopId());

            //上级id
            if (ObjectUtil.isNotEmpty(parentWorksComment.getParentIds())) {
                worksComment.setParentIds(parentWorksComment.getParentIds() + "," + parentWorksComment.getId());
            } else {
                worksComment.setParentIds(parentWorksComment.getId() + "");
            }
        }

        this.save(worksComment);

        //1 帖子 2 帖子评论
        Integer type = ObjectUtil.equal(0L, req.getParentId()) || ObjectUtil.isEmpty(req.getParentId()) ? 1 : 2;

        //修改评论数(只要针对这个作品下的评论 作品评论数都要+1)
        Works works = new Works().setId(worksComment.getWorksId()).setCommentNum(1).setTrendsTime(new Date());
        works.setUpdateData();
        worksMapper.updateWorks(works);
        //作品评论 所有上级评论数+1
        if (ObjectUtil.equal(2, type)) {
            //上级评论ids
            List<String> pids = Arrays.stream(worksComment.getParentIds().split(",")).collect(Collectors.toList());

            List<WorksComment> worksComments = pids.stream().map(id -> {
                        WorksComment comment = new WorksComment().setId(Long.valueOf(id)).setCommentNum(1);
                        comment.setUpdateTime(DateUtils.getNowDate());
                        return comment;
                    }
            ).collect(Collectors.toList());

            this.baseMapper.updateWorksCommentBatch(worksComments);
        }

        //返回结果
        WorksCommentResp commentResp = baseMapper.getWorksCommentResp(worksComment.getId());

        if (commentResp != null) {

            UserVo parentUserVo = new UserVo(worksComment.getParentUserType(), worksComment.getParentUserId());

            Set<UserVo> userVoSet = CollectionUtil.newHashSet(userVo, parentUserVo);
            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

            commentResp.setUserInfo(userMap.get(userVo));

            commentResp.setParentUserInfo(userMap.get(parentUserVo));
        }

        //推送消息
        pushMessage(req, userVo, true);

        return ResponseData.success(commentResp);
    }

    @Autowired
    private WorksMapper worksMapper;

    /**
     * 修改评论数
     *
     * @param objectId 评论主体id
     * @param type     1作品 2 作品评论
     * @param num
     */
    private void updateWorksCommentNum(Long objectId, Integer type, Integer num) {

        switch (type) {
            case 1:
                worksMapper.updateWorks(new Works().setId(objectId).setCommentNum(num));
                break;
            case 2:
                this.updateWorksComment(new WorksComment().setId(objectId).setCommentNum(num));
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + type);
        }
    }

    @Autowired
    private InteractionMessageRecordService interactionMessageRecordService;

    @Autowired
    private WorksService worksService;

    /**
     * 推送消息
     *
     * @param req
     * @param userVo
     * @param isPush
     */
    private void pushMessage(WorksCommentReq req, UserVo userVo, Boolean isPush) {

        InteractionMessageEnums enums = ObjectUtil.equal(0L, req.getParentId()) ? InteractionMessageEnums.COMMENT_WORKS : InteractionMessageEnums.REPLY_WORKS_COMMENT;

        //作品id
        Long worksId = null;

        //接收消息用户
        UserVo sendUserVo = null;

        if (ObjectUtil.equal(0L, req.getParentId())) {
            //评论作品
            worksId = req.getWorksId();
            //作品
            Works works = worksService.getById(worksId);
            sendUserVo = new UserVo(works.getUserType(), works.getStoreId());
        } else {
            //回复评论
            WorksComment worksComment = this.getById(req.getParentId());
            worksId = worksComment.getWorksId();
            sendUserVo = new UserVo(worksComment.getUserType(), worksComment.getUserId());
        }
        //互动消息
        interactionMessageRecordService.addInteractionMessage(userVo, sendUserVo, PublicCommon.InteractionMessage.评论, worksId, isPush, enums);

    }

    @Override
    public ResponseData<PageResult<WorksCommentPageResp>> worksCommentPage(WorksCommentPageReq req, UserVo userVo) {
        //筛去拉黑与被拉黑用户
        List<UserVo> blockUserList = userService.blockUserList(userVo);
        req.setBlockUserList(blockUserList);

        //筛去屏蔽用户
        List<UserVo> shieldUserList = userService.shieldUserList(userVo);
        req.setShieldUserList(shieldUserList);

        Page<WorksCommentPageResp> page = this.baseMapper.worksCommentPage(new Page<>(req.getPageNo(), req.getPageSize()), req, userVo);

        if (!page.getRecords().isEmpty()) {
            Set<UserVo> userVoSet = page.getRecords().stream().map(postPageResp -> new UserVo(postPageResp.getUserType(), postPageResp.getUserId())).collect(Collectors.toSet());
            Set<UserVo> parentUserVoSet = page.getRecords().stream().map(postPageResp -> new UserVo(postPageResp.getParentUserType(), postPageResp.getParentUserId())).collect(Collectors.toSet());

            userVoSet.addAll(parentUserVoSet);

            List<WorksCommentPageResp> postCommentList = twoCommentList(req, userVo, page);

            postCommentList.stream().forEach(resp -> {
                userVoSet.add(new UserVo(resp.getUserType(), resp.getUserId()));
                userVoSet.add(new UserVo(resp.getParentUserType(), resp.getParentUserId()));
            });


            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

            List<UserVo> userVoList = CollectionUtil.addAllIfNotContains(blockUserList, shieldUserList);

            Map<Long, Integer> commentNumMap = getCommentNumMap(userVoList, page.getRecords());

            postCommentList.stream().forEach(resp -> {
                resp.setUserInfo(userMap.get(new UserVo(resp.getUserType(), resp.getUserId())));
                resp.setParentUserInfo(userMap.get(new UserVo(resp.getParentUserType(), resp.getParentUserId())));
            });
            //获取二级评论
            Map<Long, List<WorksCommentPageResp>> map = postCommentList.stream().collect(Collectors.groupingBy(WorksCommentPageResp::getParentId));
            ;


            page.getRecords().stream().forEach(resp -> {
                resp.setUserInfo(userMap.get(new UserVo(resp.getUserType(), resp.getUserId())));
                resp.setParentUserInfo(userMap.get(new UserVo(resp.getParentUserType(), resp.getParentUserId())));
                if (commentNumMap.get(resp.getId()) != null) {
                    resp.setCommentNum(resp.getCommentNum() - commentNumMap.get(resp.getId()));
                }

                //二级评论
                resp.setChildrenList(map.get(resp.getId()));
            });
        }

        return ResponseData.success(new PageResult<>(page));
    }

    /**
     * 获取二级评论ID
     *
     * @param req
     * @param userVo
     * @param page
     * @return
     */
    private List<WorksCommentPageResp> twoCommentList(WorksCommentPageReq req, UserVo userVo, Page<WorksCommentPageResp> page) {

        Map<Long, List<WorksCommentPageResp>> map = new HashMap<>();

        if (ObjectUtil.isEmpty(req.getParentId())) {
            //一级评论ID
            List<Long> parentIds = page.getRecords().stream().map(WorksCommentPageResp::getId).collect(Collectors.toList());

            if (CollectionUtil.isEmpty(parentIds)) {
                return new ArrayList<>();
            }
            //查询二级评论
            List<WorksCommentPageResp> worksCommentList = this.baseMapper.worksCommentList(req, userVo, parentIds);

            return worksCommentList;
        }
        return new ArrayList<>();
    }

    private Map<Long, Integer> getCommentNumMap(List<UserVo> userVoList, List<WorksCommentPageResp> respList) {

        if (userVoList.size() == 0) {
            return new HashMap<>();
        }
        List<Long> commentIds = respList.stream().map(WorksCommentPageResp::getId).collect(Collectors.toList());
        //查询用户对应评论的数量 key一级评论id value 隐藏数量
        List<CommentNum> commentNums = worksCommentMapper.selectCommentNumList(commentIds, userVoList);

        Map<Long, Integer> commentNumMap = new HashMap<>();
        commentNums.stream().forEach(s -> {
            commentNumMap.put(s.getWorksId(), s.getCommentNum());
        });
        return commentNumMap;
    }

    @Override
    public ResponseData deleteComment(DeleteCommentReq req, UserVo userVo) {
        boolean update = this.lambdaUpdate().set(WorksComment::getDelFlag, PublicCommon.删除)
                .eq(WorksComment::getUserType, userVo.getUserType())
                .eq(WorksComment::getUserId, userVo.getUserId())
                .eq(WorksComment::getId, req.getId())
                .eq(WorksComment::getDelFlag, PublicCommon.启用).update();

        if (update) {
            afterDeleteComment(req.getId());
        }
        return ResponseData.success();
    }

    private void afterDeleteComment(Long objectId) {

        WorksComment worksComment = this.getById(objectId);

        //删除当前评论所有下级评论
        this.lambdaUpdate().set(WorksComment::getDelFlag, PublicCommon.删除)
                .like(WorksComment::getParentId, objectId)
                .eq(WorksComment::getDelFlag, PublicCommon.启用).update();


        //1 作品 2 作品评论
        Integer type = ObjectUtil.equal(0L, worksComment.getParentId()) ? 1 : 2;

        Integer num = -(worksComment.getCommentNum() + 1);
        //帖子评论 上级数量
        if (ObjectUtil.equal(2, type)) {
            //当前评论上级ids
            List<String> pids = Arrays.stream(worksComment.getParentIds()
                    .split(",")).collect(Collectors.toList());
            num = -1 * pids.size();

            //上级评论数都要减去当前删除评论数 + 1(本身评论)
            List<WorksComment> worksComments = pids.stream().map(id -> {
                WorksComment comment = new WorksComment().setId(Long.valueOf(id)).setCommentNum(-1 * (worksComment.getCommentNum() + 1));
                comment.setUpdateTime(DateUtils.getNowDate());
                return comment;
            }).collect(Collectors.toList());

            this.baseMapper.updateWorksCommentBatch(worksComments);

        }
        //删除当前评论所有下级评论
        this.lambdaUpdate().set(WorksComment::getDelFlag, PublicCommon.删除)
                .like(WorksComment::getParentIds, objectId)
                .eq(WorksComment::getDelFlag, PublicCommon.启用).update();


        //修改评论数
        worksMapper.updateWorks(new Works().setId(worksComment.getWorksId()).setCommentNum(num));
    }


    /**
     * 批量删除作品评论
     *
     * @param ids 需要删除的作品评论主键
     * @return 结果
     */
    @Override
    public int deleteWorksCommentByIds(Long[] ids, Integer delFlag) {
        if (PublicCommon.删除.equals(delFlag)) {
            for (Long objectId : ids) {
                afterDeleteComment(objectId);
            }
        }

        this.lambdaUpdate().set(WorksComment::getDelFlag, delFlag).in(WorksComment::getId, ids).update();
        return 1;
    }

    @Override
    public ResponseData<WorksCommentResp> worksCommentDetail(Long id, UserVo userVo) {
        WorksCommentResp commentResp = baseMapper.getWorksCommentResp(id);

        if (commentResp != null) {

            UserVo parentUserVo = new UserVo(commentResp.getParentUserType(), commentResp.getParentUserId());
            UserVo user = new UserVo(commentResp.getUserType(), commentResp.getUserId());

            Set<UserVo> userVoSet = CollectionUtil.newHashSet(user, parentUserVo);
            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

            commentResp.setUserInfo(userMap.get(user));

            commentResp.setParentUserInfo(userMap.get(parentUserVo));
        }
        return ResponseData.success(commentResp);
    }

    @Override
    public ResponseData<PageResult<Page<WorksCommentPageResp>>> worksCommentDialoguePage(DialoguePageReq req, UserVo userVo) {

        Page<WorksCommentPageResp> page = this.baseMapper.worksCommentDialoguePage(new Page<>(req.getPageNo(), req.getPageSize()), req, userVo);

        if (!page.getRecords().isEmpty()) {
            Set<UserVo> userVoSet = page.getRecords().stream().map(postPageResp -> new UserVo(postPageResp.getUserType(), postPageResp.getUserId())).collect(Collectors.toSet());
            Set<UserVo> parentUserVoSet = page.getRecords().stream().map(postPageResp -> new UserVo(postPageResp.getParentUserType(), postPageResp.getParentUserId())).collect(Collectors.toSet());

            userVoSet.addAll(parentUserVoSet);

            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

            page.getRecords().stream().forEach(resp -> {
                resp.setUserInfo(userMap.get(new UserVo(resp.getUserType(), resp.getUserId())));
                resp.setParentUserInfo(userMap.get(new UserVo(resp.getParentUserType(), resp.getParentUserId())));
            });
        }

        return ResponseData.success(new PageResult<>(page));
    }
}
