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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
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.constant.HttpStatus;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.page.ManualPagination;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.controller.req.NewsPageReq;
import com.ruoyi.frequency.news.entity.News;
import com.ruoyi.frequency.news.mapper.NewsMapper;
import com.ruoyi.frequency.news.model.result.NewsCount;
import com.ruoyi.frequency.news.service.NewsService;
import com.ruoyi.post.frequency.post.mapper.PostMapper;
import com.ruoyi.response.ResponseData;
import com.ruoyi.utils.SnowIdUtils;
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-03-19
 */
@Service
public class NewsServiceImpl extends ServiceImpl<NewsMapper, News> implements NewsService {
    @Autowired
    private NewsMapper newsMapper;

    /**
     * 查询新闻
     *
     * @param id 新闻主键
     * @return 新闻
     */
    @Override
    public News selectNewsById(Long id) {

        News news = newsMapper.selectNewsById(id);

        if (news != null) {
            List<News> list = this.list(new QueryWrapper<News>().lambda().eq(News::getDelFlag, PublicCommon.启用).ne(News::getPid, 0L)
                    .eq(News::getPid, news.getId()));
            news.setChildList(list);
        }

        return news;
    }

    /**
     * 查询新闻列表
     *
     * @param news 新闻
     * @return 新闻
     */
    @Override
    public TableDataInfo selectNewsList(News news) {
        List<News> newsList = newsList(news);

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(ManualPagination.getPage(newsList));
        rspData.setTotal(newsList.size());
        return rspData;
    }

    private List<News> newsList(News news) {
        List<News> newsList = newsMapper.selectNewsList(news);
        if (newsList.size() > 0) {
            //新闻ids
            List<Long> newsIds = newsList.stream().map(News::getId).collect(Collectors.toList());

            List<News> list = this.list(new QueryWrapper<News>().lambda().eq(News::getDelFlag, PublicCommon.启用).ne(News::getPid, 0L).in(News::getPid, newsIds));

            Map<Long, List<News>> map = list.stream().collect(Collectors.groupingBy(News::getPid));

            newsList.stream().forEach(s -> {
                s.setChildList(map.get(s.getId()));
            });
        }
        //筛选
        Iterator<News> iterator = newsList.iterator();
        while (iterator.hasNext()) {
            News next = iterator.next();
            List<News> childList = next.getChildList();
            if (childList != null && childList.size() > 0) {
                News child = childList.get(0);
                if (news != null) {
                    if (StrUtil.isNotBlank(news.getTitle()) && !child.getTitle().contains(news.getTitle())) {
                        iterator.remove();
                    }
                    if (news.getBeginTime() != null && child.getCreateTime().getTime() < news.getBeginTime().getTime()) {
                        iterator.remove();
                    }
                    if (news.getEndTime() != null && child.getCreateTime().getTime() > news.getEndTime().getTime()) {
                        iterator.remove();
                    }
                }
            }
        }

        newsList.stream().forEach(x -> {
            List<News> childList = x.getChildList();
            if (CollectionUtil.isNotEmpty(childList)) {
                News news1 = childList.get(0);
                x.setId(news1.getId());
                x.setDelFlag(news1.getDelFlag());
                x.setImage(news1.getImage());
                x.setPid(news1.getPid());
                x.setSort(news1.getSort());
                x.setTitle(news1.getTitle());
                x.setContent(news1.getContent());
                x.setLikeNum(news1.getLikeNum());
                x.setCollectNum(news1.getCollectNum());
                x.setCommentNum(news1.getCommentNum());
                x.setBrowseNum(news1.getBrowseNum());
                x.setCommentId(news1.getCommentId());
                x.setCreateTime(news1.getCreateTime());
                x.setCreateBy(news1.getCreateBy());
                x.setUpdateTime(news1.getUpdateTime());
                x.setUpdateBy(news1.getUpdateBy());

                List<News> childList2 = childList.subList(1, childList.size());
                x.setChildList(childList2);
            }
        });

        return newsList;
    }


    @Override
    public News newsInfo(Long id) {
        News news = newsMapper.selectById(id);
        if (news != null) {
            //新闻ids
            List<Long> newsIds = new ArrayList<>();
            newsIds.add(id);

            List<News> list = this.list(new QueryWrapper<News>().lambda().eq(News::getDelFlag, PublicCommon.启用).ne(News::getPid, 0L).in(News::getPid, newsIds));

            Map<Long, List<News>> map = list.stream().collect(Collectors.groupingBy(News::getPid));

            news.setChildList(map.get(id));
        }

        List<News> childList = news.getChildList();
        if (CollectionUtil.isNotEmpty(childList)) {
            News news1 = childList.get(0);
            news.setId(news1.getId());
            news.setDelFlag(news1.getDelFlag());
            news.setImage(news1.getImage());
            news.setPid(news1.getPid());
            news.setSort(news1.getSort());
            news.setTitle(news1.getTitle());
            news.setContent(news1.getContent());
            news.setLikeNum(news1.getLikeNum());
            news.setCollectNum(news1.getCollectNum());
            news.setCommentNum(news1.getCommentNum());
            news.setBrowseNum(news1.getBrowseNum());
            news.setCommentId(news1.getCommentId());
            news.setCreateTime(news1.getCreateTime());
            news.setCreateBy(news1.getCreateBy());
            news.setUpdateTime(news1.getUpdateTime());
            news.setUpdateBy(news1.getUpdateBy());

            List<News> childList2 = childList.subList(1, childList.size());
            news.setChildList(childList2);
        }
        return news;
    }

