package com.xindazhou.business.service.community.comment;

import com.xindazhou.business.controller.app.community.comment.vo.CommentCreateReqVO;
import com.xindazhou.business.controller.app.community.comment.vo.CommentPageReqVO;
import com.xindazhou.business.controller.app.community.comment.vo.CommentRespVO;
import com.xindazhou.business.convert.community.comment.CommentConvert;
import com.xindazhou.business.dal.community.dataobject.comment.CommentDO;
import com.xindazhou.business.dal.community.dataobject.post.PostDO;
import com.xindazhou.business.dal.community.mysql.comment.CommunityCommentMapper;
import com.xindazhou.business.dal.community.mysql.post.CommunityPostMapper;
import com.xindazhou.business.service.community.like.LikeService;
import com.xindazhou.business.service.community.sensitive.SensitiveWordService;
import com.xindazhou.framework.common.pojo.PageResult;
import com.xindazhou.framework.security.core.util.SecurityFrameworkUtils;
import com.xindazhou.user.api.user.MemberUserApi;
import com.xindazhou.user.api.user.dto.MemberUserRespDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

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

import static com.xindazhou.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.xindazhou.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_FOUND;
import static com.xindazhou.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;

/**
 * 评论 Service 实现类
 *
 * @author xindazhou
 */
@Service("communityCommentServiceImpl")
@Slf4j
@Validated
public class CommentServiceImpl implements CommentService {

    @Resource
    private CommunityCommentMapper commentMapper;

    @Resource
    private CommunityPostMapper communityPostMapper;

    @Resource
    private MemberUserApi memberUserApi;

    @Resource
    private LikeService likeService;

