package com.mcwl.resource.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mcwl.common.constant.QueueConstants;
import com.mcwl.common.core.domain.entity.SysUser;
import com.mcwl.common.utils.SecurityUtils;
import com.mcwl.common.utils.StringUtils;
import com.mcwl.resource.domain.ModelComment;
import com.mcwl.resource.domain.ModelCommentLike;
import com.mcwl.resource.domain.SysAdvice;
import com.mcwl.resource.domain.WorkFlowComment;
import com.mcwl.resource.domain.dto.ModelCommentRes;
import com.mcwl.resource.domain.vo.ModelCommentVo;
import com.mcwl.resource.mapper.ModelCommentMapper;
import com.mcwl.resource.mapper.ModelImageMapper;
import com.mcwl.resource.service.ISysAdviceService;
import com.mcwl.resource.service.ModelCommentLikeService;
import com.mcwl.resource.service.ModelCommentService;
import com.mcwl.system.domain.enums.AdviceEnum;
import com.mcwl.system.service.ISysUserService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 模型评论
 */
@Service
public class ModelCommentServiceImpl extends ServiceImpl<ModelCommentMapper, ModelComment> implements ModelCommentService {

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ModelCommentMapper modelCommentMapper;

    @Autowired
    private ModelCommentLikeService modelCommentLikeService;


    @Autowired
    private ISysAdviceService sysAdviceService;

    @Autowired
    private ModelImageMapper modelImageMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void comment(ModelCommentRes modelCommentRes) {
        Long parentId = modelCommentRes.getParentId();

        if (Objects.nonNull(parentId)) {
            ModelComment mic = modelCommentMapper.selectById(parentId);
            if (Objects.isNull(mic)) {
                return;
            }
        }
        ModelComment modelComment = new ModelComment();
        BeanUtil.copyProperties(modelCommentRes, modelComment);
        Long userId = SecurityUtils.getUserId();
        modelComment.setUserId(userId);
        modelCommentMapper.insert(modelComment);


        Long replyUserId = modelCommentRes.getReplyUserId();

        if (Objects.isNull(replyUserId)) {
            return;
        }

        ModelComment mc = modelCommentMapper.selectById(replyUserId);
        if (Objects.isNull(mc)) {
            return;
        }

        if (Objects.equals(userId, mc.getUserId())) {
            return;
        }


        String content = StringUtils.format("{}给您的模型发了一条评论：{}",
                SecurityUtils.getLoginUser().getUser().getNickName(), modelCommentRes.getContent());

        // 向通知表中插入一条记录
        SysAdvice sysAdvice = new SysAdvice();
        sysAdvice.setSenderId(userId);
        sysAdvice.setReceiverId(mc.getUserId());
        sysAdvice.setContent(content);
        sysAdvice.setProductId(modelCommentRes.getModelId());
        sysAdvice.setProductType(0);
        sysAdvice.setIsRead(0);
        sysAdvice.setType(AdviceEnum.COMMENT_REMIND);
        sysAdviceService.save(sysAdvice);


    }

    /**
     * 获取评论
     *
     * @param modelId 模型id
     * @return 评论区
     */
    @Override
    public List<ModelCommentVo> getComment(Long modelId, Integer sortType) {

        // 1. 查询所有父评论
        LambdaQueryWrapper<ModelComment> lqw = new LambdaQueryWrapper<ModelComment>()
                .eq(ModelComment::getModelId, modelId)
                .isNull(ModelComment::getParentId);
        if (sortType == 0) {
            // 按点赞数降序，创建时间升序
            lqw.orderByDesc(ModelComment::getLikeNum)
                    .orderByAsc(ModelComment::getCreateTime);
        } else {
            lqw.orderByDesc(ModelComment::getCreateTime);
        }
        List<ModelComment> parentComments = baseMapper.selectList(lqw);

        // 无评论直接返回空列表
        if (parentComments.isEmpty()) {
            return new ArrayList<>();
        }

        // 2. 收集所有用户ID（父评论+子评论）
        List<Long> userIds = collectUserIds(parentComments); // 收集父评论用户ID
        List<ModelComment> childComments = getChildComments(parentComments); // 查询子评论
        for (ModelComment child : childComments) {
            userIds.add(child.getUserId()); // 收集子评论用户ID
        }

        // 3. 批量查询用户信息（避免N+1查询）
        Map<Long, SysUser> userMap = userIds.isEmpty() ?
                new HashMap<>() :
                sysUserService.listByIds(userIds).stream()
                        .collect(Collectors.toMap(SysUser::getUserId, Function.identity()));

        // 4. 收集所有评论ID（父评论+子评论）
        List<Long> allCommentIds = collectAllCommentIds(parentComments, childComments);

        // 5. 批量查询点赞状态（仅当用户已登录）
        Map<Long, Integer> likeStatusMap = SecurityUtils.getUserIdMax() != 0 ?
                batchGetLikeStatus(allCommentIds, SecurityUtils.getUserIdMax()) :
                new HashMap<>();

        // 6. 构建评论树结构（传递点赞状态）
        return buildCommentTree(parentComments, childComments, userMap, likeStatusMap);
    }