    @Override
    public NewsCount statistics(News news) {
        List<News> newsList = newsList(news);
        List<Long> newsIdList = newsList.stream().map(x -> x.getId()).collect(Collectors.toList());
        newsIdList.add(-1L);

        Integer likeNum = 0;
        Integer collectNum = 0;
        Integer browseNum = 0;
        Integer commentNum = 0;
        for (News cur : newsList) {
            likeNum = likeNum + cur.getLikeNum();
            collectNum = collectNum + cur.getCollectNum();
            browseNum = browseNum + cur.getBrowseNum();
            commentNum = commentNum + cur.getCommentNum();
            List<News> childList = cur.getChildList();
            if (CollectionUtil.isNotEmpty(childList)) {
                for (News news1 : childList) {
                    likeNum = likeNum + news1.getLikeNum();
                    collectNum = collectNum + news1.getCollectNum();
                    browseNum = browseNum + news1.getBrowseNum();
                    commentNum = commentNum + news1.getCommentNum();
                }
            }
        }

        NewsCount count = newsMapper.statistics(newsIdList);
        count.setBrowseNum(browseNum);
        count.setCollectNum(collectNum);
        count.setCommentNum(commentNum);
        count.setLikeNum(likeNum);
        return count;
    }

    /**
     * 新增新闻
     *
     * @param news 新闻
     * @return 结果
     */
    @Override
    public int insertNews(News news) {
        if (news.getChildList() != null && news.getChildList().size() > 0) {
            List<News> childList = news.getChildList();
            news.setPid(0L);
            news.setCreateData();
            newsMapper.insert(news);

            childList.stream().forEach(s -> {
                s.setCreateData();
                s.setPid(news.getId());
            });

            this.saveBatch(childList);
        }

        return 1;
    }

    /**
     * 修改新闻
     *
     * @param news 新闻
     * @return 结果
     */
    @Override
    public int updateNews(News news) {
        news.setUpdateData();
        int i = newsMapper.updateNews(news);

        this.remove(new QueryWrapper<News>().lambda().eq(News::getPid, news.getId()));

        if (i > 0 && news.getChildList() != null && news.getChildList().size() > 0) {
            List<News> childList = news.getChildList();

            childList.stream().forEach(s -> {
                s.setCreateData();
                s.setPid(news.getId());
            });

            this.saveBatch(childList);
        }

        return 1;
    }

    /**
     * 批量删除新闻
     *
     * @param ids 需要删除的新闻主键
     * @return 结果
     */
    @Override
    public int deleteNewsByIds(Long[] ids, Integer delFlag) {
        this.lambdaUpdate().set(News::getDelFlag, delFlag).in(News::getId, ids).update();

        News news = getById(ids[0]);
        if (news != null) {
            //删除的id同级如果没有启用的话，就把上级也删掉
            Integer count = baseMapper.selectCount(new QueryWrapper<News>().lambda().eq(News::getPid, news.getPid())
                    .eq(News::getDelFlag, PublicCommon.启用));
            if (count == 0) {
                this.lambdaUpdate().set(News::getDelFlag, delFlag).in(News::getId, news.getPid()).update();
            }

        }

        return ids.length;
    }

    @Override
    public ResponseData<PageResult<Page<News>>> newsPage(NewsPageReq req, UserVo userVo) {

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

        //查询子集
        if (page.getRecords().size() > 0) {
            List<Long> newsIds = page.getRecords().stream().map(News::getId).collect(Collectors.toList());
            List<News> list = this.list(new QueryWrapper<News>().lambda()
                    .eq(News::getDelFlag, PublicCommon.启用)
                    .in(News::getPid, newsIds)
                    .orderByAsc(News::getSort, BaseEntity::getCreateTime)
            );
            //进行分组
            Map<Long, List<News>> map = list.stream().collect(Collectors.groupingBy(News::getPid));

            page.getRecords().stream().forEach(s -> {
                s.setChildList(map.get(s.getId()));
            });
        }

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

    @Autowired
    private PostMapper postMapper;

    @Override
    public ResponseData<News> newsDetail(Long id, Integer isAddBrowseNum, UserVo userVo) {
        News news = this.baseMapper.newsDetail(id, userVo);

        //查询子集
        if (news != null) {

            //是否增加浏览数 1不增加 2 加
            if (ObjectUtil.equal(2, isAddBrowseNum)) {
                //增加浏览数
                this.baseMapper.updateNews(new News().setId(id).setBrowseNum(1));

                //type: 类型 1作品 2 帖子 3投票 4新闻 5活动
                postMapper.updateBrowseRecord(SnowIdUtils.uniqueLong(), 4, new Date(), id, userVo);
            }
        }

        return ResponseData.success(news);
    }


}
