package com.tanpu.community.manager;

import com.fasterxml.jackson.core.type.TypeReference;
import com.tanpu.common.api.CommonResp;
import com.tanpu.common.exception.BizException;
import com.tanpu.common.util.JsonUtil;
import com.tanpu.community.api.beans.qo.FormerThemeQo;
import com.tanpu.community.api.beans.qo.NotificationQo;
import com.tanpu.community.api.beans.qo.ThemeContentQo;
import com.tanpu.community.api.beans.qo.ThemeNotifyQo;
import com.tanpu.community.api.beans.qo.ThemeQo;
import com.tanpu.community.api.beans.qo.UserBriefInfoQO;
import com.tanpu.community.api.beans.req.notification.NotifyQueryReq;
import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp;
import com.tanpu.community.api.constants.RedisKeyConstant;
import com.tanpu.community.api.enums.NotificationTypeEnum;
import com.tanpu.community.api.enums.ThemeTypeEnum;
import com.tanpu.community.cache.RedisCache;
import com.tanpu.community.dao.entity.NotificationForwardDO;
import com.tanpu.community.dao.entity.community.CollectionEntity;
import com.tanpu.community.dao.entity.community.CommentEntity;
import com.tanpu.community.dao.entity.community.FollowRelEntity;
import com.tanpu.community.dao.entity.community.NotificationEntity;
import com.tanpu.community.dao.entity.community.ThemeEntity;
import com.tanpu.community.feign.fatools.FeignClientForFatools;
import com.tanpu.community.service.BatchFeignCallService;
import com.tanpu.community.service.CollectionService;
import com.tanpu.community.service.CommentService;
import com.tanpu.community.service.FollowRelService;
import com.tanpu.community.service.NotificationService;
import com.tanpu.community.service.ThemeService;
import com.tanpu.community.service.TopicService;
import com.tanpu.community.util.ConvertUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.tanpu.community.api.constants.RedisKeyConstant.CACHE_FEIGN_USER_INFO;

@Service
public class NotificationManager {

    @Autowired
    private NotificationService notificationService;

    @Autowired
    private TopicService topicService;

    @Autowired
    private ThemeService themeService;

    @Resource
    private BatchFeignCallService batchFeignCallService;

    @Autowired
    private FeignClientForFatools feignClientForFatools;

    @Autowired
    private CommentService commentService;


    @Autowired
    private FollowRelService followRelService;

    @Autowired
    private CollectionService collectionService;

    @Autowired
    private RedisCache redisCache;

