package com.gxwebsoft.cms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.cms.entity.ArticleLike;
import com.gxwebsoft.cms.entity.Follow;
import com.gxwebsoft.cms.mapper.ArticleMapper;
import com.gxwebsoft.cms.param.ArticleLikeParam;
import com.gxwebsoft.cms.param.FollowParam;
import com.gxwebsoft.cms.service.ArticleLikeService;
import com.gxwebsoft.cms.service.ArticleService;
import com.gxwebsoft.cms.entity.Article;
import com.gxwebsoft.cms.param.ArticleParam;
import com.gxwebsoft.cms.service.FollowService;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文章Service实现
 *
 * @author 科技小王子
 * @since 2023-10-22 15:47:09
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
    @Resource
    private FollowService followService;
    @Resource
    private ArticleLikeService articleLikeService;

    @Override
    public PageResult<Article> pageRel(ArticleParam param) {
        PageParam<Article, ArticleParam> page = new PageParam<>(param);
        page.setDefaultOrder("sort_number asc, create_time desc");
        List<Article> list = baseMapper.selectPageRel(page, param);
        return new PageResult<>(list, page.getTotal());
    }

    @Override
    public List<Article> listRel(ArticleParam param) {
        List<Article> listInFollow = new ArrayList<>();
        if (param.getFollowOnly() != null && param.getLoginUserId() != null) {
            List<Follow> followList = followService.listRel(new FollowParam() {{
                setUserId(param.getLoginUserId());
            }});
            listInFollow = list(
                    new LambdaQueryWrapper<Article>()
                            .in(Article::getUserId, followList.stream().map(Follow::getFollowUserId).toList())
            );
            if (!listInFollow.isEmpty()) {
                for (Article article : listInFollow) {
                    article.setHasFollow(true);
                }
                return listInFollow;
            }
        }
        List<Article> list = baseMapper.selectListRel(param);
        // 排序
        PageParam<Article, ArticleParam> page = new PageParam<>();
        page.setDefaultOrder("sort_number asc, create_time desc");
        if (param.getLoginUserId() != null) {
            List<Follow> followList = followService.listRel(new FollowParam() {{
                setUserId(param.getLoginUserId());
            }});
            List<ArticleLike> likeList = articleLikeService.listRel(new ArticleLikeParam() {{
                setUserId(param.getLoginUserId());
            }});
            for (Article article : list) {
                article.setFansNum(followService.countByFollowUser(article.getUserId()));
                article.setHasFollow(false);
                if (!followList.isEmpty()) {
                    for (Follow follow : followList) {
                        if (article.getUserId().equals(follow.getFollowUserId())) {
                            article.setHasFollow(true);
                        }
                    }
                }
                article.setHasLike(false);
                if (!likeList.isEmpty()) {
                    for (ArticleLike articleLike : likeList) {
                        if (article.getArticleId().equals(articleLike.getArticleId())) {
                            article.setHasLike(true);
                        }
                    }
                }

            }
        } else {
            for (Article article : list) {
                article.setFansNum(followService.countByFollowUser(article.getUserId()));
            }
        }

        return page.sortRecords(list);
    }

    @Override
    public PageResult<?> pageMinData(ArticleParam param) {
        PageResult<Article> list = pageRel(param);
        List<Map<String, Object>> minDataList = new ArrayList<>();
        for (Article article : list.getList()) {
            minDataList.add(setData(article));
        }
        if (param.getIncludeId() != null) {
            Article article = getByIdRel(param.getIncludeId());
            if (article != null) {
                minDataList.add(setData(article));
            }
        }
        PageResult<Map<String, Object>> pageResult = new PageResult<>();
        pageResult.setList(minDataList);
        pageResult.setCount(list.getCount());
        return pageResult;
    }

    @Override
    public List<?> listMinData(ArticleParam param) {
        List<Article> list = listRel(param);
        List<Map<String, Object>> minDataList = new ArrayList<>();
        for (Article article : list) {
            minDataList.add(setData(article));
        }
        return minDataList;
    }

    private Map<String, Object> setData(Article article){
        Map<String, Object> data = new HashMap<>();
        data.put("articleId", article.getArticleId());
        data.put("hasFollow", article.getHasFollow());
        data.put("imageWidth", article.getImageWidth());
        data.put("imageHeight", article.getImageHeight());
        data.put("username", article.getUsername());
        data.put("title", article.getTitle());
        data.put("userAvatar", article.getUserAvatar());
        data.put("actualViews", article.getActualViews());
        data.put("commentNumbers", article.getCommentNumbers());
        data.put("cover", article.getCover());
        data.put("image", article.getImage());
        data.put("shareCover", article.getShareCover());
        data.put("likes", article.getLikes());
        data.put("hasLike", article.getHasLike());
        data.put("fansNum", article.getFansNum());
        data.put("userId", article.getUserId());
        data.put("video", article.getVideo());
        return data;
    }

    @Override
    public Article getByIdRel(Integer articleId) {
        ArticleParam param = new ArticleParam();
        param.setArticleId(articleId);
        return param.getOne(baseMapper.selectListRel(param));
    }

}
