package com.webchat.service;

import com.google.common.base.Joiner;
import com.webchat.common.enums.CommonStatusEnum;
import com.webchat.common.enums.RedisKeyEnum;
import com.webchat.common.enums.ResourceTypeEnum;
import com.webchat.common.util.HtmlUtil;
import com.webchat.common.util.ThreadPoolExecutorUtil;
import com.webchat.domain.vo.request.MomentSaveOrUpdateVO;
import com.webchat.domain.vo.response.CommentOutResponseVO;
import com.webchat.domain.vo.response.MomentResponseDetailVO;
import com.webchat.domain.vo.response.ResourceBaseInfoVO;
import com.webchat.repository.dao.IMomentDAO;
import com.webchat.repository.entity.MomentEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

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

/**
 * @author 程序员王七七 https://www.coderutil.com 网站作者
 * @date 2024/11/6 23:56
 */
@Service
public class MomentService {

    @Autowired
    private IMomentDAO momentDAO;
    @Autowired
    private MomentCacheService momentCacheService;
    @Autowired
    private CommentService commentService;

    /**
     * 朋友圈发布动态
     *
     * @param vo
     * @return
     */
    public Long publish(String userId, MomentSaveOrUpdateVO vo) {
        MomentEntity entity = convertSaveEntity(vo, userId);
        entity = momentDAO.save(entity);
        // 发布成功刷新动态缓存
        MomentEntity finalEntity = entity;
//        ThreadPoolExecutorUtil.execute(() ->
            momentCacheService.refreshCommunityAboutCacheByPublish(finalEntity);
//        );
        return entity.getId();
    }

    /**
     * 删除内容
     *
     * @param userId
     * @param id
     */
    public void delete(String userId, Long id) {
        MomentEntity entity = momentDAO.findAllById(id);
        Assert.isTrue(entity != null && !CommonStatusEnum.DELETED.getStatus().equals(entity.getStatus()),
                "内容不存在或者已经被删除");
        Assert.isTrue(entity.getAuthor().equals(userId), "没有删除权限");
        entity.setUpdateDate(new Date());
        entity.setUpdateBy(userId);
        entity.setStatus(CommonStatusEnum.DELETED.getStatus());
        momentDAO.save(entity);
        // 刷新缓存
        ThreadPoolExecutorUtil.execute(() -> momentCacheService.refreshCommunityAboutCacheByDelete(entity, userId));
    }

    public List<MomentResponseDetailVO> getUserMomentListFromTimeLineCache(String userId, int size, Long lastId) {
        List<MomentResponseDetailVO> list = momentCacheService.getUserMomentListFromTimeLineCache(userId, size, lastId == null ? Long.MAX_VALUE : lastId - 1);
        if (CollectionUtils.isEmpty(list)) {
            return list;
        }
        List<Long> resourceIdList = list.stream().map(MomentResponseDetailVO::getId).collect(Collectors.toList());
        // 批量查询外显评论
        Map<Long, List<CommentOutResponseVO>> outCommentResultMap =
                commentService.batchGetOutCommentFromCache(ResourceTypeEnum.MOMENT.getType(), resourceIdList);
        for (MomentResponseDetailVO vo : list) {
            // 设置外显评论
            vo.setOutComments(outCommentResultMap.get(vo.getId()));
        }
        return list;
    }

    /**
     * 查询社区动态详情
     *
     * @param id
     * @return
     */
    public MomentResponseDetailVO getMomentDetail(Long id) {
        MomentResponseDetailVO communityResponseDetailVO = momentCacheService.getCommunityDetailFromCache(id);
        communityResponseDetailVO.setClickCount(communityResponseDetailVO.getClickCount() + 1);
        ThreadPoolExecutorUtil.execute(() -> {
            MomentEntity entity = momentDAO.findAllById(id);
            entity.setClickCount(entity.getClickCount() + 1);
            momentDAO.save(entity);
        });
        return communityResponseDetailVO;
    }

    public ResourceBaseInfoVO getResourceBaseInfo(Long resourceId) {
        MomentResponseDetailVO communityResponseDetailVO = getMomentDetail(resourceId);
        if (communityResponseDetailVO == null) {
            return null;
        }
        ResourceBaseInfoVO resourceBaseInfoVO = new ResourceBaseInfoVO();
        resourceBaseInfoVO.setResourceId(resourceId);
        resourceBaseInfoVO.setAuthor(communityResponseDetailVO.getAuthor());
        resourceBaseInfoVO.setContent(communityResponseDetailVO.getContent());
        resourceBaseInfoVO.setDetailUrl(null);
        resourceBaseInfoVO.setFirstImage(communityResponseDetailVO.getFirstImage());
        return resourceBaseInfoVO;
    }

    private MomentEntity convertSaveEntity(MomentSaveOrUpdateVO vo, String userId) {
        MomentEntity entity;
        Date now = new Date();
        if (vo.getId() != null) {
            entity = momentDAO.findAllById(vo.getId());
            Assert.isTrue(entity != null, "内容不存在");
        } else {
            entity = new MomentEntity();
            entity.setStatus(CommonStatusEnum.PUBLISHED.getStatus());
            entity.setCreateBy(userId);
            entity.setCreateDate(now);
            entity.setPubDate(now);
            entity.setClickCount(0L);
            entity.setAuthor(userId);
        }
        entity.setContent(this.handleSpecialHtmlTag(HtmlUtil.xssEscape(vo.getContent())));
        if (!CollectionUtils.isEmpty(vo.getImages())) {
            entity.setImages(Joiner.on(",").join(vo.getImages()));
        }
        entity.setVideo(vo.getVideo());
        entity.setUpdateBy(userId);
        entity.setUpdateDate(now);
        // 发布端
        entity.setClient(vo.getClient());
        return entity;
    }

    /**
     * 处理特殊字符
     * @param content
     * @return
     */
    private String handleSpecialHtmlTag(String content) {
        if (StringUtils.isBlank(content)) {
            return content;
        }
        content = content.replaceAll("&lt;br&gt;", "<br>");
        content = content.replaceAll("&lt;b&gt;", "<b>");
        content = content.replaceAll("&lt;pre&gt;", "<pre>");
        content = content.replaceAll("&lt;/pre&gt;", "</pre>");
        return content;
    }
}