    public List<ThemeNotifyQo> queryList(NotifyQueryReq req, String userId) {
        List<NotificationEntity> query = notificationService.query(userId, req.getType(), req.getLastId(), req.getPageSize());
        List<ThemeNotifyQo> themeNotifyQos = ConvertUtil.notificationEntitiy2ThemeQos(query);
        UserInfoResp currentUser = redisCache.getObject(StringUtils.joinWith("_", CACHE_FEIGN_USER_INFO, userId),
                60, () -> this.getUserInfo(userId), UserInfoResp.class);
        Set<String> followUserIds = followRelService.queryIdolsByFansId(userId).stream().collect(Collectors.toSet());
        for (ThemeNotifyQo themeNotifyQo : themeNotifyQos) {

            // 用户信息
            UserInfoResp userInfo = redisCache.getObject(StringUtils.joinWith("_", CACHE_FEIGN_USER_INFO, themeNotifyQo.getAuthorId()),
                    60, () -> this.getUserInfo(themeNotifyQo.getAuthorId()), UserInfoResp.class);
            themeNotifyQo.setAuthorId(userInfo.getUserId());
            themeNotifyQo.setNickName(userInfo.getNickName());
            themeNotifyQo.setUserImg(userInfo.getHeadImageUrl());
            themeNotifyQo.setUserType(userInfo.getUserType());
            themeNotifyQo.setLevelGrade(userInfo.getLevelGrade());
            themeNotifyQo.setUserInvestorType(userInfo.getUserInvestorType());
            themeNotifyQo.setBelongUserOrgId(userInfo.getBelongUserOrgId());
            themeNotifyQo.setBelongUserOrgName(userInfo.getBelongUserOrgName());

            // 评论根据commentEntity找到ThemeId
            if (NotificationTypeEnum.COMMENT.getCode().equals(themeNotifyQo.getMessageType()) ||
                    NotificationTypeEnum.COMMENT_LIKE.getCode().equals(themeNotifyQo.getMessageType())) {
                // 评论类型将commentId替换为themeId
                CommentEntity commentEntity = commentService.queryByCommentId(themeNotifyQo.getCommentId());
                if (commentEntity != null) {
                    themeNotifyQo.setFormerThemeId(commentEntity.getThemeId());
                    if (NotificationTypeEnum.COMMENT_LIKE.getCode().equals(themeNotifyQo.getMessageType())) {
                        themeNotifyQo.setContent(commentEntity.getContent());
                    }

                }

            }

            // 封装引用对象
            if (StringUtils.isNotEmpty(themeNotifyQo.getFormerThemeId())) {
                ThemeEntity former = themeService.queryByThemeId(themeNotifyQo.getFormerThemeId());
                if (former != null) {
                    themeNotifyQo.setFormerUserName(currentUser.getNickName());
                    if (StringUtils.isNotBlank(former.getTopicId())) {
                        // 内部话题
                        themeNotifyQo.setFormerTopicId(former.getTopicId());
                        themeNotifyQo.setFormerTopicTitle(topicService.queryTitleById(former.getTopicId()));
                    }
                    if (ThemeTypeEnum.DISCUSSION.getCode().equals(former.getThemeType()) || ThemeTypeEnum.FORWARD.getCode().equals(former.getThemeType())) {
                        List<ThemeContentQo> themeContentQos = JsonUtil.toBean(former.getContent(), new TypeReference<List<ThemeContentQo>>() {
                        });
                        themeNotifyQo.setFormerContent(themeContentQos.get(0).getValue());
                    } else if (ThemeTypeEnum.LONG_TEXT.getCode().equals(former.getThemeType())) {
                        themeNotifyQo.setFormerContent(former.getTitle());
                    }
                } else {
                    // 引用主题已被删除
                    themeNotifyQo.setFormerThemeId(null);
                }
            }
            // 外部话题
            if (StringUtils.isNotBlank(themeNotifyQo.getTopicId())) {
                themeNotifyQo.setTopicTitle(topicService.queryTitleById(themeNotifyQo.getTopicId()));
            }
            // 点赞聚合
            if (themeNotifyQo.getLikeUserCount() != null && themeNotifyQo.getLikeUserCount() > 1) {
                List<UserBriefInfoQO> likeUsers = themeNotifyQo.getLikeUsers();
                for (UserBriefInfoQO likeUser : likeUsers) {
                    UserInfoResp luser = redisCache.getObject(StringUtils.joinWith("_", CACHE_FEIGN_USER_INFO, likeUser.getUserId()),
                            60, () -> this.getUserInfo(likeUser.getUserId()), UserInfoResp.class);
                    likeUser.setHeadImageUrl(luser.getHeadImageUrl());
                    likeUser.setNickName(luser.getNickName());
                }
            }
            // 是否关注
            themeNotifyQo.setFollow(followUserIds.contains(themeNotifyQo.getAuthorId()));
        }

        redisCache.evict(RedisKeyConstant.MESSAGE_NOTIFY_COUNT + userId);
        // 更新查询时间,用于删除评论
        redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_QUERY_TIME + userId,
                JsonUtil.toJson(LocalDateTime.now()), 60 * 60 * 24 * 30);

