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

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.PublicCommon;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.controller.req.CollectObjectReq;
import com.ruoyi.controller.req.CollectPageReq;
import com.ruoyi.controller.resp.WorksPageResp;
import com.ruoyi.frequency.collect.entity.Collect;
import com.ruoyi.frequency.collect.mapper.CollectMapper;
import com.ruoyi.frequency.collect.model.param.UserCollectNumParam;
import com.ruoyi.frequency.collect.service.CollectService;
import com.ruoyi.frequency.customer.service.UserService;
import com.ruoyi.frequency.news.entity.News;
import com.ruoyi.frequency.news.mapper.NewsMapper;
import com.ruoyi.frequency.works.entity.Works;
import com.ruoyi.frequency.works.mapper.WorksMapper;
import com.ruoyi.frequency.workspanorama.entity.WorksPanorama;
import com.ruoyi.frequency.workspanorama.service.WorksPanoramaService;
import com.ruoyi.frequency.worksshield.service.WorksShieldService;
import com.ruoyi.frequency.workstype.service.WorksTypeService;
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.mapper.PostMapper;
import com.ruoyi.post.frequency.postcomment.service.PostCommentService;
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 org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 收藏Service业务层处理
 *
 * @author zj
 * @date 2023-10-16
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class CollectServiceImpl extends ServiceImpl<CollectMapper, Collect> implements CollectService {
    @Autowired
    private CollectMapper collectMapper;

    /**
     * 查询收藏
     *
     * @param id 收藏主键
     * @return 收藏
     */
    @Override
    public Collect selectCollectById(Long id) {
        return collectMapper.selectCollectById(id);
    }

    /**
     * 查询收藏列表
     *
     * @param collect 收藏
     * @return 收藏
     */
    @Override
    public List<Collect> selectCollectList(Collect collect) {
        return collectMapper.selectCollectList(collect);
    }

    /**
     * 新增收藏
     *
     * @param collect 收藏
     * @return 结果
     */
    @Override
    public int insertCollect(Collect collect) {
        collect.setCreateTime(DateUtils.getNowDate());
        return collectMapper.insertCollect(collect);
    }

    /**
     * 修改收藏
     *
     * @param collect 收藏
     * @return 结果
     */
    @Override
    public int updateCollect(Collect collect) {
        collect.setUpdateTime(DateUtils.getNowDate());
        return collectMapper.updateCollect(collect);
    }

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

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

    @Override
    public ResponseData collectObject(CollectObjectReq req, UserVo userVo) {

        Collect collect = new Collect(req.getType(), req.getObjectId());

        collect.setCreateData();
        collect.setUpdateData();
        collect.setUserType(userVo.getUserType())
                .setUserId(userVo.getUserId());

        //收藏
        collectMapper.collect(collect, userVo);

        collect = collectMapper.selectOne(new QueryWrapper<Collect>().lambda().eq(Collect::getObjectId, req.getObjectId())
                .eq(Collect::getType, req.getType())
                .eq(Collect::getUserType, userVo.getUserType())
                .eq(Collect::getUserId, userVo.getUserId()));

        //是否收藏
        Boolean isCollect = collect.getDelFlag().equals(PublicCommon.启用);

        //收藏类型 1作品 2 动态 3资讯 4新闻
        updateCollectNum(req.getType(), req.getObjectId(), isCollect);

        return ResponseData.success();
    }

    @Autowired
    private UserService userService;

    @Autowired
    private PostCommentService postCommentService;

    @Autowired
    private WorksTypeService worksTypeService;

    @Autowired
    private WorksPanoramaService worksPanoramaService;

    @Autowired
    private PostShieldService postShieldService;

    @Autowired
    private WorksShieldService worksShieldService;

    @Override
    public ResponseData collectPage(CollectPageReq req, UserVo userVo) {

        //收藏类型 1作品 2 动态 3咨询 4新闻
        switch (req.getType()) {
            case 1:
                Page<WorksPageResp> worksPage = getCollectWorksPage(req, userVo);
                if (!worksPage.getRecords().isEmpty()) {

                    Set<UserVo> userVoSet = worksPage.getRecords().stream().map(worksPageResp -> new UserVo(worksPageResp.getUserType(), worksPageResp.getStoreId())).collect(Collectors.toSet());
                    //查询用户信息
                    Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

                    //作品ids
                    List<Long> worksIds = worksPage.getRecords().stream().map(WorksPageResp::getId).collect(Collectors.toList());
                    //查询3D图
                    List<WorksPanorama> worksPanoramaList = worksPanoramaService.list(new QueryWrapper<WorksPanorama>().lambda().in(WorksPanorama::getWorksId, worksIds).orderByDesc(WorksPanorama::getCreateTime));

                    Map<Long, List<WorksPanorama>> map = worksPanoramaList.stream().collect(Collectors.groupingBy(WorksPanorama::getWorksId));

                    worksPage.getRecords().stream().forEach(worksPageResp -> {
                        worksPageResp.setUserInfo(userMap.get(new UserVo(worksPageResp.getUserType(), worksPageResp.getStoreId())));
                        worksPageResp.setWorksPanoramaList(map.get(worksPageResp.getId()));
                    });
                }
                return ResponseData.success(new PageResult<>(worksPage));
            case 4:
                Page<News> newsPage = getCollectNewsPage(req, userVo);
                return ResponseData.success(new PageResult<>(newsPage));
            default:
                Page<PostPageResp> postPage = getCollectPostPage(req, userVo);

                if (!postPage.getRecords().isEmpty()) {
                    Set<UserVo> userVoSet = postPage.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 = postPage.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 = postPage.getRecords().stream().filter(s -> ObjectUtil.isNotEmpty(s.getId())).map(PostPageResp::getId).collect(Collectors.toList());

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

                    postPage.getRecords().stream().forEach(postPageResp -> {
                        postPageResp.setUserInfo(userMap.get(new UserVo(postPageResp.getUserType(), postPageResp.getUserId())));
                        if (selectedCommentMap.get(postPageResp.getCommentId()) != null) {
                            postPageResp.setSelectedComment(selectedCommentMap.get(postPageResp.getCommentId()));
                        } else {
                            //没有精选评论-->查询最新一条评论
                            postPageResp.setSelectedComment(selectedNewCommentMap.get(postPageResp.getId()));
                        }
                    });
                }

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

    private void setBlockShieldUserOrPost(CollectPageReq req, UserVo userVo) {
        if (req.getType() == 1) {
            //筛去拉黑与被拉黑用户
            if (CollectionUtil.isEmpty(req.getBlockUserList())) {
                List<UserVo> blockUserList = userService.blockUserList(userVo);
                req.setBlockUserList(blockUserList);
            }

            //筛去屏蔽用户
            if (CollectionUtil.isEmpty(req.getShieldUserList())) {
                List<UserVo> shieldUserList = userService.shieldUserList(userVo);
                req.setShieldUserList(shieldUserList);
            }

            //筛去屏蔽的帖子
            if (CollectionUtil.isEmpty(req.getShieldWorksIdList())) {
                List<Long> shieldWorksList = worksShieldService.shieldWorksList(userVo);
                req.setShieldWorksIdList(shieldWorksList);
            }
        } else if (req.getType() == 2) {
            //筛去拉黑与被拉黑用户
            if (CollectionUtil.isEmpty(req.getBlockUserList())) {
                List<UserVo> blockUserList = userService.blockUserList(userVo);
                req.setBlockUserList(blockUserList);
            }

            //筛去屏蔽用户
            if (CollectionUtil.isEmpty(req.getShieldUserList())) {
                List<UserVo> shieldUserList = userService.shieldUserList(userVo);
                req.setShieldUserList(shieldUserList);
            }

            //筛去屏蔽的帖子
            if (CollectionUtil.isEmpty(req.getShieldPostIdList())) {
                List<Long> shieldPostIdList = postShieldService.shieldPostList(userVo);
                req.setShieldPostIdList(shieldPostIdList);
            }
        }

    }


    /**
     * 作品收藏数量
     *
     * @param req
     * @param userVo
     * @return
     */
    @Override
    public Page<WorksPageResp> getCollectWorksPage(CollectPageReq req, UserVo userVo) {

        setBlockShieldUserOrPost(req, userVo);

        if (ObjectUtil.isNotEmpty(req.getTypeId())) {
            //根据类型id获取三级id
            List<Long> typeIdList = worksTypeService.getIdsByTypeId(req.getTypeId());
            if (typeIdList.isEmpty()) {
                return new Page<>(req.getPageNo(), req.getPageSize());
            }
            req.setTypeIds(typeIdList);
        }

        Page<WorksPageResp> worksPage = baseMapper.worksCollectPage(new Page<>(req.getPageNo(), req.getPageSize()), req, userVo);
        return worksPage;
    }


    /**
     * 作品收藏数量
     *
     * @param req
     * @param userVo
     * @return
     */
    @Override
    public Page<News> getCollectNewsPage(CollectPageReq req, UserVo userVo) {

        setBlockShieldUserOrPost(req, userVo);

        Page<News> newsPage = baseMapper.newsCollectPage(new Page<>(req.getPageNo(), req.getPageSize()), req, userVo);
        return newsPage;
    }

    /**
     * 帖子收藏数量
     *
     * @param req
     * @param userVo
     * @return
     */
    @Override
    public Page<PostPageResp> getCollectPostPage(CollectPageReq req, UserVo userVo) {

        setBlockShieldUserOrPost(req, userVo);

        Page<PostPageResp> postPage = baseMapper.postCollectPage(new Page<>(req.getPageNo(), req.getPageSize()), req, userVo);
        return postPage;
    }

    @Override
    public ResponseData otherCollectPage(CollectPageReq req, UserVo userVoSelf) {

        UserVo userVo = new UserVo(req.getUserType(), req.getUserId());

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

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

            //筛去屏蔽的帖子
            List<Long> shieldPostIdList = worksShieldService.shieldWorksList(userVo);
            req.setShieldPostIdList(shieldPostIdList);
        } else if (req.getType() == 2) {
            //筛去拉黑与被拉黑用户
            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);
        }

        //收藏类型 1作品 2 动态
        switch (req.getType()) {
            case 1:
                if (ObjectUtil.isNotEmpty(req.getTypeId())) {
                    //根据类型id获取三级id
                    List<Long> typeIdList = worksTypeService.getIdsByTypeId(req.getTypeId());
                    if (typeIdList.isEmpty()) {
                        return ResponseData.success(new PageResult<>(new Page<>(req.getPageNo(), req.getPageSize())));
                    }
                    req.setTypeIds(typeIdList);
                }
                Page<WorksPageResp> worksPage = baseMapper.worksCollectPage(new Page<>(req.getPageNo(), req.getPageSize()), req, userVoSelf);

                if (!worksPage.getRecords().isEmpty()) {

                    Set<UserVo> userVoSet = worksPage.getRecords().stream().map(worksPageResp -> new UserVo(worksPageResp.getUserType(), worksPageResp.getStoreId())).collect(Collectors.toSet());
                    //查询用户信息
                    Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVoSelf);

                    //作品ids
                    List<Long> worksIds = worksPage.getRecords().stream().map(WorksPageResp::getId).collect(Collectors.toList());
                    //查询3D图
                    List<WorksPanorama> worksPanoramaList = worksPanoramaService.list(new QueryWrapper<WorksPanorama>().lambda().in(WorksPanorama::getWorksId, worksIds).orderByDesc(WorksPanorama::getCreateTime));

                    Map<Long, List<WorksPanorama>> map = worksPanoramaList.stream().collect(Collectors.groupingBy(WorksPanorama::getWorksId));

                    worksPage.getRecords().stream().forEach(worksPageResp -> {
                        worksPageResp.setUserInfo(userMap.get(new UserVo(worksPageResp.getUserType(), worksPageResp.getStoreId())));
                        worksPageResp.setWorksPanoramaList(map.get(worksPageResp.getId()));
                    });
                }

                return ResponseData.success(new PageResult<>(worksPage));
            default:
                Page<PostPageResp> postPage = baseMapper.postCollectPage(new Page<>(req.getPageNo(), req.getPageSize()), req, userVoSelf);

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

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

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

                    postPage.getRecords().stream().forEach(videoPageResp -> {
                        videoPageResp.setUserInfo(userMap.get(new UserVo(videoPageResp.getUserType(), videoPageResp.getUserId())));
                        videoPageResp.setSelectedComment(selectedCommentMap.get(videoPageResp.getId()));
                    });
                }
                return ResponseData.success(new PageResult<>(postPage));
        }
    }

    @Override
    public Integer getUserCollectNum(UserVo userVo, Integer type) {

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

        //筛去屏蔽用户
//        List<UserVo> shieldUserList = userService.shieldUserList(userVo);
//        req.setShieldUserList(shieldUserList);
//
//        if (req.getType() != null) {
//            if (req.getType() == 1) {
//                //筛去屏蔽的作品
//                List<Long> shieldWorksList = worksShieldService.shieldWorksList(userVo);
//                req.setShieldWorksIdList(shieldWorksList);
//            } else if (req.getType() == 2) {
//                //筛去屏蔽的作品
//                List<Long> shieldPostList = postShieldService.shieldPostList(userVo);
//                req.setShieldPostIdList(shieldPostList);
//            }
//        } else {
//            //筛去屏蔽的作品
//            List<Long> shieldWorksList = worksShieldService.shieldWorksList(userVo);
//            req.setShieldWorksIdList(shieldWorksList);
//
//            //筛去屏蔽的作品
//            List<Long> shieldPostList = postShieldService.shieldPostList(userVo);
//            req.setShieldPostIdList(shieldPostList);
//        }

        return baseMapper.getUserCollectNum(userVo, req);
    }


    @Autowired
    private PostMapper postMapper;

    @Autowired
    private NewsMapper newsMapper;

    @Autowired
    private WorksMapper worksMapper;

    /**
     * 修改收藏数量
     *
     * @param type      收藏类型 1作品 2 动态 3资讯 4新闻
     * @param objectId  收藏对象id
     * @param isCollect 是否收藏
     */
    private void updateCollectNum(Integer type, Long objectId, Boolean isCollect) {

        //收藏 +1 ，取消收藏 -1
        Integer num = isCollect ? 1 : -1;

        switch (type) {
            case 1:
                Works works = new Works().setId(objectId).setCollectNum(num);
                works.setUpdateData();
                worksMapper.updateWorks(works);
                break;
            case 2:
                postMapper.updateNumPost(objectId, PublicCommon.Post.收藏数, num);
                break;
            case 3:
                postMapper.updateNumPost(objectId, PublicCommon.Post.收藏数, num);
                break;
            case 4:
                newsMapper.updateNews(new News().setId(objectId).setCollectNum(num));
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + type);
        }
    }
}
