package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import shop.alien.entity.result.R;
import shop.alien.entity.store.LifeLikeRecord;
import shop.alien.entity.store.StoreStaffComment;
import shop.alien.entity.store.StoreStaffReview;
import shop.alien.entity.store.dto.StoreStaffCommentRequestDto;
import shop.alien.entity.store.dto.StoreStaffReplyDto;
import shop.alien.entity.store.vo.StoreStaffCommentVo;
import shop.alien.mapper.LifeLikeRecordMapper;
import shop.alien.mapper.StoreStaffCommentMapper;
import shop.alien.store.service.StoreStaffCommentService;
import shop.alien.store.service.StoreStaffReviewService;
import shop.alien.store.util.ai.AiContentModerationUtil;
import shop.alien.store.util.StoreLikeRecordIdentityHelper;
import shop.alien.store.util.StoreLikeRecordIdentityHelper.StoreLikerScope;

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

/**
 * 员工评论 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Transactional
@Service
public class StoreStaffCommentServiceImpl extends ServiceImpl<StoreStaffCommentMapper, StoreStaffComment> implements StoreStaffCommentService {

    private static final String LIKE_TYPE_COMMENT = "10"; // 员工评论点赞类型
    private static final int HEAD_TYPE_COMMENT = 0; // 首评类型
    private static final int HEAD_TYPE_REPLY = 1; // 回复类型

    private final StoreStaffCommentMapper storeStaffCommentMapper;
    private final StoreStaffReviewService storeStaffReviewService;
    private final LifeLikeRecordMapper lifeLikeRecordMapper;
    private final AiContentModerationUtil aiContentModerationUtil;
    private final StoreLikeRecordIdentityHelper lifeLikeIdentityHelper;

    public StoreStaffCommentServiceImpl(StoreStaffCommentMapper storeStaffCommentMapper,
                                        @Lazy StoreStaffReviewService storeStaffReviewService,
                                        LifeLikeRecordMapper lifeLikeRecordMapper, AiContentModerationUtil aiContentModerationUtil,
                                        StoreLikeRecordIdentityHelper lifeLikeIdentityHelper) {
        this.storeStaffCommentMapper = storeStaffCommentMapper;
        this.storeStaffReviewService = storeStaffReviewService;
        this.lifeLikeRecordMapper = lifeLikeRecordMapper;
        this.aiContentModerationUtil = aiContentModerationUtil;
        this.lifeLikeIdentityHelper = lifeLikeIdentityHelper;
    }

    @Override
    public R<StoreStaffComment> createComment(StoreStaffComment comment) {
        log.info("创建评论, comment={}", comment);
        
        // 参数校验
        R<String> validateResult = validateComment(comment);
        if (!validateResult.isSuccess()) {
            return R.fail(validateResult.getMsg());
        }

        // 验证评价是否存在且已通过审核（未通过 AI 的评价不允许首评，避免 comment_count 等指标被撬开）
        StoreStaffReview review = storeStaffReviewService.getById(comment.getReviewId());
        if (review == null || review.getDeleteFlag() == 1) {
            return R.fail("评价不存在或已删除");
        }
        if (review.getAuditStatus() == null || review.getAuditStatus() != 1) {
            return R.fail("评价未通过展示审核，暂不能评论");
        }

        // 设置评论属性
        setCommentDefaults(comment, review);
        AiContentModerationUtil.AuditResult auditResult = aiContentModerationUtil.auditContent(comment.getCommentContent(), null);
        if (!auditResult.isPassed()) {
            return R.fail(auditResult.getFailureReason());
        }
        boolean success = this.save(comment);
        if (success) {
            // 更新评价的评论数
            updateReviewCommentCount(review.getId(), 1);
            log.info("创建评论成功, 评论ID={}", comment.getId());
            return R.data(comment, "评论成功");
        } else {
            log.error("创建评论失败");
            return R.fail("创建评论失败");
        }
    }

    @Override
    public R<List<StoreStaffCommentVo>> getCommentListByReviewId(Integer reviewId, Integer currentUserId) {
        log.info("根据评价ID查询评论列表, reviewId={}, currentUserId={}", reviewId, currentUserId);

        if (reviewId == null) {
            return R.fail("评价ID不能为空");
        }

        StoreStaffReview review = storeStaffReviewService.getById(reviewId);
        if (review == null || review.getDeleteFlag() == 1) {
            return R.fail("评价不存在或已删除");
        }
        if (review.getAuditStatus() == null || review.getAuditStatus() != 1) {
            return R.fail("评价不可见");
        }

        List<StoreStaffCommentVo> comments = storeStaffCommentMapper.getCommentListByReviewId(reviewId, currentUserId);

        // 为每个首评加载回复列表
        if (!CollectionUtils.isEmpty(comments)) {
            comments.forEach(comment -> {
                List<StoreStaffCommentVo> replies = storeStaffCommentMapper.getReplyListByHeadId(comment.getId(), currentUserId);
                comment.setReplyList(replies != null ? replies : new java.util.ArrayList<>());
            });
        }

        return R.data(comments);
    }

    @Override
    public R<Boolean> likeComment(StoreStaffCommentRequestDto requestDto) {
        log.info("点赞评论, requestDto={}", requestDto);

        Integer commentId = requestDto.getCommentId();
        Integer userId = requestDto.getUserId();

        if (commentId == null) {
            return R.fail("评论ID不能为空");
        }
        if (userId == null) {
            return R.fail("用户ID不能为空");
        }

        // 验证评论是否存在
        StoreStaffComment comment = this.getById(commentId);
        if (comment == null || comment.getDeleteFlag() == 1) {
            return R.fail("评论不存在或已删除");
        }

        // 检查是否已点赞
        if (isLiked(commentId, userId, LIKE_TYPE_COMMENT)) {
            return R.data(true, "已点赞");
        }

        // 执行点赞
        return doLikeComment(commentId, userId);
    }

    @Override
    public R<Boolean> cancelLikeComment(StoreStaffCommentRequestDto requestDto) {
        log.info("取消点赞评论, requestDto={}", requestDto);

        Integer commentId = requestDto.getCommentId();
        Integer userId = requestDto.getUserId();
        
        if (commentId == null) {
            return R.fail("评论ID不能为空");
        }
        if (userId == null) {
            return R.fail("用户ID不能为空");
        }

        // 执行取消点赞
        return doCancelLikeComment(commentId, userId);
    }

    @Override
    public R<StoreStaffComment> createReply(StoreStaffReplyDto replyDto) {
        log.info("创建回复, replyDto={}", replyDto);

        // 参数校验
        R<String> validateResult = validateReplyDto(replyDto);
        if (!validateResult.isSuccess()) {
            return R.fail(validateResult.getMsg());
        }

        // 验证首评是否存在
        StoreStaffComment headComment = this.getById(replyDto.getCommentId());
        if (headComment == null || headComment.getDeleteFlag() == 1) {
            return R.fail("评论不存在或已删除");
        }
        if (headComment.getHeadType() != HEAD_TYPE_COMMENT) {
            return R.fail("只能回复首评");
        }

        StoreStaffReview parentReview = storeStaffReviewService.getById(headComment.getReviewId());
        if (parentReview == null || parentReview.getDeleteFlag() == 1) {
            return R.fail("评价不存在或已删除");
        }
        if (parentReview.getAuditStatus() == null || parentReview.getAuditStatus() != 1) {
            return R.fail("评价未通过展示审核，暂不能回复");
        }

        // 构建回复对象
        StoreStaffComment reply = buildReplyFromDto(replyDto, headComment);

        boolean success = this.save(reply);
        if (success) {
            // 更新首评的回复数
            updateHeadCommentReplyCount(headComment.getId(), 1);
            // 更新评价的评论数
            updateReviewCommentCount(reply.getReviewId(), 1);
            log.info("创建回复成功, 回复ID={}", reply.getId());
            return R.data(reply, "回复成功");
        } else {
            log.error("创建回复失败");
            return R.fail("创建回复失败");
        }
    }

    @Override
    public R<List<StoreStaffCommentVo>> getReplyListByHeadId(Integer headId, Integer currentUserId) {
        log.info("根据首评ID查询回复列表, headId={}, currentUserId={}", headId, currentUserId);

        if (headId == null) {
            return R.fail("首评ID不能为空");
        }

        List<StoreStaffCommentVo> replies = storeStaffCommentMapper.getReplyListByHeadId(headId, currentUserId);
        return R.data(replies);
    }

    @Override
    public R<Boolean> deleteReply(Integer replyId, Integer userId) {
        log.info("删除回复, replyId={}, userId={}", replyId, userId);

        if (replyId == null) {
            return R.fail("回复ID不能为空");
        }
        if (userId == null) {
            return R.fail("用户ID不能为空");
        }

        // 查询回复
        StoreStaffComment reply = this.getById(replyId);
        if (reply == null) {
            return R.fail("回复不存在");
        }
        if (reply.getHeadType() != HEAD_TYPE_REPLY) {
            return R.fail("该记录不是回复");
        }

        // 验证是否为回复用户
        if (!reply.getSendUserId().equals(userId)) {
            return R.fail("只能删除自己的回复");
        }

        // 删除回复（逻辑删除）
        boolean success = this.removeById(reply.getId());

        if (success) {
            // 更新首评的回复数
            updateHeadCommentReplyCount(reply.getHeadId(), -1);
            // 更新评价的评论数
            updateReviewCommentCount(reply.getReviewId(), -1);
            log.info("删除回复成功, replyId={}", replyId);
            return R.data(true, "删除成功");
        } else {
            log.error("删除回复失败, replyId={}", replyId);
            return R.fail("删除回复失败");
        }
    }

    @Override
    public R<Boolean> deleteReviewComment(StoreStaffComment comment) {
        Integer id = comment.getId();
        Integer userId = comment.getUserId();
        log.info("删除评论, id={}, userId={}", id, userId);
        
        if (id == null) {
            return R.fail("评论ID不能为空");
        }

        // 查询评论
        StoreStaffComment commentEntity = this.getById(id);
        if (commentEntity == null) {
            return R.fail("评论不存在");
        }

        // 当userId有值时，验证是否为评论用户
        if (userId != null && !commentEntity.getSendUserId().equals(userId)) {
            return R.fail("只能删除自己的评论");
        }

        // 计算需要减少的评论数
        int commentCountToReduce = 1;

        // 判断是否为首评论
        if (commentEntity.getHeadType() != null && commentEntity.getHeadType() == HEAD_TYPE_COMMENT) {
            // 如果是首评论，需要先删除所有子评论
            LambdaQueryWrapper<StoreStaffComment> childQueryWrapper = new LambdaQueryWrapper<>();
            childQueryWrapper.eq(StoreStaffComment::getHeadId, id)
                    .eq(StoreStaffComment::getHeadType, HEAD_TYPE_REPLY)
                    .eq(StoreStaffComment::getDeleteFlag, 0);
            List<StoreStaffComment> childComments = this.list(childQueryWrapper);

            if (!CollectionUtils.isEmpty(childComments)) {
                List<Integer> childIds = childComments.stream()
                        .map(StoreStaffComment::getId)
                        .collect(Collectors.toList());
                boolean deleteChildrenResult = this.removeByIds(childIds);
                if (!deleteChildrenResult) {
                    log.warn("删除子评论失败, 首评论ID={}, 子评论数量={}", id, childIds.size());
                    return R.fail("删除子评论失败");
                }
                commentCountToReduce += childComments.size();
            }
        }

        // 删除评论本身
        boolean result = this.removeById(id);
        if (result) {
            // 更新评价的评论数
            updateReviewCommentCount(commentEntity.getReviewId(), -commentCountToReduce);
            
            if (userId != null) {
                log.info("用户删除评论成功, 评论ID={}, userId={}", id, userId);
            } else {
                log.info("管理员删除评论成功, 评论ID={}", id);
            }
            return R.success("删除成功");
        }
        return R.fail("删除失败");
    }

    /**
     * 校验评论参数
     */
    private R<String> validateComment(StoreStaffComment comment) {
        if (comment == null) {
            return R.fail("评论信息不能为空");
        }
        if (comment.getReviewId() == null) {
            return R.fail("评价ID不能为空");
        }
        if (!StringUtils.hasText(comment.getCommentContent())) {
            return R.fail("评论内容不能为空");
        }
        if (comment.getSendUserId() == null) {
            return R.fail("用户ID不能为空");
        }
        if (comment.getSendUserType() == null) {
            return R.fail("发送用户类型不能为空");
        }
        if (comment.getReceiveUserType() == null) {
            return R.fail("接收用户类型不能为空");
        }
        return R.success("校验评论参数成功");
    }

    /**
     * 校验回复DTO参数
     */
    private R<String> validateReplyDto(StoreStaffReplyDto replyDto) {
        if (replyDto == null) {
            return R.fail("回复信息不能为空");
        }
        if (replyDto.getCommentId() == null) {
            return R.fail("评论ID不能为空");
        }
        if (!StringUtils.hasText(replyDto.getReplyContent())) {
            return R.fail("回复内容不能为空");
        }
        if (replyDto.getUserId() == null) {
            return R.fail("用户ID不能为空");
        }
        return R.success("校验评论参数成功");
    }

    /**
     * 设置评论默认值
     */
    private void setCommentDefaults(StoreStaffComment comment, StoreStaffReview review) {
        if (comment.getReceiveUserId() == null) {
            comment.setReceiveUserId(review.getUserId());
        }
        if (comment.getLikeCount() == null) {
            comment.setLikeCount(0);
        }
        if (comment.getReplyCount() == null) {
            comment.setReplyCount(0);
        }
        if (comment.getHeadType() == null) {
            comment.setHeadType(HEAD_TYPE_COMMENT);
        }
        comment.setCreatedUserId(comment.getSendUserId());
        comment.setCreatedTime(new Date());
    }

    /**
     * 构建回复对象
     */
    private StoreStaffComment buildReplyFromDto(StoreStaffReplyDto replyDto, StoreStaffComment headComment) {
        StoreStaffComment reply = new StoreStaffComment();
        reply.setReviewId(headComment.getReviewId());
        reply.setSendUserId(replyDto.getUserId());
        
        Integer receiveUserId = replyDto.getReplyToUserId() != null 
                ? replyDto.getReplyToUserId() 
                : headComment.getSendUserId();
        reply.setReceiveUserId(receiveUserId);
        
        // 处理用户类型
        Integer sendUserType = replyDto.getSendUserType();
        if (sendUserType == null) {
            sendUserType = headComment.getReceiveUserType();
        }
        if (sendUserType == null) {
            throw new IllegalArgumentException("发送用户类型不能为空");
        }
        
        Integer receiveUserType = replyDto.getReceiveUserType();
        if (receiveUserType == null) {
            receiveUserType = headComment.getSendUserType();
        }
        if (receiveUserType == null) {
            throw new IllegalArgumentException("接收用户类型不能为空");
        }
        
        reply.setSendUserType(sendUserType);
        reply.setReceiveUserType(receiveUserType);
        reply.setCommentContent(replyDto.getReplyContent());
        reply.setLikeCount(0);
        reply.setReplyCount(0);
        reply.setHeadType(HEAD_TYPE_REPLY);
        reply.setHeadId(replyDto.getCommentId());
        reply.setCreatedUserId(replyDto.getUserId());
        reply.setCreatedTime(new Date());
        
        return reply;
    }

    /**
     * 检查是否已点赞
     */
    private boolean isLiked(Integer commentId, Integer userId, String type) {
        StoreLikerScope likerScope = lifeLikeIdentityHelper.fromLifeUserId(userId);
        LambdaQueryWrapper<LifeLikeRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LifeLikeRecord::getType, type)
                .eq(LifeLikeRecord::getHuifuId, String.valueOf(commentId))
                .eq(LifeLikeRecord::getDeleteFlag, 0);
        lifeLikeIdentityHelper.applyLikerFilter(queryWrapper, likerScope);
        List<LifeLikeRecord> records = lifeLikeRecordMapper.selectList(queryWrapper);
        return !CollectionUtils.isEmpty(records);
    }

    /**
     * 执行点赞评论
     */
    private R<Boolean> doLikeComment(Integer commentId, Integer userId) {
        try {
            // 插入点赞记录
            LifeLikeRecord likeRecord = new LifeLikeRecord();
            likeRecord.setDianzanId(String.valueOf(userId));
            lifeLikeIdentityHelper.normalizeBeforeSave(likeRecord);
            likeRecord.setHuifuId(String.valueOf(commentId));
            likeRecord.setType(LIKE_TYPE_COMMENT);
            likeRecord.setCreatedTime(new Date());
            likeRecord.setCreatedUserId(userId);
            lifeLikeRecordMapper.insert(likeRecord);

            // 更新评论点赞数
            LambdaUpdateWrapper<StoreStaffComment> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(StoreStaffComment::getId, commentId);
            updateWrapper.setSql("like_count = like_count + 1");
            int result = storeStaffCommentMapper.update(null, updateWrapper);

            if (result > 0) {
                log.info("点赞评论成功, commentId={}", commentId);
                return R.data(true, "点赞成功");
            } else {
                return R.fail("点赞失败");
            }
        } catch (Exception e) {
            log.error("点赞评论异常, commentId={}, userId={}, error={}", commentId, userId, e.getMessage(), e);
            return R.fail("点赞失败");
        }
    }

    /**
     * 执行取消点赞评论
     */
    private R<Boolean> doCancelLikeComment(Integer commentId, Integer userId) {
        try {
            // 查询点赞记录
            StoreLikerScope likerScope = lifeLikeIdentityHelper.fromLifeUserId(userId);
            LambdaQueryWrapper<LifeLikeRecord> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LifeLikeRecord::getType, LIKE_TYPE_COMMENT)
                    .eq(LifeLikeRecord::getHuifuId, String.valueOf(commentId))
                    .eq(LifeLikeRecord::getDeleteFlag, 0);
            lifeLikeIdentityHelper.applyLikerFilter(queryWrapper, likerScope);
            List<LifeLikeRecord> records = lifeLikeRecordMapper.selectList(queryWrapper);

            if (CollectionUtils.isEmpty(records)) {
                return R.data(true, "未点赞");
            }

            // 删除点赞记录（逻辑删除）
            records.forEach(record -> lifeLikeRecordMapper.deleteById(record.getId()));

            // 更新评论点赞数
            LambdaUpdateWrapper<StoreStaffComment> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(StoreStaffComment::getId, commentId);
            updateWrapper.setSql("like_count = GREATEST(0, like_count - 1)");
            int result = storeStaffCommentMapper.update(null, updateWrapper);

            if (result > 0) {
                log.info("取消点赞评论成功, commentId={}", commentId);
                return R.data(true, "取消点赞成功");
            } else {
                return R.fail("取消点赞失败");
            }
        } catch (Exception e) {
            log.error("取消点赞评论异常, commentId={}, userId={}, error={}", commentId, userId, e.getMessage(), e);
            return R.fail("取消点赞失败");
        }
    }

    /**
     * 更新首评的回复数
     */
    private void updateHeadCommentReplyCount(Integer headId, int delta) {
        StoreStaffComment headComment = this.getById(headId);
        if (headComment != null) {
            Integer currentCount = headComment.getReplyCount() == null ? 0 : headComment.getReplyCount();
            headComment.setReplyCount(Math.max(0, currentCount + delta));
            this.updateById(headComment);
        }
    }

    /**
     * 更新评价的评论数
     */
    private void updateReviewCommentCount(Integer reviewId, int delta) {
        StoreStaffReview review = storeStaffReviewService.getById(reviewId);
        if (review != null) {
            Integer currentCount = review.getCommentCount() == null ? 0 : review.getCommentCount();
            review.setCommentCount(Math.max(0, currentCount + delta));
            storeStaffReviewService.updateById(review);
            log.debug("更新评价评论数, reviewId={}, delta={}, 当前评论数={}", reviewId, delta, review.getCommentCount());
        }
    }
}