        return themeNotifyQos;
    }


    // 查询消息通知概览
    public NotificationQo queryBriefInfo(String userId) {
        String count = redisCache.get(RedisKeyConstant.MESSAGE_NOTIFY_COUNT + userId);
        String lastMsg = redisCache.get(RedisKeyConstant.MESSAGE_NOTIFY_LAST_MSG + userId);
        String lastTime = redisCache.get(RedisKeyConstant.MESSAGE_NOTIFY_LAST_TIME + userId);
        return NotificationQo.builder().message(lastMsg).updateCount(count == null ? 0 : Integer.parseInt(count)).updateTime(lastTime).build();
    }

    // 初始化所有消息通知
    public void initAllData() {
        notificationService.truncate();
        // 关注
        List<FollowRelEntity> followRelEntities = followRelService.queryAll();
        for (FollowRelEntity followRelEntity : followRelEntities) {
            notificationService.insert(followRelEntity.getFansId(), followRelEntity.getIdolId(), NotificationTypeEnum.FOLLOW
                    , followRelEntity.getFansId(), "", followRelEntity.getUpdateTime());

            notificationService.putNotifyCacheFollow(followRelEntity.getIdolId(), followRelEntity.getFansId(), followRelEntity.getUpdateTime());
        }
        // 转发
        List<ThemeEntity> themeEntities = themeService.queryAllForward();
        for (ThemeEntity themeEntity : themeEntities) {
            ThemeEntity former = themeService.queryByThemeId(themeEntity.getFormerThemeId());
            if (former == null) {
                continue;
            }
            List<ThemeContentQo> themeContentQos = JsonUtil.toBean(themeEntity.getContent(), new TypeReference<List<ThemeContentQo>>() {
            });
            String s = themeContentQos.get(0).getValue();
            NotificationForwardDO content = NotificationForwardDO.builder()
                    .content(s.length() > 500 ? s.substring(0, 500) : s)
                    .themeId(themeEntity.getThemeId())
                    .topicId(themeEntity.getTopicId()).build();
            notificationService.insert(themeEntity.getAuthorId(), former.getAuthorId(), NotificationTypeEnum.FORWARD
                    , themeEntity.getFormerThemeId(), JsonUtil.toJson(content), themeEntity.getUpdateTime());
            notificationService.putNotifyCache(former.getAuthorId(), themeEntity.getAuthorId(), NotificationTypeEnum.FORWARD, themeEntity.getUpdateTime());
        }
        // 评论
        List<CommentEntity> commentEntities = commentService.queryAll();
        for (CommentEntity commentEntity : commentEntities) {
            ThemeEntity themeEntity = themeService.queryByThemeId(commentEntity.getThemeId());
            if (themeEntity == null) {
                continue;
            }
            String s = commentEntity.getContent();
            notificationService.insert(commentEntity.getAuthorId(), themeEntity.getAuthorId(), NotificationTypeEnum.COMMENT
                    , commentEntity.getCommentId(), s, commentEntity.getUpdateTime());
            notificationService.putNotifyCache(themeEntity.getAuthorId(), commentEntity.getAuthorId(), NotificationTypeEnum.COMMENT, commentEntity.getUpdateTime());
        }

        // 点赞
        List<CollectionEntity> collectionEntities = collectionService.queryALlLikeTheme();
        for (CollectionEntity collectionEntity : collectionEntities) {
            ThemeEntity themeEntity = themeService.queryByThemeId(collectionEntity.getTargetId());
            if (themeEntity == null) {
                continue;
            }
            notificationService.insertLike(collectionEntity.getUserId(), themeEntity.getAuthorId(), collectionEntity.getTargetId(), collectionEntity.getUpdateTime());
            notificationService.putNotifyCache(themeEntity.getAuthorId(), collectionEntity.getUserId(), NotificationTypeEnum.LIKE, collectionEntity.getUpdateTime());
        }

    }

    //返回被转发主题
    private FormerThemeQo getFormerTheme(String formerThemeId) {
        if (StringUtils.isNotBlank(formerThemeId)) {
            ThemeQo formerTheme = ConvertUtil.themeEntityToQo(themeService.queryByThemeId(formerThemeId));
            if (formerTheme != null) {
                batchFeignCallService.getAttachDetail(formerTheme);
                FormerThemeQo f = ConvertUtil.themeQo2FormerThemeQo(formerTheme);
                return f;
            }

        }
        return null;
    }


    private UserInfoResp getUserInfo(String authorId) {
        CommonResp<UserInfoResp> userInfoNewCommonResp = feignClientForFatools.queryUserInfoNew(authorId);
        if (userInfoNewCommonResp.isNotSuccess()) {
            throw new BizException("内部接口调用失败");
        }
        return userInfoNewCommonResp.getData();
    }
}