package com.wzj.soopin.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.domain.bo.CommentBO;
import com.wzj.soopin.content.domain.po.Comment;
import com.wzj.soopin.content.domain.po.Vlog;
import com.wzj.soopin.content.domain.po.Users;
import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.content.domain.vo.ChildCommentVO;
import com.wzj.soopin.content.domain.vo.CommentVO;
import com.wzj.soopin.content.enums.MessageEnum;
import com.wzj.soopin.content.enums.YesOrNo;
import com.wzj.soopin.content.mapper.CommentMapper;
import com.wzj.soopin.content.mapper.CommentMapperCustom;
import com.wzj.soopin.content.mapper.UsersMapper;
import com.wzj.soopin.member.mapper.MemberMapper;
import com.wzj.soopin.content.mapper.VlogMapper;
import com.wzj.soopin.content.service.CommentService;
import com.wzj.soopin.content.service.MsgService;
import com.wzj.soopin.content.service.VlogService;
import com.wzj.soopin.content.utils.PagedGridResult;
import com.wzj.soopin.content.utils.Sid;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.mq.domain.MQMessage;
import org.dromara.common.mq.enums.MQMessageType;
import org.dromara.common.mq.enums.MessageActionEnum;
import org.dromara.common.mq.utils.MqUtil;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;

