package cn.meowrain.aioj.backend.blogservice.service.impl;

import cn.meowrain.aioj.backend.blogservice.dao.entity.Article;
import cn.meowrain.aioj.backend.blogservice.dao.entity.Comment;
import cn.meowrain.aioj.backend.blogservice.dao.mapper.ArticleMapper;
import cn.meowrain.aioj.backend.blogservice.dao.mapper.CommentMapper;
import cn.meowrain.aioj.backend.blogservice.dto.req.CommentCreateRequestDTO;
import cn.meowrain.aioj.backend.blogservice.dto.req.CommentQueryRequestDTO;
import cn.meowrain.aioj.backend.blogservice.dto.resp.CommentResponseDTO;
import cn.meowrain.aioj.backend.blogservice.service.ArticleService;
import cn.meowrain.aioj.backend.blogservice.service.CommentService;
import cn.meowrain.aioj.backend.framework.core.exception.ClientException;
import cn.meowrain.aioj.backend.framework.core.utils.ContextHolderUtils;
import cn.hutool.core.bean.BeanUtil;
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 评论服务实现类
 *
 * @author AIOJ
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    private final ArticleMapper articleMapper;
    private final ArticleService articleService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createComment(CommentCreateRequestDTO request) {
        Long currentUserId = ContextHolderUtils.getCurrentUserId();

        // 检查文章是否存在
        Article article = articleMapper.selectById(request.getArticleId());
        if (article == null) {
            throw new ClientException("文章不存在");
        }

        Comment comment = new Comment()
                .setArticleId(request.getArticleId())
                .setUserId(currentUserId)
                .setParentId(request.getParentId() != null ? request.getParentId() : 0L)
                .setReplyToId(request.getReplyToId() != null ? request.getReplyToId() : 0L)
                .setContent(request.getContent())
                .setLikeCount(0)
                .setReplyCount(0)
                .setIsAuthor(article.getAuthorId().equals(currentUserId) ? 1 : 0)
                .setStatus(1);

        this.save(comment);

        // 更新文章评论数
        article.setCommentCount(article.getCommentCount() + 1);
        articleMapper.updateById(article);

        return comment.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long replyComment(CommentCreateRequestDTO request) {
        return createComment(request);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteComment(Long commentId) {
        Long currentUserId = ContextHolderUtils.getCurrentUserId();

        Comment comment = this.getById(commentId);
        if (comment == null) {
            throw new ClientException("评论不存在");
        }

        if (!comment.getUserId().equals(currentUserId)) {
            throw new ClientException("无权删除此评论");
        }

        // 逻辑删除
        comment.setStatus(3);
        this.updateById(comment);

        // 更新文章评论数
        Article article = articleMapper.selectById(comment.getArticleId());
        if (article != null && article.getCommentCount() > 0) {
            article.setCommentCount(article.getCommentCount() - 1);
            articleMapper.updateById(article);
        }

        return true;
    }

    @Override
    public CommentResponseDTO getCommentById(Long commentId) {
        Comment comment = this.getById(commentId);
        if (comment == null) {
            return null;
        }
        return convertToResponseDTO(comment);
    }

    @Override
    public List<CommentResponseDTO> getCommentsByArticleId(Long articleId) {
        List<Comment> comments = this.lambdaQuery()
                .eq(Comment::getArticleId, articleId)
                .eq(Comment::getParentId, 0)
                .eq(Comment::getStatus, 1)
                .orderByDesc(Comment::getCreateTime)
                .list();

        return comments.stream()
                .map(this::convertToResponseDTO)
                .collect(Collectors.toList());
    }

    @Override
    public IPage<CommentResponseDTO> getCommentList(CommentQueryRequestDTO request) {
        Page<Comment> page = new Page<>(request.getCurrent(), request.getSize());

        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();

        if (request.getArticleId() != null) {
            queryWrapper.eq(Comment::getArticleId, request.getArticleId());
        }
        if (request.getUserId() != null) {
            queryWrapper.eq(Comment::getUserId, request.getUserId());
        }
        if (request.getParentId() != null) {
            queryWrapper.eq(Comment::getParentId, request.getParentId());
        }
        if (request.getStatus() != null) {
            queryWrapper.eq(Comment::getStatus, request.getStatus());
        } else {
            queryWrapper.eq(Comment::getStatus, 1);
        }

        queryWrapper.orderByDesc(Comment::getCreateTime);

        IPage<Comment> commentPage = this.page(page, queryWrapper);

        Page<CommentResponseDTO> resultPage = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        List<CommentResponseDTO> records = commentPage.getRecords().stream()
                .map(this::convertToResponseDTO)
                .collect(Collectors.toList());
        resultPage.setRecords(records);

        return resultPage;
    }

    @Override
    public List<CommentResponseDTO> getChildComments(Long parentId) {
        List<Comment> comments = this.lambdaQuery()
                .eq(Comment::getParentId, parentId)
                .eq(Comment::getStatus, 1)
                .orderByDesc(Comment::getCreateTime)
                .list();

        return comments.stream()
                .map(this::convertToResponseDTO)
                .collect(Collectors.toList());
    }

    private CommentResponseDTO convertToResponseDTO(Comment comment) {
        CommentResponseDTO dto = BeanUtil.copyProperties(comment, CommentResponseDTO.class);
        // TODO: 查询用户信息、回复用户信息、子评论列表、点赞状态
        dto.setUserName("User" + comment.getUserId());
        dto.setUserAvatar("");
        dto.setChildren(getChildComments(comment.getId()));
        return dto;
    }
}