    @Resource
    private SensitiveWordService sensitiveWordService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createComment(CommentCreateReqVO createReqVO) {
        // 校验帖子存在
        PostDO post = communityPostMapper.selectById(createReqVO.getPostId());
        if (post == null) {
            throw exception(NOT_FOUND, "帖子不存在");
        }

        // 如果父评论ID不为0，校验父评论存在
        if (createReqVO.getParentId() != null && createReqVO.getParentId() > 0) {
            CommentDO parentComment = commentMapper.selectById(createReqVO.getParentId());
            if (parentComment == null) {
                throw exception(NOT_FOUND, "父评论不存在");
            }
            // 确保父评论属于同一个帖子
            if (!parentComment.getPostId().equals(createReqVO.getPostId())) {
                throw exception(NOT_FOUND, "父评论不属于该帖子");
            }
        }

        // 敏感词过滤：评论内容
        String filteredContent = sensitiveWordService.filterSensitiveWord(createReqVO.getContent());
        if (filteredContent == null) {
            throw exception(BAD_REQUEST, "评论内容包含敏感词，不允许发布");
        }
        createReqVO.setContent(filteredContent);

        // 获取当前登录用户
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        // 插入评论
        CommentDO comment = CommentConvert.INSTANCE.convert(createReqVO);
        comment.setUserId(userId);
        comment.setParentId(createReqVO.getParentId() != null ? createReqVO.getParentId() : 0L);
        comment.setLikeCount(0);
        comment.setStatus(1); // 1-正常
        commentMapper.insert(comment);

        // 增加帖子的评论数
        post.setCommentCount(post.getCommentCount() + 1);
        communityPostMapper.updateById(post);

        return comment.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteComment(Long id) {
        // 校验评论存在
        CommentDO comment = validateCommentExists(id);

        // 校验权限：只能删除自己的评论
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        if (!comment.getUserId().equals(userId)) {
            throw exception(NOT_FOUND, "无权删除该评论");
        }

        // 删除（逻辑删除）
        commentMapper.deleteById(id);

        // 减少帖子的评论数
        PostDO post = communityPostMapper.selectById(comment.getPostId());
        if (post != null && post.getCommentCount() > 0) {
            post.setCommentCount(post.getCommentCount() - 1);
            communityPostMapper.updateById(post);
        }
    }

    @Override
    public CommentRespVO getComment(Long id) {
        CommentDO comment = validateCommentExists(id);
        CommentRespVO respVO = CommentConvert.INSTANCE.convert(comment);
        
        // 填充用户信息
        fillUserInfo(respVO, comment.getUserId());
        
        // 填充点赞状态
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        if (userId != null) {
            respVO.setIsLiked(likeService.isLiked(2, id)); // 2-评论
        } else {
            respVO.setIsLiked(false);
        }
        
        return respVO;
    }

    @Override
    public PageResult<CommentRespVO> getCommentPage(CommentPageReqVO reqVO) {
        PageResult<CommentDO> pageResult = commentMapper.selectPage(reqVO);
        PageResult<CommentRespVO> result = CommentConvert.INSTANCE.convertPage(pageResult);
        
        // 批量填充用户信息
        fillUserInfoList(result.getList());
        
        // 批量填充点赞状态
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        if (userId != null) {
            fillLikeStatus(result.getList(), userId);
        }
        
        return result;
    }

    @Override
    public List<CommentRespVO> getCommentTree(Long postId) {
        // 查询顶级评论
        List<CommentDO> topComments = commentMapper.selectTopLevelByPostId(postId);
        if (topComments.isEmpty()) {
            return new ArrayList<>();
        }

        // 转换为VO
        List<CommentRespVO> topCommentVOs = CommentConvert.INSTANCE.convertList(topComments);

        // 查询所有回复
        List<Long> topCommentIds = topComments.stream().map(CommentDO::getId).collect(Collectors.toList());
        List<CommentDO> allReplies = new ArrayList<>();
        for (Long topCommentId : topCommentIds) {
            List<CommentDO> replies = commentMapper.selectRepliesByParentId(topCommentId);
            allReplies.addAll(replies);
        }

        // 转换为VO并按父评论ID分组
        List<CommentRespVO> replyVOs = CommentConvert.INSTANCE.convertList(allReplies);
        Map<Long, List<CommentRespVO>> replyMap = replyVOs.stream()
                .collect(Collectors.groupingBy(CommentRespVO::getParentId));

        // 将回复挂载到对应的顶级评论下
        for (CommentRespVO topCommentVO : topCommentVOs) {
            List<CommentRespVO> replies = replyMap.getOrDefault(topCommentVO.getId(), new ArrayList<>());
            topCommentVO.setReplies(replies);
        }

        // 批量填充用户信息（包括顶级评论和回复）
        List<CommentRespVO> allComments = new ArrayList<>(topCommentVOs);
        topCommentVOs.forEach(comment -> {
            if (comment.getReplies() != null) {
                allComments.addAll(comment.getReplies());
            }
        });
        fillUserInfoList(allComments);

        // 批量填充点赞状态
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        if (userId != null) {
            fillLikeStatus(allComments, userId);
        }

        return topCommentVOs;
    }

    /**
     * 填充单个评论的用户信息
     */
    private void fillUserInfo(CommentRespVO respVO, Long userId) {
        if (userId == null) {
            return;
        }
        MemberUserRespDTO user = memberUserApi.getUser(userId).getCheckedData();
        if (user != null) {
            respVO.setUserNickname(user.getNickname());
            respVO.setUserAvatar(user.getAvatar());
        }
    }

    /**
     * 批量填充评论列表的用户信息
     */
    private void fillUserInfoList(List<CommentRespVO> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        Set<Long> userIds = list.stream()
                .map(CommentRespVO::getUserId)
                .filter(userId -> userId != null)
                .collect(Collectors.toSet());
        if (userIds.isEmpty()) {
            return;
        }
        Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds);
        list.forEach(comment -> {
            MemberUserRespDTO user = userMap.get(comment.getUserId());
            if (user != null) {
                comment.setUserNickname(user.getNickname());
                comment.setUserAvatar(user.getAvatar());
            }
            // 填充父评论用户昵称
            if (comment.getParentId() != null && comment.getParentId() > 0) {
                CommentDO parentComment = commentMapper.selectById(comment.getParentId());
                if (parentComment != null) {
                    MemberUserRespDTO parentUser = userMap.get(parentComment.getUserId());
                    if (parentUser != null) {
                        comment.setParentUserNickname(parentUser.getNickname());
                    }
                }
            }
        });
    }