import org.dromara.common.redis.redis.RedisCache;
import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@AllArgsConstructor
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    private final CommentMapper commentMapper;
    private final CommentMapperCustom commentMapperCustom;
    private final MsgService msgService;
    private final Sid sid;
    private final MemberMapper memberMapper;
    private final VlogMapper vlogMapper;
    private final RedisCache redisCache;


    @Override
    public TableDataInfo<CommentVO> getCommentList(String vlogId, String mobile, PageQuery pageQuery) {
        // 如果既没有vlogId也没有mobile，返回空结果
        if (!StringUtils.hasText(vlogId) && !StringUtils.hasText(mobile)) {
            Page<CommentVO> emptyPage = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
            emptyPage.setRecords(new ArrayList<>());
            emptyPage.setTotal(0);
            return TableDataInfo.build(emptyPage);
        }

        // 使用自定义SQL查询
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.hasText(vlogId)) {
            params.put("vlogId", vlogId);
        }
        if (StringUtils.hasText(mobile)) {
            params.put("mobile", mobile);
        }

        List<CommentVO> commentList = commentMapperCustom.getCommentList(params);

        // 创建分页对象
        Page<CommentVO> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
        page.setRecords(commentList);
        page.setTotal(commentList.size());

        return TableDataInfo.build(page);
    }

    @Override
    public TableDataInfo<CommentVO> queryVlogComments(String vlogId, String userId, PageQuery pageQuery) {
        // 创建分页对象
        Page<Comment> page = pageQuery.build();

        // 构建查询条件
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Comment::getVlogId, vlogId)
            .orderByDesc(Comment::getCreateTime);

        // 执行分页查询
        Page<Comment> commentPage = commentMapper.selectPage(page, queryWrapper);

        // 转换为CommentVO列表
        List<CommentVO> commentVOList = commentPage.getRecords().stream()
            .map(comment -> {
                CommentVO vo = new CommentVO();
                BeanUtils.copyProperties(comment, vo);
                // 设置额外的VO属性
                vo.setCommentId(comment.getId());
                return vo;
            })
            .collect(Collectors.toList());

        // 创建新的Page对象，包含转换后的VO列表
        Page<CommentVO> voPage = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        voPage.setRecords(commentVOList);

        // 构建并返回TableDataInfo
        return TableDataInfo.build(voPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteComment(String commentId, String username) {
        // 1. 逻辑删除父评论
        Comment comment = commentMapper.selectByCommentId(commentId);
        if (comment == null) {
            throw new RuntimeException("评论不存在");
        }
        comment.setStatus(1);
        comment.setUpdateBy(username);
        commentMapper.updateById(comment);

        // 2. 逻辑删除所有子评论
        List<Comment> childComments = commentMapper.selectByFatherCommentId(commentId);
        for (Comment childComment : childComments) {
            childComment.setStatus(1);
            childComment.setUpdateBy(username);
            commentMapper.updateById(childComment);
        }
    }

    @Override
    public Comment getCommentDetail(String commentId) {
        return commentMapper.selectByCommentId(commentId);
    }

    @Override
    public List<Comment> getChildComments(String fatherCommentId) {
        return commentMapper.selectByFatherCommentId(fatherCommentId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createComment(CommentBO commentBO) {
        String commentId = sid.nextShort();
        Comment comment = new Comment();
        comment.setId(commentId);
        comment.setVlogId(commentBO.getVlogId());
        comment.setVlogerId(commentBO.getVlogerId());
        comment.setCommentUserId(commentBO.getCommentUserId());
        comment.setFatherCommentId(commentBO.getFatherCommentId());
        comment.setContent(commentBO.getContent());
        comment.setLikeCounts(0);
        comment.setCreateTime(LocalDateTime.now());
        commentMapper.insert(comment);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateComment(Comment comment) {
        commentMapper.updateById(comment);
    }

    @Override
    public Page<CommentVO> pageComment(Page<Comment> page, CommentBO bo) {
        // 如果是按点赞数排序，则调用新的Mapper方法进行聚合排序

        LambdaQueryWrapper<Comment> wrapper = bo.toWrapper();
        if (bo.getFatherCommentId() == null) {
            wrapper.eq(Comment::getFatherCommentId, "0");
        }

        // 手机号查视频
        if (bo != null && org.springframework.util.StringUtils.hasText(bo.getMobile())) {
            Member user = memberMapper.selectOne(new LambdaQueryWrapper<Member>().eq(Member::getPhoneHidden, bo.getMobile()));
            if (user == null) {
                Page<CommentVO> emptyPage = new Page<>(page.getCurrent(), page.getSize(), 0);
                emptyPage.setRecords(new ArrayList<>());
                return emptyPage;
            }
            List<Vlog> vlogList = vlogMapper.selectList(new LambdaQueryWrapper<Vlog>().eq(Vlog::getMemberId, user.getId()));
            if (vlogList.isEmpty()) {
                Page<CommentVO> emptyPage = new Page<>(page.getCurrent(), page.getSize(), 0);
                emptyPage.setRecords(new ArrayList<>());
                return emptyPage;
            }
            List<String> vlogIds = vlogList.stream().map(Vlog::getId).collect(Collectors.toList());
            wrapper.in(Comment::getVlogId, vlogIds);
        } else if (bo != null && org.springframework.util.StringUtils.hasText(bo.getVlogId())) {
            wrapper.eq(Comment::getVlogId, bo.getVlogId());
        }

        wrapper.orderByDesc(Comment::getCreateTime);
        Page<Comment> commentPage = commentMapper.selectPage(page, wrapper);

        // 转VO并加子评论数
        Page<CommentVO> voPage = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        List<CommentVO> voList = commentPage.getRecords().stream().map(comment -> {
            CommentVO vo = new CommentVO();
            BeanUtils.copyProperties(comment, vo);
            vo.setCommentId(comment.getId());
            // 查评论用户信息
            Member user = memberMapper.selectById(comment.getCommentUserId());
            if (user != null) {
                vo.setCommentUserFace(user.getAvatar());
                vo.setCommentUserNickname(user.getNickname());
            }
            // 查视频作者手机号和视频播放地址
            Vlog vlog = vlogMapper.selectById(comment.getVlogId());
            if (vlog != null) {
                Member vloger = memberMapper.selectById(vlog.getMemberId());
                if (vloger != null) {
                    vo.setVlogerMobile(vloger.getPhoneHidden());
                }
                vo.setVlogUrl(vlog.getUrl()); // 假设Vlog实体有getUrl()方法
            }
            // 子评论数
            Long childCount = commentMapper.selectCount(
                new LambdaQueryWrapper<Comment>()
                    .eq(Comment::getFatherCommentId, comment.getId())
            );
            vo.setChildCount(Math.toIntExact(childCount));
            return vo;
        }).collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public List<ChildCommentVO> getChildCommentVOs(String fatherCommentId) {
        // 查所有子评论
        List<Comment> childComments = commentMapper.selectByFatherCommentId(fatherCommentId);
        // 查父评论
        Comment fatherComment = commentMapper.selectById(fatherCommentId);
        String replyedUserNickname = null;
        if (fatherComment != null) {
            Member replyedUser = memberMapper.selectById(fatherComment.getCommentUserId());
            if (replyedUser != null) {
                replyedUserNickname = replyedUser.getNickname();
            }
        }
        // 组装VO
        List<ChildCommentVO> voList = new java.util.ArrayList<>();
        for (Comment child : childComments) {
            ChildCommentVO vo = new ChildCommentVO();
            vo.setId(child.getId());
            vo.setCommentId(child.getId());
            vo.setContent(child.getContent());
            vo.setFatherCommentId(child.getFatherCommentId());
            vo.setVlogId(child.getVlogId());
            vo.setCommentUserId(child.getCommentUserId());
            vo.setCreateTime(child.getCreateTime());
            vo.setReplyedUserNickname(replyedUserNickname);
            // 回复人昵称和头像
            Member replyUser = memberMapper.selectById(child.getCommentUserId());
            if (replyUser != null) {
                vo.setReplyUserNickname(replyUser.getNickname());
                vo.setReplyUserFace(replyUser.getAvatar());
            }
            voList.add(vo);
        }
        return voList;
    }

    @Override
    public Page<ChildCommentVO> getChildCommentVOsPaged(String fatherCommentId, long current, long size) {
        Page<Comment> page = new Page<>(current, size);
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getFatherCommentId, fatherCommentId);
        wrapper.orderByAsc(Comment::getCreateTime);

        Page<Comment> commentPage = commentMapper.selectPage(page, wrapper);

        // 查父评论
        Comment fatherComment = commentMapper.selectById(fatherCommentId);
        String replyedUserNickname;
        if (fatherComment != null) {
            Member replyedUser = memberMapper.selectById(fatherComment.getCommentUserId());
            if (replyedUser != null) {
                replyedUserNickname = replyedUser.getNickname();
            } else {
                replyedUserNickname = null;
            }
        } else {
            replyedUserNickname = null;
        }

        // 组装VO
        List<ChildCommentVO> voList = commentPage.getRecords().stream().map(child -> {
            ChildCommentVO vo = new ChildCommentVO();
            vo.setId(child.getId());
            vo.setCommentId(child.getId());
            vo.setContent(child.getContent());
            vo.setFatherCommentId(child.getFatherCommentId());
            vo.setVlogId(child.getVlogId());
            vo.setStatus(child.getStatus());
            vo.setLikeCounts(String.valueOf(child.getLikeCounts()));
            vo.setCommentUserId(child.getCommentUserId());
            vo.setCreateTime(child.getCreateTime());
            vo.setReplyedUserNickname(replyedUserNickname);
            // 回复人昵称和头像
            Member replyUser = memberMapper.selectById(child.getCommentUserId());
            if (replyUser != null) {
                vo.setReplyUserNickname(replyUser.getNickname());
                vo.setReplyUserFace(replyUser.getAvatar());
            }
            return vo;
        }).collect(java.util.stream.Collectors.toList());

        Page<ChildCommentVO> voPage = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void offlineComment(String commentId, String username) {
        // 1. 查父评论
        Comment comment = commentMapper.selectByCommentId(commentId);
        if (comment == null) {
            throw new RuntimeException("评论不存在");
        }
        int newStatus = (comment.getStatus() != null && comment.getStatus() == 2) ? 0 : 2;
        comment.setStatus(newStatus);
        comment.setUpdateBy(username);
        commentMapper.updateById(comment);

        // 2. 查并切换所有子评论
        List<Comment> childComments = commentMapper.selectByFatherCommentId(commentId);
        for (Comment childComment : childComments) {
            childComment.setStatus(newStatus);
            childComment.setUpdateBy(username);
            commentMapper.updateById(childComment);
        }
    }

    @Override
    public void publishComment(CommentBO bo) {
        // 鉴权：评论人从登录上下文获取，覆盖入参
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new RuntimeException("未登录或登录已过期");
        }
        bo.setCommentUserId(String.valueOf(loginUser.getUserId()));

        // 父评论为空时，按根评论处理（约定使用"0"作为无父评论标记）
        if (bo.getFatherCommentId() == null || bo.getFatherCommentId().isEmpty()) {
            bo.setFatherCommentId("0");
        }

        // 1) 创建评论
        this.createComment(bo);

        // 2) 短视频评论总数 +1（Redis 优先）
        redisCache.zSetIncrement(BaseInfoProperties.REDIS_VLOG_COMMENT_COUNTS, bo.getVlogId(), 1);

        Map<String, Object> params = new HashMap<>();
        // 3) 发送站内消息：根评论 -> 通知视频作者；回复评论 -> 通知被回复用户


        // 关注消息
        MqUtil.sendIMMessage(buildMessage(bo));
    }

    private MQMessage buildMessage(CommentBO bo){
        Map<String,Object> params=new HashMap<>();
        LoginUser loginUser=LoginHelper.getLoginUser();
        if ("0".equals(bo.getFatherCommentId())) {
            // 评论视频，通知视频作者
            if (bo.getVlogerId() != null && !bo.getVlogerId().isEmpty()
                && !String.valueOf(loginUser.getUserId()).equals(bo.getVlogerId())) {
                params.put("userId", loginUser.getUserId());
                params.put("nickName", loginUser.getNickname());
                params.put("toUserId", bo.getVlogerId());
                params.put("vlogId", bo.getVlogId());
                params.put("action", MessageActionEnum.INTERACTION_COMMENT.getAccount());
            }

        } else {
            // 回复评论，通知父评论作者
            Comment father = baseMapper.selectById(bo.getFatherCommentId());
            if (father != null && father.getCommentUserId() != null
                && !String.valueOf(loginUser.getUserId()).equals(father.getCommentUserId())) {
                params.put("userId", loginUser.getUserId());
                params.put("nickName", loginUser.getNickname());
                params.put("toUserId", father.getCommentUserId());
                params.put("vlogId", bo.getVlogId());
                params.put("commentId",father.getId());
                params.put("commentContent",father.getContent());
                params.put("action", MessageActionEnum.INTERACTION_REPLY.getAccount());

            }
        }

        MQMessage mqMessage = new MQMessage();
        mqMessage.setTag(MessageActionEnum.NEW_FOUCS.getAccount());
        mqMessage.setData(params);
        return mqMessage;
    }
}
