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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.code.DictConstant;
import com.ruoyi.code.PublicCommon;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.enums.process.ProcessResultEnums;
import com.ruoyi.enums.user.UserEnums;
import com.ruoyi.frequency.customer.service.UserService;
import com.ruoyi.frequency.enterprise.entity.Enterprise;
import com.ruoyi.frequency.enterprise.service.EnterpriseService;
import com.ruoyi.frequency.recommend.service.RecommendService;
import com.ruoyi.frequency.store.entity.Store;
import com.ruoyi.frequency.store.service.StoreService;
import com.ruoyi.post.controller.req.PostPageReq;
import com.ruoyi.post.controller.req.PostReleaseReq;
import com.ruoyi.post.controller.resp.PostDetailResp;
import com.ruoyi.post.controller.resp.PostPageResp;
import com.ruoyi.post.controller.vo.SelectedComment;
import com.ruoyi.post.frequency.posshield.service.PostShieldService;
import com.ruoyi.post.frequency.post.entity.Post;
import com.ruoyi.post.frequency.post.mapper.PostMapper;
import com.ruoyi.post.frequency.post.model.result.PostCount;
import com.ruoyi.post.frequency.post.service.PostService;
import com.ruoyi.post.frequency.postcomment.service.PostCommentService;
import com.ruoyi.response.ResponseData;
import com.ruoyi.utils.BusinessUtil;
import com.ruoyi.utils.SnowIdUtils;
import com.ruoyi.vo.UserInfo;
import com.ruoyi.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 帖子Service业务层处理
 *
 * @author liwenlong
 * @date 2023-10-09
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService {
    @Autowired
    private PostMapper postMapper;

    /**
     * 查询帖子
     *
     * @param id 帖子主键
     * @return 帖子
     */
    @Override
    public Post selectPostById(Long id) {
        Post post = postMapper.selectPostById(id);

        if (post != null) {
            Set<UserVo> userVoSet = new HashSet<>();
            userVoSet.add(new UserVo(post.getUserType(), post.getUserId()));
            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, null);

            if (ObjectUtil.isNotEmpty(post.getCommentId())) {
                //精彩评论ids
                List<Long> commentIds = CollectionUtil.toList(post.getCommentId());

                //查询精选评论
                Map<Long, SelectedComment> selectedCommentMap = postCommentService.getSelectedCommentMap(commentIds, null);

                post.setSelectedComment(selectedCommentMap.get(post.getId()));
            }

            post.setUserInfo(userMap.get(new UserVo(post.getUserType(), post.getUserId())));

        }

        return post;
    }

    @Autowired
    private EnterpriseService enterpriseService;

    /**
     * 查询帖子列表
     *
     * @param post 帖子
     * @return 帖子
     */
    @Override
    public List<Post> selectPostList(Post post) {

        List<Post> posts = postList(post);

        if (!posts.isEmpty()) {
            Set<UserVo> userVoSet = posts.stream().map(s -> new UserVo(s.getUserType(), s.getUserId())).collect(Collectors.toSet());
            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, null);

            //精彩评论ids
            List<Long> commentIds = posts.stream().filter(s -> ObjectUtil.isNotEmpty(s.getCommentId())).map(Post::getCommentId).collect(Collectors.toList());

            //查询精选评论
            Map<Long, SelectedComment> selectedCommentMap = postCommentService.getSelectedCommentMap(commentIds, null);

            posts.stream().forEach(s -> {
                s.setUserInfo(userMap.get(new UserVo(s.getUserType(), s.getUserId())));
                s.setSelectedComment(selectedCommentMap.get(s.getId()));
            });
        }

        return posts;
    }

    private List<Post> postList(Post post) {
        if (SecurityUtils.hasRoleKey("enterprise")) {
            Enterprise enterprise = enterpriseService.getOne(new QueryWrapper<Enterprise>().lambda().eq(Enterprise::getSysUserId, SecurityUtils.getUserId()));
            if (enterprise == null) {
                return null;
            }
            post.setEnterpriseId(enterprise.getId());
        }

        List<Post> posts = postMapper.selectPostList(post);
        return posts;
    }

    @Override
    public PostCount statistics(Post post) {

        List<Post> posts = postList(post);
        List<Long> postIdList = posts.stream().map(x -> x.getId()).collect(Collectors.toList());
        postIdList.add(-1L);
        return postMapper.statistics(postIdList);
    }

    /**
     * 新增帖子
     *
     * @param post 帖子
     * @return 结果
     */
    @Override
    public int insertPost(Post post) {
        post.setCreateTime(DateUtils.getNowDate());
        return postMapper.insert(post);
    }

    /**
     * 修改帖子
     *
     * @param post 帖子
     * @return 结果
     */
    @Override
    public int updatePost(Post post) {
        post.setUpdateTime(DateUtils.getNowDate());
        return postMapper.updateById(post);
    }


    /**
     * 修改帖子
     *
     * @param post 帖子
     * @return 结果
     */
    @Override
    public int updatePostLikeNum(Post post, Integer num) {
        post.setUpdateTime(DateUtils.getNowDate());
        return postMapper.updatePostLikeNum(post.getId(), num);
    }

    /**
     * 批量删除帖子
     *
     * @param ids 需要删除的帖子主键
     * @return 结果
     */
    @Override
    public int deletePostByIds(Long[] ids) {
        this.lambdaUpdate().set(Post::getDelFlag, PublicCommon.删除).in(Post::getId, ids).update();
        return ids.length;
    }

    /**
     * 删除帖子信息
     *
     * @param id 帖子主键
     * @return 结果
     */
    @Override
    public int deletePostById(Long id) {
        this.lambdaUpdate().set(Post::getDelFlag, PublicCommon.删除).eq(Post::getId, id).update();
        return 1;
    }

    @Override
    public AjaxResult topping(Long id) {

        //自动置顶 1作品 2帖子
        recommendService.topping(2, id);

        return AjaxResult.success();
    }


    @Autowired
    private BusinessUtil businessUtil;

    @Autowired
    private UserService userService;

    @Autowired
    private StoreService storeService;

    @Autowired
    private RecommendService recommendService;

    @Override
    public ResponseData postRelease(PostReleaseReq req, UserVo userVo) {

        Post post = new Post(req, userVo);

        //是否需要审核
        SysDictData post_dict = businessUtil.getDict(DictConstant.帖子审核);

        Optional.ofNullable(post_dict)
                .filter(s -> s.getDictValue().equals(PublicCommon.Process.不用审核))
                .ifPresent(p -> post.setResult(ProcessResultEnums.APPROVED.getCode()));

        boolean save = this.save(post);
        //表现师发布帖子 判断该表现师是否是官方用户
        if (save && ObjectUtil.equal(UserEnums.store.getCode(), userVo.getUserType())) {
            Store store = storeService.getById(userVo.getUserId());
            if (store != null && ObjectUtil.isNotEmpty(store.getIsPlatform()) && store.getIsPlatform() == 2) {
                //自动置顶 1作品 2帖子
                recommendService.topping(2, post.getId());
            }
        }
        return ResponseData.success(post.getId());
    }

    @Autowired
    private PostCommentService postCommentService;

    @Autowired
    private PostShieldService postShieldService;

    @Override
    public ResponseData postPage(PostPageReq req, UserVo userVo) {

        //筛去拉黑与被拉黑用户
        List<UserVo> blockUserList = userService.blockUserList(userVo);
        req.setBlockUserList(blockUserList);

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

        //筛去屏蔽的帖子
        List<Long> shieldPostIdList = postShieldService.shieldPostList(userVo);
        req.setShieldPostIdList(shieldPostIdList);


        Page<PostPageResp> page = this.baseMapper.postPage(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());
            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

            //精彩评论ids
            List<Long> commentIds = page.getRecords().stream().filter(s -> ObjectUtil.isNotEmpty(s.getCommentId())).map(PostPageResp::getCommentId).collect(Collectors.toList());

            //查询精选评论
            Map<Long, SelectedComment> selectedCommentMap = postCommentService.getSelectedCommentMap(commentIds, userVo);

            //帖子ids
            List<Long> postIds = page.getRecords().stream().filter(s -> ObjectUtil.isNotEmpty(s.getId())).map(PostPageResp::getId).collect(Collectors.toList());

            //查询最新评论 帖子id ->最新评论
            Map<Long, SelectedComment> selectedNewCommentMap = postCommentService.getSelectedNewCommentMap(postIds, userVo);


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

                if (selectedCommentMap.get(resp.getCommentId()) != null) {
                    resp.setSelectedComment(selectedCommentMap.get(resp.getCommentId()));
                } else {
                    //没有精选评论-->查询最新一条评论
                    resp.setSelectedComment(selectedNewCommentMap.get(resp.getId()));
                }
            });
        }

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


    @Override
    public ResponseData postDetail(Long id, Integer isAddBrowseNum, UserVo userVo) {

        PostDetailResp detailResp = this.baseMapper.postDetail(id, userVo);

        //增加论坛浏览数
        Optional.ofNullable(detailResp).ifPresent(p -> {

                    //是否增加浏览数 1不增加 2 加
                    if (ObjectUtil.equal(2, isAddBrowseNum)) {
                        this.baseMapper.updateNumPost(id, PublicCommon.Post.浏览数, 1);

                        this.baseMapper.updateBrowseRecord(SnowIdUtils.uniqueLong(), 2, new Date(), id, userVo);
                    }

                    Set<UserVo> userVoSet = new HashSet<>();
                    UserVo user = new UserVo(detailResp.getUserType(), detailResp.getUserId());
                    userVoSet.add(user);
                    //查询用户信息
                    Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);
                    detailResp.setUserInfo(userMap.get(user));

                    PostPageResp postPageResp = new PostPageResp();
                    BeanUtil.copyProperties(detailResp, postPageResp);
                }
        );
        return ResponseData.success(detailResp);
    }

    @Override
    public Map<Long, Post> selectPostMap(Set<Long> postIds) {

        List<Post> posts = this.list(new QueryWrapper<Post>().lambda().in(Post::getId, postIds));

        return posts.stream().collect(Collectors.toMap(Post::getId, Function.identity()));
    }

    @Override
    public ResponseData postEdit(PostReleaseReq req, UserVo userVo) {
        Post post = new Post();
        BeanUtil.copyProperties(req, post);
        post.setUpdateData();
        this.updateById(post);
        return ResponseData.success();
    }

    @Override
    public ResponseData postDelete(Long id, UserVo userVo) {
        this.lambdaUpdate().set(Post::getDelFlag, PublicCommon.删除).eq(Post::getId, id).update();
        return ResponseData.success();
    }
}