    /**
     * 获取评论总数
     *
     * @param modelId 模型ID
     * @return 评论总数
     */
    @Override
    public Integer getCommentCount(Long modelId) {

        // 获取所模型父评论
        List<ModelComment> modelCommentList = baseMapper.selectList(
                new LambdaQueryWrapper<ModelComment>()
                        .isNull(ModelComment::getParentId)
                        .eq(ModelComment::getModelId, modelId));

        // 获取所有父评论的ID
        List<Long> parentIds = modelCommentList.stream()
                .map(ModelComment::getId)
                .collect(Collectors.toList());

        // 获取所有子评论
        List<ModelComment> childCommentList = new ArrayList<>();
        if (!parentIds.isEmpty()) {
            childCommentList = baseMapper.selectList(new LambdaQueryWrapper<ModelComment>()
                    .in(ModelComment::getParentId, parentIds));
        }


        return parentIds.size() + childCommentList.size();
    }

    /**
     * 收集所有评论ID（父+子）
     */
    private List<Long> collectAllCommentIds(List<ModelComment> parentComments, List<ModelComment> childComments) {
        List<Long> commentIds = new ArrayList<>();
        parentComments.forEach(c -> commentIds.add(c.getId()));
        childComments.forEach(c -> commentIds.add(c.getId()));
        return commentIds;
    }

    private Map<Long, Integer> batchGetLikeStatus(List<Long> commentIds, Long currentUserId) {
        if (commentIds.isEmpty()) {
            return Collections.emptyMap();
        }

        // 批量查询点赞状态
        List<ModelCommentLike> likes = modelCommentLikeService.list(new LambdaQueryWrapper<ModelCommentLike>()
                .eq(ModelCommentLike::getUserId, currentUserId)
                .in(ModelCommentLike::getModelCommentId, commentIds));

        // 构建点赞状态映射
        return likes.stream()
                .collect(Collectors.toMap(ModelCommentLike::getModelCommentId, like -> 1));
    }

    /**
     * 收集父评论的用户ID
     *
     * @param parentComments 父评论列表
     * @return 用户ID集合
     */
    private List<Long> collectUserIds(List<ModelComment> parentComments) {
        List<Long> userIds = new ArrayList<>();
        for (ModelComment comment : parentComments) {
            userIds.add(comment.getUserId());
        }
        return userIds;
    }

    /**
     * 批量查询子评论
     *
     * @param parentComments 父评论列表
     * @return 子评论列表
     */
    private List<ModelComment> getChildComments(List<ModelComment> parentComments) {
        if (parentComments.isEmpty()) {
            return new ArrayList<>();
        }
        // 提取父评论ID集合
        List<Long> parentIds = parentComments.stream()
                .map(ModelComment::getId)
                .collect(Collectors.toList());

        // 查询子评论
        return baseMapper.selectList(
                new LambdaQueryWrapper<ModelComment>()
                        .in(ModelComment::getParentId, parentIds)
                        .orderByAsc(ModelComment::getCreateTime)
        );
    }

    /**
     * 构建树形VO结构
     */
    private List<ModelCommentVo> buildCommentTree(List<ModelComment> parentComments,
                                                  List<ModelComment> childComments,
                                                  Map<Long, SysUser> userMap,
                                                  Map<Long, Integer> likeStatusMap) {
        Map<Long, List<ModelComment>> childMap = new HashMap<>();
        for (ModelComment child : childComments) {
            childMap.computeIfAbsent(child.getParentId(), k -> new ArrayList<>()).add(child);
        }

        List<ModelCommentVo> result = new ArrayList<>();
        for (ModelComment parent : parentComments) {
            ModelCommentVo parentVo = convertToVo(parent, userMap, likeStatusMap);
            List<ModelComment> children = childMap.getOrDefault(parent.getId(), new ArrayList<>());
            List<ModelCommentVo> childVos = new ArrayList<>();
            for (ModelComment child : children) {
                childVos.add(convertToVo(child, userMap, likeStatusMap));
            }
            parentVo.setContentList(childVos);
            result.add(parentVo);
        }
        return result;
    }

    private ModelCommentVo convertToVo(ModelComment comment,
                                       Map<Long, SysUser> userMap,
                                       Map<Long, Integer> likeStatusMap) {
        SysUser user = userMap.get(comment.getUserId());
        if (user == null) {
            user = createDefaultUser();
        }
        ModelCommentVo vo = new ModelCommentVo();
        vo.setUserId(comment.getUserId());
        vo.setUserName(user.getNickName());
        vo.setUserAvatar(user.getAvatar());
        vo.setCommentId(comment.getId());
        vo.setContent(comment.getContent());
        vo.setReplyUserId(comment.getReplyUserId());
        vo.setLikeNum(comment.getLikeNum());
        vo.setIsLike(likeStatusMap.getOrDefault(comment.getId(), 0));
        vo.setCreateTime(comment.getCreateTime());
        return vo;
    }

    /**
     * 创建默认用户（防止空指针）
     */
    private SysUser createDefaultUser() {
        SysUser defaultUser = new SysUser();
        defaultUser.setUserName("匿名用户");
        defaultUser.setAvatar("/default-avatar.png");
        return defaultUser;
    }


}