    /**
     * 批量填充点赞状态
     */
    private void fillLikeStatus(List<CommentRespVO> list, Long userId) {
        if (list == null || list.isEmpty()) {
            return;
        }
        for (CommentRespVO comment : list) {
            comment.setIsLiked(likeService.isLiked(2, comment.getId())); // 2-评论
        }
    }

    @Override
    public PageResult<com.xindazhou.business.controller.admin.community.comment.vo.CommentRespVO> getCommentPageAdmin(com.xindazhou.business.controller.admin.community.comment.vo.CommentPageReqVO reqVO) {
        PageResult<CommentDO> pageResult = commentMapper.selectPageAdmin(reqVO);
        
        // 转换为管理后台VO
        List<com.xindazhou.business.controller.admin.community.comment.vo.CommentRespVO> adminComments = pageResult.getList().stream()
                .map(comment -> {
                    com.xindazhou.business.controller.admin.community.comment.vo.CommentRespVO adminComment = new com.xindazhou.business.controller.admin.community.comment.vo.CommentRespVO();
                    adminComment.setId(comment.getId());
                    adminComment.setPostId(comment.getPostId());
                    adminComment.setUserId(comment.getUserId());
                    adminComment.setParentId(comment.getParentId());
                    adminComment.setContent(comment.getContent());
                    adminComment.setLikeCount(comment.getLikeCount());
                    adminComment.setStatus(comment.getStatus());
                    adminComment.setCreateTime(comment.getCreateTime());
                    adminComment.setUpdateTime(comment.getUpdateTime());
                    return adminComment;
                })
                .collect(Collectors.toList());
        
        // 批量填充用户信息和帖子标题
        Set<Long> userIds = adminComments.stream()
                .map(com.xindazhou.business.controller.admin.community.comment.vo.CommentRespVO::getUserId)
                .filter(userId -> userId != null)
                .collect(Collectors.toSet());
        Set<Long> postIds = adminComments.stream()
                .map(com.xindazhou.business.controller.admin.community.comment.vo.CommentRespVO::getPostId)
                .filter(postId -> postId != null)
                .collect(Collectors.toSet());
        
        if (!userIds.isEmpty()) {
            Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds);
            adminComments.forEach(comment -> {
                MemberUserRespDTO user = userMap.get(comment.getUserId());
                if (user != null) {
                    comment.setUserNickname(user.getNickname());
                }
            });
        }
        
        if (!postIds.isEmpty()) {
            List<PostDO> posts = communityPostMapper.selectBatchIds(postIds);
            Map<Long, String> postTitleMap = posts.stream()
                    .collect(Collectors.toMap(PostDO::getId, PostDO::getTitle));
            adminComments.forEach(comment -> {
                String postTitle = postTitleMap.get(comment.getPostId());
                if (postTitle != null) {
                    comment.setPostTitle(postTitle);
                }
            });
        }
        
        return new PageResult<>(adminComments, pageResult.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCommentAdmin(Long id) {
        // 校验评论存在
        CommentDO comment = validateCommentExists(id);
        
        // 删除（逻辑删除）
        commentMapper.deleteById(id);
        
        // 减少帖子的评论数
        PostDO post = communityPostMapper.selectById(comment.getPostId());
        if (post != null && post.getCommentCount() > 0) {
            post.setCommentCount(post.getCommentCount() - 1);
            communityPostMapper.updateById(post);
        }
    }

    private CommentDO validateCommentExists(Long id) {
        CommentDO comment = commentMapper.selectById(id);
        if (comment == null) {
            throw exception(NOT_FOUND, "评论不存在");
        }
        return comment;
    }

}

