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.core.domain.entity.SysUser;
import com.mcwl.common.utils.SecurityUtils;
import com.mcwl.common.utils.StringUtils;
import com.mcwl.resource.domain.*;
import com.mcwl.resource.domain.dto.ModelImageCommentRes;
import com.mcwl.resource.domain.vo.ModelImageCommentVo;
import com.mcwl.resource.mapper.ModelImageCommentMapper;
import com.mcwl.resource.service.ISysAdviceService;
import com.mcwl.resource.service.ModelImageCommentLikeService;
import com.mcwl.resource.service.ModelImageCommentService;
import com.mcwl.system.domain.enums.AdviceEnum;
import com.mcwl.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
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
@RequiredArgsConstructor
public class ModelImageCommentServiceImpl extends ServiceImpl<ModelImageCommentMapper, ModelImageComment> implements ModelImageCommentService {

    private final ISysUserService sysUserService;

    private final ModelImageCommentLikeService modelImageCommentLikeService;

    private final ISysAdviceService sysAdviceService;

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

        if (Objects.nonNull(parentId)) {
            ModelImageComment mic = baseMapper.selectById(parentId);
            if (Objects.isNull(mic)) {
                return;
            }
        }

        ModelImageComment modelImageComment = new ModelImageComment();
        BeanUtil.copyProperties(modelImageCommentRes, modelImageComment);
        Long userId = SecurityUtils.getUserId();
        modelImageComment.setUserId(userId);
        baseMapper.insert(modelImageComment);


        Long replyUserId = modelImageCommentRes.getReplyUserId();

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

        ModelImageComment mic = baseMapper.selectById(replyUserId);
        if (Objects.isNull(mic)) {
            return;
        }

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


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

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


    }

    /**
     * 获取评论
     *
     * @param imageId 图片id
     * @return 评论区
     */
    @Override
    public List<ModelImageCommentVo> getComment(Long imageId, Integer sortType) {
        // 1. 查询所有父评论
        LambdaQueryWrapper<ModelImageComment> lqw = new LambdaQueryWrapper<ModelImageComment>()
                .eq(ModelImageComment::getModelImageId, imageId)
                .isNull(ModelImageComment::getParentId);
        if (sortType == 0) {
            // 按点赞数降序，创建时间升序
            lqw.orderByDesc(ModelImageComment::getLikeNum)
                    .orderByAsc(ModelImageComment::getCreateTime);
        } else {
            lqw.orderByDesc(ModelImageComment::getCreateTime);
        }
        List<ModelImageComment> parentComments = baseMapper.selectList(lqw);

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

        // 2. 收集所有用户ID（父评论+子评论）
        List<Long> userIds = collectUserIds(parentComments); // 收集父评论用户ID
        List<ModelImageComment> childComments = getChildComments(parentComments); // 查询子评论
        for (ModelImageComment 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);

    }

    @Override
    public Integer getCommentCount(Long imageId) {

        // 获取所有图片父评论
        List<ModelImageComment> modelImageCommentList = baseMapper.selectList(
                new LambdaQueryWrapper<ModelImageComment>()
                        .isNull(ModelImageComment::getParentId)
                        .eq(ModelImageComment::getModelImageId, imageId));

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

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


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


    /**
     * 收集所有评论ID（父+子）
     */
    private List<Long> collectAllCommentIds(List<ModelImageComment> parentComments, List<ModelImageComment> 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<ModelImageCommentLike> likes = modelImageCommentLikeService.list(new LambdaQueryWrapper<ModelImageCommentLike>()
                .eq(ModelImageCommentLike::getUserId, currentUserId)
                .in(ModelImageCommentLike::getModelImageCommentId, commentIds));

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

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

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

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

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

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

    /**
     * 转换单个评论为VO对象
     */
    private ModelImageCommentVo convertToVo(ModelImageComment comment,
                                            Map<Long, SysUser> userMap,
                                            Map<Long, Integer> likeStatusMap) {
        SysUser user = userMap.get(comment.getUserId());
        if (user == null) {
            user = createDefaultUser(); // 处理用户信息缺失
        }

        ModelImageCommentVo vo = new ModelImageCommentVo();
        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;
    }


}
