package shop.alien.lawyer.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;
import shop.alien.entity.result.R;
import shop.alien.entity.store.*;
import shop.alien.entity.store.dto.OrderReviewDto;
import shop.alien.entity.store.dto.ReviewCommentRequestDto;
import shop.alien.entity.store.dto.ReviewReplyDto;
import shop.alien.entity.store.vo.*;
import shop.alien.lawyer.config.WebSocketProcess;
import shop.alien.lawyer.service.StoreCommentService;
import shop.alien.lawyer.service.StoreImgService;
import shop.alien.lawyer.util.FileUploadUtil;
import shop.alien.mapper.*;
import shop.alien.util.common.DateUtils;
import shop.alien.util.common.netease.ImageCheckUtil;
import shop.alien.util.common.netease.TextCheckUtil;
import shop.alien.util.common.safe.TextModerationResultVO;
import shop.alien.util.common.safe.TextModerationUtil;
import shop.alien.util.common.safe.TextReviewServiceEnum;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 评论表 服务实现类
 *
 * @author ssk
 * @since 2025-01-02
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StoreCommentServiceImpl extends ServiceImpl<StoreCommentMapper, StoreComment> implements StoreCommentService {

    private final StoreCommentMapper storeCommentMapper;

    private final LifeLikeRecordMapper lifeLikeRecordMapper;

    private final FileUploadUtil fileUploadUtil;

    private final StoreImgMapper storeImgMapper;

    private final LifeUserViolationMapper lifeUserViolationMapper;

    private final StoreUserMapper storeUserMapper;

    private final LifeUserMapper lifeUserMapper;

    private final StoreCommentAppealMapper storeCommentAppealMapper;

    private final StoreInfoMapper storeInfoMapper;

    private final LifeNoticeMapper lifeNoticeMapper;

    private final WebSocketProcess webSocketProcess;

    private final TagsSynonymMapper tagsSynonymMapper;

    private final LifeUserOrderMapper lifeUserOrderMapper;

    private final LawyerConsultationOrderMapper lawyerConsultationOrderMapper;
    private final LawyerUserMapper lawyerUserMapper;
    private final LawFirmMapper lawFirmMapper;

    @Autowired
    private TextModerationUtil textModerationUtil;
    @Autowired
    private StoreImgService storeImgService;

    /**
     * 评论列表
     *
     * @param pageNum      页数
     * @param pageSize     页容
     * @param businessId   业务id
     * @param businessType 业务类型(1:订单评论, 2:动态社区评论, 3:活动评论, 4:店铺打卡评论, 5:订单评价, 6:订单评论的评论)
     * @param storeId      门店id
     * @param replyStatus  回复状态(0:全部, 1:已回复, 2:未回复)
     * @param commentLevel 评论等级(0:全部, 1:好评, 2:中评, 3:差评)
     * @param days         查询时间, 多少天前
     * @param phoneId      消息标识
     * @param userType     评论的用户类型(0:商家, 其他:用户)
     * @param tagId        标签id
     * @param hasImage     是否有图片(0否/1是)
     * @return IPage<StoreComment>
     */
    @Override
    public IPage<StoreCommentVo> getList(Integer pageNum, Integer pageSize, Integer businessId, Integer businessType, Integer storeId, Integer replyStatus, Integer commentLevel, Integer days, String phoneId, Integer userType, Integer tagId, Boolean hasImage) {
        IPage<StoreCommentVo> storeCommentIPage = new Page<>(pageNum, pageSize);
        QueryWrapper<StoreCommentVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(null != businessId, "a.business_id", businessId);
        queryWrapper.eq(null != businessType, "a.business_type", businessType);
        queryWrapper.eq(null != storeId, "a.store_id", storeId);
        //好评 a>=4
        queryWrapper.ge(null != commentLevel && 1 == commentLevel, "a.score", 4.5);
        //中评 a>=2&& a<4
        queryWrapper.ge(null != commentLevel && 2 == commentLevel, "a.score", 3).le(null != commentLevel && 2 == commentLevel, "a.score", 4);
        //差评 a<2
        queryWrapper.ge(null != commentLevel && 3 == commentLevel, "a.score", 0.5).le(null != commentLevel && 3 == commentLevel, "a.score", 2.5);
        if (null != days) {
            Date date = DateUtils.calcDays(new Date(), -days);
            queryWrapper.ge("a.created_time", DateUtils.formatDate(date, "yyyy-MM-dd"));
        }
        //通过当前登录人id 类型 查询举报业务id
        List<LifeUserViolation> lifeUserViolations = new ArrayList<>();
        if(businessType==2){
            String userId;
            if(phoneId.startsWith("store_")){
                userId = phoneId.substring("store_".length());
                StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getPhone,userId));
                if(storeUser!=null){
                    LambdaQueryWrapper<LifeUserViolation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(LifeUserViolation::getReportingUserId,storeUser.getId());
                    lambdaQueryWrapper.eq(LifeUserViolation::getReportingUserType,1);
                    lambdaQueryWrapper.ne(LifeUserViolation::getProcessingStatus,2);
                    lifeUserViolations = lifeUserViolationMapper.selectList(lambdaQueryWrapper);
                }
            }else{
                userId = phoneId.substring("user_".length());
                LifeUser lifeUser = lifeUserMapper.selectOne(new LambdaQueryWrapper<LifeUser>().eq(LifeUser::getUserPhone,userId));
                if(lifeUser!=null){
                    LambdaQueryWrapper<LifeUserViolation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(LifeUserViolation::getReportingUserId,lifeUser.getId());
                    lambdaQueryWrapper.eq(LifeUserViolation::getReportingUserType,2);
                    lambdaQueryWrapper.ne(LifeUserViolation::getProcessingStatus,2);
                    lifeUserViolations = lifeUserViolationMapper.selectList(lambdaQueryWrapper);
                }
            }
        }
        List<Integer> businessIds = lifeUserViolations.stream()
                .filter(Objects::nonNull)
                .map(LifeUserViolation::getBusinessId)
                .filter(id -> id != null && !id.toString().isEmpty())
                .collect(Collectors.toList());
        if(businessIds!=null && businessIds.size()>0){
            queryWrapper.notIn("a.id",businessIds);
        }

        //根据标签id查询表签字表拿到评论ids
        if(tagId !=null){
            List<TagsSynonym> tagsSynonymList = tagsSynonymMapper.selectList(new LambdaQueryWrapper<TagsSynonym>().eq(TagsSynonym::getMainTagId,tagId));
            if(CollectionUtils.isNotEmpty(tagsSynonymList)){
                List<Integer> commentIdList = tagsSynonymList.stream().filter(synonym -> synonym != null)
                        .map(TagsSynonym::getCommentId).filter(commentId -> commentId != null).collect(Collectors.toList());
                queryWrapper.in("a.id",commentIdList);
            }
        }

        //先查询父级评论
        queryWrapper.isNull(businessType != 1, "a.reply_id").eq("a.delete_flag", 0).orderByDesc("a.created_time");
        IPage<StoreCommentVo> page = storeCommentMapper.getCommentPage(storeCommentIPage, queryWrapper);
        List<StoreCommentVo> records = page.getRecords();
        List<StoreCommentVo> storeCommentVoList = new ArrayList<>();

        //评价图片
        Set<Integer> imgIdList = new HashSet<>();
        for (int i = 0; i < records.size(); i++) {
            StoreCommentVo storeCommentVo = new StoreCommentVo();
            BeanUtils.copyProperties(records.get(i), storeCommentVo);
            //首评
            storeCommentVo.setFirstComment(i == 0);
            //有无图片
            if (records.get(i).getImgId() != null) {
                storeCommentVo.setHasImage(true);
                String[] split = records.get(i).getImgId().split(",");
                for (String s : split) {
                    imgIdList.add(Integer.parseInt(s));
                }
            } else {
                storeCommentVo.setHasImage(false);
            }
            //低分
            storeCommentVo.setLowScore(records.get(i).getScore() <= 1);

            QueryWrapper<StoreCommentAppealVo> storeCommentAppealVoQueryWrapper = new QueryWrapper<>();
            storeCommentAppealVoQueryWrapper.eq("a.comment_id", storeCommentVo.getId()).eq("a.delete_flag", 0).orderByDesc("a.created_time").last("limit 1");
            StoreCommentAppealVo commentDetail = storeCommentAppealMapper.getCommentDetail(storeCommentAppealVoQueryWrapper);
            if (ObjectUtils.isNotEmpty(commentDetail)) {
                storeCommentVo.setAppealFlag(1);
                storeCommentVo.setAppealStatusStr(commentDetail.getAppealStatusStr());
                storeCommentVo.setAppealStatus(commentDetail.getAppealStatus());
            }else {
                storeCommentVo.setAppealFlag(0);
            }

            //商家用户
            if (StringUtils.isNotEmpty(records.get(i).getPhoneId())) {
                if (records.get(i).getPhoneId().contains("store_")) {
                    storeCommentVo.setStoreUserFlag(0);
                    StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getStoreId, records.get(i).getStoreId()));
                    storeCommentVo.setStoreUserName(storeUser.getName());
                    storeCommentVo.setStoreUserImg(storeUser.getHeadImg());
                } else {
                    storeCommentVo.setStoreUserFlag(1);
                }
            }
            StoreInfo storeInfo = storeInfoMapper.selectById(records.get(i).getStoreId());
            if (storeInfo != null) {
                storeCommentVo.setStoreName(storeInfo.getStoreName());
            }
            storeCommentVoList.add(storeCommentVo);
        }

        //塞图片
        if (!imgIdList.isEmpty()) {
            List<StoreImg> storeImgList = storeImgMapper.selectList(new QueryWrapper<StoreImg>().in("id", imgIdList));

            storeCommentVoList.forEach(storeCommentVo -> {
                if (null != storeCommentVo.getImgId()) {
                    storeCommentVo.setImgUrl(new ArrayList<>());
                    for (StoreImg storeImg : storeImgList) {
                        for (String s : storeCommentVo.getImgId().split(",")) {
                            if (storeImg.getId().equals(Integer.parseInt(s))) {
                                storeCommentVo.getImgUrl().add(storeImg.getImgUrl());
                            }
                        }
                    }
                }
            });
        }

        //父级评论下拼接子评论
        for (StoreCommentVo storeCommentVo : storeCommentVoList) {
            storeCommentVo.setCommitCount(0);
            //父级点赞状态
            if (StringUtils.isNotEmpty(phoneId)) {
                LambdaQueryWrapper<LifeLikeRecord> likeRecordQueryWrapper = new LambdaQueryWrapper<>();
                likeRecordQueryWrapper.eq(LifeLikeRecord::getDianzanId, phoneId).eq(LifeLikeRecord::getHuifuId, storeCommentVo.getId());
                Integer i = lifeLikeRecordMapper.selectCount(likeRecordQueryWrapper);
                if (i > 0) {
                    storeCommentVo.setIsLike(1);
                } else {
                    storeCommentVo.setIsLike(0);
                }
            }
            QueryWrapper<StoreCommentVo> childQueryWrapper = new QueryWrapper<>();
            if(businessIds!=null && businessIds.size()>0){
                childQueryWrapper.notIn("a.id",businessIds);
            }
            childQueryWrapper.eq(null != businessId && 6 == businessId, "a.business_id", businessId).eq("a.delete_flag", 0).eq("a.reply_id", storeCommentVo.getId()).orderByDesc("a.created_time");
            List<StoreCommentVo> childCommentList = storeCommentMapper.getCommentList(childQueryWrapper);
            storeCommentVo.setCommitCount(storeCommentVo.getCommitCount() + childCommentList.size());
            //评价的评论的评论
            childCommentList.forEach(child -> {
                QueryWrapper<StoreCommentVo> childQueryCommentWrapper = new QueryWrapper<>();
                childQueryCommentWrapper
//                        .eq(null != businessId && 6 == businessId, "a.business_id", businessId)
                        .eq("a.delete_flag", 0).eq("a.reply_id", child.getId()).orderByDesc("a.created_time");
                List<StoreCommentVo> childComment2List = storeCommentMapper.getCommentList(childQueryCommentWrapper);

                //商家用户
                for (StoreCommentVo commentVo : childComment2List) {
                    if (StringUtils.isNotEmpty(commentVo.getPhoneId())) {
                        if (commentVo.getPhoneId().contains("store_")) {
                            commentVo.setStoreUserFlag(0);
                            StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getStoreId, child.getStoreId()));
                            commentVo.setStoreUserName(storeUser.getName());
                            commentVo.setStoreUserImg(storeUser.getHeadImg());
                        } else {
                            commentVo.setStoreUserFlag(1);
                        }
                    }
                }

                child.setStoreComment(childComment2List);
                storeCommentVo.setCommitCount(storeCommentVo.getCommitCount() + childComment2List.size());

                //商家用户
                if (StringUtils.isNotEmpty(child.getPhoneId())) {
                    if (child.getPhoneId().contains("store_")) {
                        child.setStoreUserFlag(0);
                        StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getStoreId, child.getStoreId()));
                        child.setStoreUserName(storeUser.getName());
                        child.setStoreUserImg(storeUser.getHeadImg());
                    } else {
                        child.setStoreUserFlag(1);
                    }
                }

            });
            //筛选商家评论
            List<StoreCommentVo> storeCommentList = new ArrayList<>();
            if (null != userType && userType == 0) {
                List<StoreCommentVo> collect = childCommentList.stream().filter(childComment -> childComment.getPhoneId().contains("store_")).collect(Collectors.toList());
                if (!collect.isEmpty()) {
                    storeCommentList.add(collect.get(0));
                    storeCommentVo.setStoreComment(storeCommentList);
                }
            } else {
                storeCommentVo.setStoreComment(childCommentList);
            }
            //子级点赞状态
            if (StringUtils.isNotEmpty(phoneId)) {
                childCommentList.forEach(child -> {
                    LambdaQueryWrapper<LifeLikeRecord> childlikeRecordQueryWrapper = new LambdaQueryWrapper<>();
                    childlikeRecordQueryWrapper.eq(LifeLikeRecord::getDianzanId, phoneId).eq(LifeLikeRecord::getHuifuId, child.getId());
                    if (lifeLikeRecordMapper.selectCount(childlikeRecordQueryWrapper) > 0) {
                        child.setIsLike(1);
                    } else {
                        child.setIsLike(0);
                    }
                });
            }
        }
        IPage<StoreCommentVo> resultPage = new Page<>();
        resultPage.setCurrent(page.getCurrent());
        resultPage.setSize(page.getSize());
        resultPage.setTotal(page.getTotal());
        resultPage.setPages(page.getPages());
        //筛选有无评论
        List<StoreCommentVo> collect = new ArrayList<>();
        if (replyStatus != null) {
            if (1 == replyStatus) {
                //只查询有回复的评论
                collect = storeCommentVoList.stream().filter(storeCommentVo -> ObjectUtils.isNotEmpty(storeCommentVo.getStoreComment())).collect(Collectors.toList());
            } else if (2 == replyStatus) {
                //只查询无回复的评论
                collect = storeCommentVoList.stream().filter(storeCommentVo -> ObjectUtils.isEmpty(storeCommentVo.getStoreComment())).collect(Collectors.toList());
            } else {
                collect = storeCommentVoList;
            }
        }
//        collect.forEach(item -> {
//            item.setCommitCount(null != item.getStoreComment() ? item.getStoreComment().size() : 0);
//        });
        resultPage.setRecords(collect);
        return resultPage;
    }

    /**
     * 获取最新一条评论/评价
     *
     * @param businessId   业务id
     * @param businessType 业务类型(1:订单评论, 2:动态社区评论, 3:活动评论,4:店铺打卡评论)
     * @param storeId      门店id
     * @return StoreCommentVo
     */
    @Override
    public StoreCommentVo getOne(Integer businessId, Integer businessType, Integer storeId) {
        AtomicReference<Integer> count = new AtomicReference<>(0);
        QueryWrapper<StoreCommentVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(null != businessId, "a.business_id", businessId).eq(null != businessType, "a.business_type", businessType).eq(null != storeId, "a.store_id", storeId).eq("a.delete_flag", 0).orderByDesc("a.created_time");
        List<StoreCommentVo> commentList = storeCommentMapper.getCommentList(queryWrapper);
        count.updateAndGet(v -> v + commentList.size());
        //父级评论下拼接子评论
        for (StoreCommentVo storeCommentVo : commentList) {
            QueryWrapper<StoreCommentVo> childQueryWrapper = new QueryWrapper<>();
            childQueryWrapper.eq("a.delete_flag", 0).eq("a.reply_id", storeCommentVo.getId());
            List<StoreCommentVo> childCommentList = storeCommentMapper.getCommentList(childQueryWrapper);
            count.updateAndGet(v -> v + childCommentList.size());
            //评价的评论的评论
            childCommentList.forEach(child -> {
                QueryWrapper<StoreCommentVo> childQueryCommentWrapper = new QueryWrapper<>();
                childQueryCommentWrapper
//                        .eq(null != businessId && 6 == businessId, "a.business_id", businessId)
                        .eq("a.delete_flag", 0).eq("a.reply_id", child.getId()).orderByDesc("a.created_time");
                List<StoreCommentVo> childComment2List = storeCommentMapper.getCommentList(childQueryCommentWrapper);
                count.updateAndGet(v -> v + childComment2List.size());
            });
        }
        if (!commentList.isEmpty()) {
            StoreCommentVo storeCommentVo = commentList.get(0);
            storeCommentVo.setCommitCount(Integer.parseInt(String.valueOf(count)));
            return storeCommentVo;
        }
        return null;
    }

    /**
     * 评论/评价数量和评分
     *
     * @param businessId   业务id
     * @param businessType 业务类型(1:订单评论, 2:动态社区评论, 3:活动评论,4:店铺打卡评论)
     * @param storeId      门店id
     * @return Integer
     */
    @Override
    public Map<String, Object> getCommitCountAndScore(Integer businessId, Integer businessType, Integer storeId, String phoneId, Integer days) {
        Map<String, Object> map = new HashMap<>();
        AtomicReference<Integer> count = new AtomicReference<>(0);
        QueryWrapper<StoreCommentVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(null != businessId, "a.business_id", businessId);
        queryWrapper.eq(null != businessType, "a.business_type", businessType);
        queryWrapper.eq(null != storeId, "a.store_id", storeId);

        if (null != days) {
            Date date = DateUtils.calcDays(new Date(), -days);
            queryWrapper.ge("a.created_time", DateUtils.formatDate(date, "yyyy-MM-dd"));
        }

        //通过当前登录人id 类型 查询举报业务id
        List<LifeUserViolation> lifeUserViolations = new ArrayList<>();
        if(businessType==2){
            String userId;
            if(phoneId!=null && !phoneId.equals("") && phoneId.startsWith("store_")){
                userId = phoneId.substring("store_".length());
                StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getPhone,userId));
                if(storeUser!=null){
                    LambdaQueryWrapper<LifeUserViolation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(LifeUserViolation::getReportingUserId,storeUser.getId());
                    lambdaQueryWrapper.eq(LifeUserViolation::getReportingUserType,1);
                    lambdaQueryWrapper.ne(LifeUserViolation::getProcessingStatus,2);
                    lifeUserViolations = lifeUserViolationMapper.selectList(lambdaQueryWrapper);
                }
            }else if(phoneId!=null && !phoneId.equals("") && phoneId.startsWith("user_")){
                userId = phoneId.substring("user_".length());
                LifeUser lifeUser = lifeUserMapper.selectOne(new LambdaQueryWrapper<LifeUser>().eq(LifeUser::getUserPhone,userId));
                if(lifeUser!=null){
                    LambdaQueryWrapper<LifeUserViolation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(LifeUserViolation::getReportingUserId,lifeUser.getId());
                    lambdaQueryWrapper.eq(LifeUserViolation::getReportingUserType,2);
                    lambdaQueryWrapper.ne(LifeUserViolation::getProcessingStatus,2);
                    lifeUserViolations = lifeUserViolationMapper.selectList(lambdaQueryWrapper);
                }
            }
        }

        List<Integer> businessIds = lifeUserViolations.stream()
                .filter(Objects::nonNull)
                .map(LifeUserViolation::getBusinessId)
                .filter(id -> id != null && !id.toString().isEmpty())
                .collect(Collectors.toList());
        if(businessIds!=null && businessIds.size()>0){
            queryWrapper.notIn("a.id",businessIds);
        }

        //先查询父级评论
        queryWrapper.isNull(businessType != 1, "a.reply_id").eq("a.delete_flag", 0).orderByDesc("a.created_time");
        List<StoreCommentVo> storeCommentVoList = storeCommentMapper.getCommentList(queryWrapper);
        count.updateAndGet(v -> v + storeCommentVoList.size());
        //评分合计
        Double sumScore = 0.0;
        //父级评论下拼接子评论
        for (StoreCommentVo storeCommentVo : storeCommentVoList) {
            sumScore += storeCommentVo.getScore();
            QueryWrapper<StoreCommentVo> childQueryWrapper = new QueryWrapper<>();
            childQueryWrapper.eq("a.delete_flag", 0).eq("a.reply_id", storeCommentVo.getId());
            List<StoreCommentVo> childCommentList = storeCommentMapper.getCommentList(childQueryWrapper);
            count.updateAndGet(v -> v + childCommentList.size());
            //评价的评论的评论
            childCommentList.forEach(child -> {
                QueryWrapper<StoreCommentVo> childQueryCommentWrapper = new QueryWrapper<>();
                childQueryCommentWrapper
//                        .eq(null != businessId && 6 == businessId, "a.business_id", businessId)
                        .eq("a.delete_flag", 0).eq("a.reply_id", child.getId()).orderByDesc("a.created_time");
                List<StoreCommentVo> childComment2List = storeCommentMapper.getCommentList(childQueryCommentWrapper);
                count.updateAndGet(v -> v + childComment2List.size());
            });
        }
        map.put("commitCount", count.toString());
        map.put("img", storeCommentVoList.stream().filter(i -> i.getScore() >= 4.5).map(StoreCommentVo::getUserImage).distinct().limit(6).collect(Collectors.toList()));
        if (sumScore == 0 || storeCommentVoList.isEmpty()) {
            map.put("score", "0");
        } else {
            BigDecimal score = new BigDecimal(sumScore).divide(new BigDecimal(storeCommentVoList.size()), 2, BigDecimal.ROUND_HALF_UP);
            map.put("score", score.toString());
        }

//        Map<String, Object> commentCountAndScore = storeCommentMapper.getCommentCountAndScore(businessId, businessType, storeId);
//        Object scoreObj = commentCountAndScore.get("score");
//        double scoreDouble = 0.0;
//        if (scoreObj != null) {
//            if (scoreObj instanceof Number) {
//                scoreDouble = ((Number) scoreObj).doubleValue();
//            } else if (scoreObj instanceof String) {
//                scoreDouble = Double.parseDouble((String) scoreObj);
//            }
//        }
//        if (scoreDouble == 0) {
//            map.put("score", "0");
//        } else {
//            BigDecimal scoreBigDecimal = new BigDecimal(String.valueOf(scoreDouble)).divide(new BigDecimal(commentCountAndScore.get("rootCount").toString()), 2, BigDecimal.ROUND_HALF_UP);
//            map.put("score", scoreBigDecimal.toString());
//        }
//        map.put("commitCount", commentCountAndScore.get("count").toString());
        return map;
    }

    /**
     * 评论
     *
     * @param multipartRequest 文件
     * @param businessId       业务id
     * @param businessType     业务类型(1:订单评论, 2:动态社区评论, 3:活动评论,4:店铺打卡评论)
     * @param storeId          门店id
     * @param userId           用户id
     * @param replyId          回复id
     * @param commentContent   评价内容
     * @return 0:成功, 1:失败, 2:文本内容异常, 3:图片内容异常
     */
    @Override
    public Integer userComment(MultipartRequest multipartRequest, Integer businessId, Integer businessType, Integer storeId, Integer userId, Integer replyId, String commentContent) {
        try {
            Map<String, String> checkText = TextCheckUtil.check(commentContent);
            if (null == checkText || checkText.get("result").equals("1")) {
                return 2;
            }
            StoreComment storeComment = new StoreComment();
            storeComment.setStoreId(storeId);
            storeComment.setUserId(userId);
            storeComment.setCommentContent(commentContent);
            storeComment.setReplyId(replyId);
            storeComment.setBusinessId(businessId);
            storeComment.setBusinessType(businessType);
            List<String> fileNameSet = new ArrayList<>(multipartRequest.getMultiFileMap().keySet());
            if (!fileNameSet.isEmpty()) {
                StringBuilder imgId = new StringBuilder();
                for (int i = 0; i < fileNameSet.size(); i++) {
                    MultipartFile multipartFile = multipartRequest.getFileMap().get(fileNameSet.get(i));
                    if (null != multipartFile) {
                        byte[] fileByte;
                        try {
                            fileByte = multipartFile.getBytes();
                        } catch (IOException e) {
                            return 1;
                        }
                        String base64 = Base64.getEncoder().encodeToString(fileByte);
                        Map<String, String> checkImage = ImageCheckUtil.check(base64, 2);
                        if (checkImage != null && checkImage.get("result").equals("1")) {
                            return 3;
                        }
                        StoreImg storeImg = new StoreImg();
                        storeImg.setStoreId(storeComment.getStoreId());
                        storeImg.setImgType(8);
                        storeImg.setImgSort(i + 1);
                        storeImg.setImgUrl(fileUploadUtil.uploadOneFile(multipartFile));
                        storeImgMapper.insert(storeImg);
                        imgId.append(storeImg.getId()).append(",");
                    }
                }
                if (!imgId.toString().isEmpty()) {
                    storeComment.setImgId(imgId.substring(0, imgId.length() - 1));
                }
            }
            storeComment.setCreatedUserId(storeComment.getUserId());
            return this.save(storeComment) ? 0 : 1;
        } catch (Exception e) {
            log.error("StoreCommentService.userComment ERROR Msg={}", e.getMessage());
            return 1;
        }

    }

    /**
     * 新增或修改评论/评价
     *
     * @param multipartRequest 文件
     * @param id               主键
     * @param businessId       业务id
     * @param businessType     业务类型(1:订单评论, 2:动态社区评论, 3:活动评论,4:店铺打卡评论)
     * @param storeId          门店id
     * @param userId           用户id
     * @param replyId          回复id
     * @param commentContent   评价内容
     * @param score            评分
     * @param otherScore       其他评分
     * @param isAnonymous      是否匿名(0:否(默认), 1:是)
     * @param evaluationTags   评价标签
     * @param phoneId          用户id
     * @return 0:成功, 1:失败, 2:文本内容异常, 3:图片内容异常
     */
    @Override
    public Integer addComment(MultipartRequest multipartRequest, Integer id, Integer businessId, Integer businessType, Integer storeId, Integer userId, Integer replyId, String commentContent, Double score, String otherScore, Integer isAnonymous, String evaluationTags, String phoneId) {
        try {
            List<String> servicesList = Lists.newArrayList();
            servicesList.add(TextReviewServiceEnum.COMMENT_DETECTION_PRO.getService());
            servicesList.add(TextReviewServiceEnum.LLM_QUERY_MODERATION.getService());
            TextModerationResultVO textCheckResult = textModerationUtil.invokeFunction(commentContent, servicesList);
            if ("high".equals(textCheckResult.getRiskLevel())) {
                return 2;
            }

            /*Map<String, String> checkText = TextCheckUtil.check(commentContent);
            if (null == checkText || checkText.get("result").equals("1")) {
                return 2;
            }*/
            StoreComment storeComment = new StoreComment();
            storeComment.setId(id);
            storeComment.setStoreId(storeId);
            storeComment.setUserId(userId);
            storeComment.setCommentContent(commentContent);
            storeComment.setReplyId(replyId);
            storeComment.setBusinessId(businessId);
            storeComment.setBusinessType(businessType);
            storeComment.setScore(score);

            if (StringUtils.isNotEmpty(otherScore)) {
                List<LifeCouponVo> lifeCouponVos = JSONArray.parseArray(otherScore, LifeCouponVo.class);
                lifeCouponVos.stream().filter(i -> "口味".equals(i.getName())).findFirst().ifPresent(item -> storeComment.setTasteScore(Double.valueOf(item.getRateScore())));
                lifeCouponVos.stream().filter(i -> "环境".equals(i.getName())).findFirst().ifPresent(item -> storeComment.setEnScore(Double.valueOf(item.getRateScore())));
                lifeCouponVos.stream().filter(i -> "服务".equals(i.getName())).findFirst().ifPresent(item -> storeComment.setServiceScore(Double.valueOf(item.getRateScore())));
            }
            storeComment.setOtherScore(otherScore);
            storeComment.setIsAnonymous(isAnonymous);
            storeComment.setEvaluationTags(evaluationTags);
            storeComment.setPhoneId(phoneId);
            List<String> fileNameSet = new ArrayList<>(multipartRequest.getMultiFileMap().keySet());
            if (!fileNameSet.isEmpty() && storeId != null) {
                StringBuilder imgId = new StringBuilder();
                for (int i = 0; i < fileNameSet.size(); i++) {
                    MultipartFile multipartFile = multipartRequest.getFileMap().get(fileNameSet.get(i));
                   //b
                    System.out.println(multipartFile.getSize());
                    //kb
                    System.out.println(multipartFile.getSize() / 1024);
                    if (null != multipartFile && multipartFile.getSize() / 1024 > 0) {
                        byte[] fileByte;
                        try {
                            fileByte = multipartFile.getBytes();
                        } catch (IOException e) {
                            return 1;
                        }
                        String base64 = Base64.getEncoder().encodeToString(fileByte);
                        Map<String, String> checkImage = ImageCheckUtil.check(base64, 2);
                        if (checkImage != null && checkImage.get("result").equals("1")) {
                            return 3;
                        }
                        StoreImg storeImg = new StoreImg();
                        storeImg.setStoreId(storeComment.getStoreId());
                        storeImg.setImgType(8);
                        storeImg.setImgSort(i + 1);
                        storeImg.setImgUrl(fileUploadUtil.uploadOneFile(multipartFile));
                        storeImgMapper.insert(storeImg);
                        imgId.append(storeImg.getId()).append(",");
                    }
                }
                if (!imgId.toString().isEmpty()) {
                    storeComment.setImgId(imgId.substring(0, imgId.length() - 1));
                }
            }
            storeComment.setCreatedUserId(storeComment.getUserId());
            int i = this.save(storeComment) ? 0 : 1;

            //判断类型如果为5是评价 更新订单表orderAppraise为1 订单已评价
            if(businessType == 5){
                LambdaUpdateWrapper<LifeUserOrder> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.eq(LifeUserOrder :: getId, businessId );
                lambdaUpdateWrapper.set(LifeUserOrder :: getOrderAppraise, 1);
                lifeUserOrderMapper.update(null,lambdaUpdateWrapper);
            }
            StoreInfoScoreVo storeInfoScoreVo = storeCommentMapper.getCommentCountAndScoreInfo(storeId);
            double total = storeInfoScoreVo.getTotal();
            double scoreAvg = (total == 0 ? 0 : storeInfoScoreVo.getScore() / total);
            double tasteScore = (total == 0 ? 0 : storeInfoScoreVo.getTasteScore() / total);
            double enScore = (total == 0 ? 0 : storeInfoScoreVo.getEnScore() / total);
            double serviceScore = (total == 0 ? 0 : storeInfoScoreVo.getServiceScore() / total);
            StoreInfo storeInfo = new StoreInfo();
            storeInfo.setId(storeId);
            storeInfo.setScoreAvg(new BigDecimal(scoreAvg).setScale(2, RoundingMode.HALF_UP).doubleValue());
            storeInfo.setTasteScore(new BigDecimal(tasteScore).setScale(2, RoundingMode.HALF_UP).doubleValue());
            storeInfo.setEnScore(new BigDecimal(enScore).setScale(2, RoundingMode.HALF_UP).doubleValue());
            storeInfo.setServiceScore(new BigDecimal(serviceScore).setScale(2, RoundingMode.HALF_UP).doubleValue());
            storeInfoMapper.updateById(storeInfo);
            StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getStoreId, storeInfo.getId()).eq(StoreUser::getDeleteFlag, 0));

            // 如果差评，则发送差评提醒
            if(score != null && score >= 0.5 && score <= 2.5){
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String commonDate = simpleDateFormat.format(new Date());
                LifeNotice lifeMessage = new LifeNotice();
                lifeMessage.setReceiverId("store_" + storeUser.getPhone());
                String text = "在"+commonDate+"，您的店铺有一条差评记录，您可查看评价内容是否属实，如不属实，可向平台进行申诉。";
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("message", text);
                lifeMessage.setContext(jsonObject.toJSONString());
                lifeMessage.setTitle("差评通知");
                lifeMessage.setSenderId("system");
                lifeMessage.setIsRead(0);
                lifeMessage.setNoticeType(1);
                lifeMessage.setBusinessType(1);
                lifeNoticeMapper.insert(lifeMessage);

                WebSocketVo websocketVo = new WebSocketVo();
                websocketVo.setSenderId("system");
                websocketVo.setReceiverId("store_" + storeUser.getPhone());
                websocketVo.setCategory("notice");
                websocketVo.setNoticeType("1");
                websocketVo.setIsRead(0);
                websocketVo.setText(JSONObject.from(lifeMessage).toJSONString());
                webSocketProcess.sendMessage("store_" + storeUser.getPhone(), JSONObject.from(websocketVo).toJSONString());
            }
            return i;
        } catch (Exception e) {
            log.error("StoreCommentService.userComment ERROR Msg={}", e.getMessage());
            return 1;
        }

    }

    /**
     * 新增或修改评论/评价
     *
     * @param multipartRequest 文件
     * @param id               主键
     * @param businessId       业务id
     * @param businessType     业务类型(1:订单评论, 2:动态社区评论, 3:活动评论,4:店铺打卡评论)
     * @param storeId          门店id
     * @param userId           用户id
     * @param replyId          回复id
     * @param commentContent   评价内容
     * @param score            评分
     * @param otherScore       其他评分
     * @param isAnonymous      是否匿名(0:否(默认), 1:是)
     * @param evaluationTags   评价标签
     * @param phoneId          用户id
     * @return 0:成功, 1:失败, 2:文本内容异常, 3:图片内容异常
     */
    @Override
    public Integer addCommentNew(MultipartRequest multipartRequest, Integer id, Integer businessId, Integer businessType, Integer storeId, Integer orderId, Integer lawyerId, Integer userId, Integer replyId, String commentContent, Double score, String otherScore, Integer isAnonymous, String evaluationTags, String phoneId) {
        try {
            List<String> servicesList = Lists.newArrayList();
            servicesList.add(TextReviewServiceEnum.COMMENT_DETECTION_PRO.getService());
            servicesList.add(TextReviewServiceEnum.LLM_QUERY_MODERATION.getService());
            TextModerationResultVO textCheckResult = textModerationUtil.invokeFunction(commentContent, servicesList);
            if ("high".equals(textCheckResult.getRiskLevel())) {
                return 2;
            }

            /*Map<String, String> checkText = TextCheckUtil.check(commentContent);
            if (null == checkText || checkText.get("result").equals("1")) {
                return 2;
            }*/
            StoreComment storeComment = new StoreComment();
            storeComment.setId(id);
            storeComment.setStoreId(storeId);
            storeComment.setUserId(userId);
            storeComment.setCommentContent(commentContent);
            storeComment.setReplyId(replyId);
            storeComment.setBusinessId(businessId);
            storeComment.setBusinessType(businessType);
            storeComment.setScore(score);
            storeComment.setLawyerId(lawyerId);
            storeComment.setOrderId(orderId);

            if (StringUtils.isNotEmpty(otherScore)) {
                List<LifeCouponVo> lifeCouponVos = JSONArray.parseArray(otherScore, LifeCouponVo.class);
                lifeCouponVos.stream().filter(i -> "口味".equals(i.getName())).findFirst().ifPresent(item -> storeComment.setTasteScore(Double.valueOf(item.getRateScore())));
                lifeCouponVos.stream().filter(i -> "环境".equals(i.getName())).findFirst().ifPresent(item -> storeComment.setEnScore(Double.valueOf(item.getRateScore())));
                lifeCouponVos.stream().filter(i -> "服务".equals(i.getName())).findFirst().ifPresent(item -> storeComment.setServiceScore(Double.valueOf(item.getRateScore())));
            }
            storeComment.setOtherScore(otherScore);
            storeComment.setIsAnonymous(isAnonymous);
            storeComment.setEvaluationTags(evaluationTags);
            storeComment.setPhoneId(phoneId);
            List<String> fileNameSet = new ArrayList<>(multipartRequest.getMultiFileMap().keySet());
            if (!fileNameSet.isEmpty() && storeId != null) {
                StringBuilder imgId = new StringBuilder();
                for (int i = 0; i < fileNameSet.size(); i++) {
                    MultipartFile multipartFile = multipartRequest.getFileMap().get(fileNameSet.get(i));
                    //b
                    System.out.println(multipartFile.getSize());
                    //kb
                    System.out.println(multipartFile.getSize() / 1024);
                    if (null != multipartFile && multipartFile.getSize() / 1024 > 0) {
                        byte[] fileByte;
                        try {
                            fileByte = multipartFile.getBytes();
                        } catch (IOException e) {
                            return 1;
                        }
                        String base64 = Base64.getEncoder().encodeToString(fileByte);
                        Map<String, String> checkImage = ImageCheckUtil.check(base64, 2);
                        if (checkImage != null && checkImage.get("result").equals("1")) {
                            return 3;
                        }
                        StoreImg storeImg = new StoreImg();
                        storeImg.setStoreId(storeComment.getStoreId());
                        storeImg.setImgType(8);
                        storeImg.setImgSort(i + 1);
                        storeImg.setImgUrl(fileUploadUtil.uploadOneFile(multipartFile));
                        storeImgMapper.insert(storeImg);
                        imgId.append(storeImg.getId()).append(",");
                    }
                }
                if (!imgId.toString().isEmpty()) {
                    storeComment.setImgId(imgId.substring(0, imgId.length() - 1));
                }
            }
            storeComment.setCreatedUserId(storeComment.getUserId());
            int i = this.save(storeComment) ? 0 : 1;

            //判断类型如果为5是评价 更新订单表orderAppraise为1 订单已评价
            if(businessType == 5){
                LambdaUpdateWrapper<LifeUserOrder> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.eq(LifeUserOrder :: getId, businessId );
                lambdaUpdateWrapper.set(LifeUserOrder :: getOrderAppraise, 1);
                lifeUserOrderMapper.update(null,lambdaUpdateWrapper);
            }
            StoreInfoScoreVo storeInfoScoreVo = storeCommentMapper.getCommentCountAndScoreInfo(storeId);
            double total = storeInfoScoreVo.getTotal();
            double scoreAvg = (total == 0 ? 0 : storeInfoScoreVo.getScore() / total);
            double tasteScore = (total == 0 ? 0 : storeInfoScoreVo.getTasteScore() / total);
            double enScore = (total == 0 ? 0 : storeInfoScoreVo.getEnScore() / total);
            double serviceScore = (total == 0 ? 0 : storeInfoScoreVo.getServiceScore() / total);
            StoreInfo storeInfo = new StoreInfo();
            storeInfo.setId(storeId);
            storeInfo.setScoreAvg(new BigDecimal(scoreAvg).setScale(2, RoundingMode.HALF_UP).doubleValue());
            storeInfo.setTasteScore(new BigDecimal(tasteScore).setScale(2, RoundingMode.HALF_UP).doubleValue());
            storeInfo.setEnScore(new BigDecimal(enScore).setScale(2, RoundingMode.HALF_UP).doubleValue());
            storeInfo.setServiceScore(new BigDecimal(serviceScore).setScale(2, RoundingMode.HALF_UP).doubleValue());
            storeInfoMapper.updateById(storeInfo);
            StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getStoreId, storeInfo.getId()).eq(StoreUser::getDeleteFlag, 0));

            // 如果差评，则发送差评提醒
            if(score != null && score >= 0.5 && score <= 2.5){
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String commonDate = simpleDateFormat.format(new Date());
                LifeNotice lifeMessage = new LifeNotice();
                lifeMessage.setReceiverId("store_" + storeUser.getPhone());
                String text = "在"+commonDate+"，您的店铺有一条差评记录，您可查看评价内容是否属实，如不属实，可向平台进行申诉。";
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("message", text);
                lifeMessage.setContext(jsonObject.toJSONString());
                lifeMessage.setTitle("差评通知");
                lifeMessage.setSenderId("system");
                lifeMessage.setIsRead(0);
                lifeMessage.setNoticeType(1);
                lifeMessage.setBusinessType(1);
                lifeNoticeMapper.insert(lifeMessage);

                WebSocketVo websocketVo = new WebSocketVo();
                websocketVo.setSenderId("system");
                websocketVo.setReceiverId("store_" + storeUser.getPhone());
                websocketVo.setCategory("notice");
                websocketVo.setNoticeType("1");
                websocketVo.setIsRead(0);
                websocketVo.setText(JSONObject.from(lifeMessage).toJSONString());
                webSocketProcess.sendMessage("store_" + storeUser.getPhone(), JSONObject.from(websocketVo).toJSONString());
            }
            return i;
        } catch (Exception e) {
            log.error("StoreCommentService.userComment ERROR Msg={}", e.getMessage());
            return 1;
        }

    }

    /**
     * 回复率, 评价比例
     *
     * @param storeId 门店id
     * @return StoreCommitPercentVo
     */
    @Override
    public StoreCommitPercentVo getCommitPercent(Integer storeId) {
        StoreCommitPercentVo storeCommit = storeCommentMapper.getCommentByStoreId(storeId);
        if (storeCommit != null) {
            if ("0".equals(storeCommit.getAllCommentCount())) {
                storeCommit.setHighPercent("0%");
                storeCommit.setMidPercent("0%");
                storeCommit.setLowPercent("0%");
            } else {
                double highPercentDouble = Double.parseDouble(storeCommit.getHighCommentCount()) / Double.parseDouble(storeCommit.getRootCommentCount());
                BigDecimal highPercent = BigDecimal.valueOf(highPercentDouble).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
                //好评
                storeCommit.setHighPercent(highPercent + "%");
                double midPercentDouble = Double.parseDouble(storeCommit.getMidCommentCount()) / Double.parseDouble(storeCommit.getRootCommentCount());
                BigDecimal midPercent = BigDecimal.valueOf(midPercentDouble).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
                //中评
                storeCommit.setMidPercent(midPercent + "%");
                double lowPercentDouble = Double.parseDouble(storeCommit.getLowCommentCount()) / Double.parseDouble(storeCommit.getRootCommentCount());
                BigDecimal lowPercent = BigDecimal.valueOf(lowPercentDouble).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
                //差评
                storeCommit.setLowPercent(lowPercent + "%");
            }
            if ("0".equals(storeCommit.getRootCommentCount())) {
                storeCommit.setReplyPercent("0%");
            } else {
                double replyPercentDouble = Double.parseDouble(storeCommit.getCommentCount()) / Double.parseDouble(storeCommit.getRootCommentCount());
                BigDecimal replyPercent = BigDecimal.valueOf(replyPercentDouble).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
                //回复率
                storeCommit.setReplyPercent(replyPercent + "%");
            }
            return storeCommit;
        }
        return null;
    }

    @Override
    public IPage<LifeUserOrderCommentVo> getCommentOrderPage(Integer pageNum, Integer pageSize, Integer type, String userId) {
        IPage<LifeUserOrderCommentVo> lifeUserOrderCommentVoIPage = new Page<>(pageNum, pageSize);
        IPage<LifeUserOrderCommentVo> commentOrderPage;
        //1.未评价 2.已评价
        if (type == 1) {
            commentOrderPage = storeCommentMapper.getCommentOrderWPJPage(lifeUserOrderCommentVoIPage, userId);
        } else {
            commentOrderPage = storeCommentMapper.getCommentOrderYPJPage(lifeUserOrderCommentVoIPage, userId);
        }
        List<String> collect = commentOrderPage.getRecords().stream().map(LifeUserOrderCommentVo::getGroupBuyImgId).collect(Collectors.toList());

        if (ObjectUtils.isNotEmpty(collect)) {
            List<StoreImg> storeImgList = storeImgMapper.selectList(new QueryWrapper<StoreImg>().inSql("id", String.join(",", collect)));
//            commentOrderPage.getRecords().forEach(i ->
//                    i.setGroupBuyImgUrl(storeImgList.stream().filter(j -> j.getId().toString().equals(i.getGroupBuyImgId()))
//                            .findFirst().map(StoreImg::getImgUrl).orElse(null)));
            // 2. 优化分组：id唯一，直接映射为 Map<Integer, StoreImg>（避免List处理）
            Map<Integer, StoreImg> imgIdToImgMap = storeImgList.stream()
                    .collect(Collectors.toMap(
                            StoreImg::getId,  // 键：图片id
                            Function.identity(),  // 值：图片对象本身
                            (existing, replacement) -> existing  // 若有重复id（理论上不会），保留第一个
                    ));

            // 3. 遍历订单评论记录，处理图片URL拼接
            for (LifeUserOrderCommentVo record : commentOrderPage.getRecords()) {
                String groupBuyImgId = record.getGroupBuyImgId();
                // 空指针防护：如果imgId为空，直接设为空字符串
                if (groupBuyImgId == null || groupBuyImgId.trim().isEmpty()) {
                    record.setGroupBuyImgUrl("");
                    continue;
                }

                // 分割imgId并一次性转换为Integer（避免重复解析）
                List<Integer> imgIds = Arrays.stream(groupBuyImgId.split(","))
                        .map(String::trim)  // 处理可能的空格
                        .filter(idStr -> !idStr.isEmpty())  // 过滤空字符串（如连续逗号导致的）
                        .map(idStr -> {
                            try {
                                return Integer.parseInt(idStr);
                            } catch (NumberFormatException e) {
                                // 处理非数字id的异常（如无效id）
                                return null;
                            }
                        })
                        .filter(Objects::nonNull)  // 过滤转换失败的null
                        .collect(Collectors.toList());

                // 拼接图片URL（使用StringBuilder高效拼接）
                StringBuilder imgUrlBuilder = new StringBuilder();
                for (Integer imgId : imgIds) {
                    StoreImg storeImg = imgIdToImgMap.get(imgId);
                    if (storeImg != null && storeImg.getImgUrl() != null) {
                        if (imgUrlBuilder.length() > 0) {
                            imgUrlBuilder.append(",");  // 非第一个元素前加逗号
                        }
                        imgUrlBuilder.append(storeImg.getImgUrl());
                    }
                }

                // 设置最终的图片URL字符串（去掉末尾可能的逗号，这里通过逻辑避免了）
                record.setGroupBuyImgUrl(imgUrlBuilder.toString());
            }
        }


        List<LifeUserOrderCommentVo> lifeUserOrderCommentVos =  commentOrderPage.getRecords();
        if(CollectionUtils.isEmpty(lifeUserOrderCommentVos)){
            return commentOrderPage;
        }
        List<String> orderIds = lifeUserOrderCommentVos.stream().map(LifeUserOrderCommentVo::getId).collect(Collectors.toList());
        List<StoreComment> storeCommentList = storeCommentMapper.selectList(new QueryWrapper<StoreComment>().inSql("business_id", String.join(",", orderIds)).eq("business_type", 5));
        if(CollectionUtils.isEmpty(storeCommentList)){
            return commentOrderPage;
        }
        Map<Integer, StoreComment> commentIdToMap = storeCommentList.stream()
                .collect(Collectors.toMap(
                        StoreComment::getBusinessId,
                        Function.identity(),
                        (existing, replacement) -> existing  // 若有重复id（理论上不会），保留第一个
                ));
        if(CollectionUtils.isEmpty(commentIdToMap)){
            return commentOrderPage;
        }
        for(LifeUserOrderCommentVo lifeUserOrderCommentVo : commentOrderPage.getRecords()){
            Integer orderId = Integer.parseInt(lifeUserOrderCommentVo.getId());

            if(commentIdToMap.containsKey(orderId)){
                StoreComment storeComment = commentIdToMap.get(orderId);
                lifeUserOrderCommentVo.setScore(storeComment.getScore().toString());
                lifeUserOrderCommentVo.setCommentDate(storeComment.getCreatedTime());
                String imgIds = storeComment.getImgId();

                if(StringUtils.isNotEmpty(imgIds)){
                    LambdaQueryWrapper<StoreImg> storeImgLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    List<String> imgIdList = Arrays.stream(imgIds.split(","))
                            .map(String::trim)
                            .collect(Collectors.toList());
                    storeImgLambdaQueryWrapper.in(StoreImg::getId, imgIdList);
                    List<StoreImg> storeImgList = storeImgMapper.selectList(storeImgLambdaQueryWrapper);
                    if(CollectionUtils.isNotEmpty(storeImgList)){
                        List<String> imgUrlList = storeImgList.stream()    // 转换为 Stream
                                .map(StoreImg::getImgUrl)                  // 映射，提取 name 字段
                                .collect(Collectors.toList());
                        lifeUserOrderCommentVo.setImgUrls(imgUrlList);
                    }
                }
            }
        }

        return commentOrderPage;
    }

    /**
     * 当前用户的全部评价（店铺订单评价 + 律师订单评价）
     */
    @Override
    public IPage<LifeUserOrderCommentVo> getUserAllCommentsPage(Integer pageNum, Integer pageSize, Integer userId) {
        IPage<LifeUserOrderCommentVo> page = new Page<>(pageNum, pageSize);
        IPage<LifeUserOrderCommentVo> result = storeCommentMapper.getUserAllCommentsPage(page, userId);
        List<LifeUserOrderCommentVo> records = result.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return result;
        }

        // 收集需要补全的图片ID
        Set<Integer> allImgIds = new HashSet<>();
        records.forEach(r -> {
            // 团购图片
            if (StringUtils.isNotEmpty(r.getGroupBuyImgId())) {
                Arrays.stream(r.getGroupBuyImgId().split(","))
                        .map(String::trim)
                        .filter(s -> !s.isEmpty())
                        .forEach(s -> {
                            try { allImgIds.add(Integer.parseInt(s)); } catch (NumberFormatException ignored) {}
                        });
            }
            // 店铺评价图片（img_id）
            if (r.getSrc() != null && r.getSrc() == 1 && StringUtils.isNotEmpty(r.getImgId())) {
                Arrays.stream(r.getImgId().split(","))
                        .map(String::trim)
                        .filter(s -> !s.isEmpty())
                        .forEach(s -> {
                            try { allImgIds.add(Integer.parseInt(s)); } catch (NumberFormatException ignored) {}
                        });
            }
        });

        final Map<Integer, StoreImg> imgIdToImgMap = new HashMap<>();
        if (!allImgIds.isEmpty()) {
            List<StoreImg> storeImgList = storeImgMapper.selectList(new QueryWrapper<StoreImg>().in("id", allImgIds));
            imgIdToImgMap.putAll(storeImgList.stream().collect(Collectors.toMap(StoreImg::getId, Function.identity(), (a, b) -> a)));
        }

        // 补全 groupBuyImgUrl 与评价图片列表
        for (LifeUserOrderCommentVo r : records) {
            // 团购图片 URL
            if (StringUtils.isNotEmpty(r.getGroupBuyImgId())) {
                List<String> urls = Arrays.stream(r.getGroupBuyImgId().split(","))
                        .map(String::trim)
                        .filter(s -> !s.isEmpty())
                        .map(idStr -> {
                            try {
                                StoreImg img = imgIdToImgMap.get(Integer.parseInt(idStr));
                                return img != null ? img.getImgUrl() : null;
                            } catch (NumberFormatException e) {
                                return null;
                            }
                        })
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());
                r.setGroupBuyImgUrl(String.join(",", urls));
            }

            // 评价图片 URL 列表
            if (r.getSrc() != null && r.getSrc() == 1) {
                // 店铺评价：imgId 是逗号分隔的图片ID
                if (StringUtils.isNotEmpty(r.getImgId())) {
                    List<String> imgUrls = Arrays.stream(r.getImgId().split(","))
                            .map(String::trim)
                            .filter(s -> !s.isEmpty())
                            .map(idStr -> {
                                try {
                                    StoreImg img = imgIdToImgMap.get(Integer.parseInt(idStr));
                                    return img != null ? img.getImgUrl() : null;
                                } catch (NumberFormatException e) {
                                    return null;
                                }
                            })
                            .filter(Objects::nonNull)
                            .collect(Collectors.toList());
                    r.setImgUrls(imgUrls);
                }
            } else if (r.getSrc() != null && r.getSrc() == 2) {
                // 律师评价：review_images 是 JSON 数组(URL 列表)
                if (StringUtils.isNotEmpty(r.getImgId())) {
                    try {
                        List<String> imgUrls = JSONArray.parseArray(r.getImgId(), String.class);
                        r.setImgUrls(imgUrls);
                    } catch (Exception e) {
                        log.warn("parse lawyer review images fail, raw={}", r.getImgId());
                    }
                }
            }
        }
        return result;
    }

    /**
     * 获取店铺评价计数统计
     *
     * @param storeId 门店id
     * @return StoreCommentCountVo
     */
    @Override
    public StoreCommentCountVo getAppraiseCount(Integer storeId) {
        StoreCommentCountVo countVo = new StoreCommentCountVo();

        // 查询条件：只统计当前门店、根评论（reply_id为null）、未删除的评论
        LambdaQueryWrapper<StoreComment> totalWrapper = buildBaseStoreCommentWrapper(storeId);
        countVo.setTotalCount(storeCommentMapper.selectCount(totalWrapper));

        // 2. 有图评论数（img_id不为空且不为空字符串）
        LambdaQueryWrapper<StoreComment> imageWrapper = buildBaseStoreCommentWrapper(storeId);
        imageWrapper.isNotNull(StoreComment::getImgId)
                .apply("img_id != ''");
        countVo.setImageCount(storeCommentMapper.selectCount(imageWrapper));

        // 3. 好评数（score >= 4.5）
        LambdaQueryWrapper<StoreComment> goodWrapper = buildBaseStoreCommentWrapper(storeId);
        goodWrapper.ge(StoreComment::getScore, 4.5);
        countVo.setGoodCount(storeCommentMapper.selectCount(goodWrapper));

        // 4. 中评数（score >= 3 && score <= 4）
        LambdaQueryWrapper<StoreComment> midWrapper = buildBaseStoreCommentWrapper(storeId);
        midWrapper.ge(StoreComment::getScore, 3.0)
                .le(StoreComment::getScore, 4.0);
        countVo.setMidCount(storeCommentMapper.selectCount(midWrapper));

        // 5. 差评数（score >= 0.5 && score <= 2.5）
        LambdaQueryWrapper<StoreComment> badWrapper = buildBaseStoreCommentWrapper(storeId);
        badWrapper.ge(StoreComment::getScore, 0.5)
                .le(StoreComment::getScore, 2.5);
        countVo.setBadCount(storeCommentMapper.selectCount(badWrapper));

        return countVo;
    }

    /**
     * 构建当前门店根评论的查询条件
     */
    private LambdaQueryWrapper<StoreComment> buildBaseStoreCommentWrapper(Integer storeId) {
        return new LambdaQueryWrapper<StoreComment>()
                .eq(StoreComment::getStoreId, storeId)
                .gt(StoreComment::getScore,0 )
                .eq(StoreComment::getBusinessType, 5)
                .eq(StoreComment::getDeleteFlag, 0);
    }

    // ==================== 订单评价相关方法实现（迁移自 OrderReviewService）====================

    @Override
    public R<StoreComment> createOrderReview(OrderReviewDto reviewDto) {
        log.info("StoreCommentServiceImpl.createOrderReview?reviewDto={}", reviewDto);

        // 参数校验
        if (reviewDto == null) {
            return R.fail("评价信息不能为空");
        }
        if (reviewDto.getOrderId() == null) {
            return R.fail("订单ID不能为空");
        }
        Integer userId = reviewDto.getUserId();
        if (userId == null) {
            return R.fail("用户ID不能为空");
        }

        // 验证订单是否存在且属于该用户
        LawyerConsultationOrder order = lawyerConsultationOrderMapper.selectById(reviewDto.getOrderId());
        if (order == null) {
            return R.fail("订单不存在");
        }
        if (!order.getClientUserId().equals(userId)) {
            return R.fail("只能评价自己的订单");
        }

        // 检查订单是否已完成
        if (order.getOrderStatus() == null || order.getOrderStatus() != 3) {
            return R.fail("只能对已完成的订单进行评价");
        }

        // 检查是否已经评价过（使用 store_comment 表，business_type=5）
        LambdaQueryWrapper<StoreComment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreComment::getOrderId, reviewDto.getOrderId())
                .eq(StoreComment::getBusinessType, 5)
                .eq(StoreComment::getDeleteFlag, 0);
        StoreComment existingReview = this.getOne(queryWrapper);
        if (existingReview != null) {
            return R.success("该订单已经评价过了");
        }

        // 创建评价（使用 store_comment 表）
        StoreComment review = new StoreComment();
        review.setOrderId(reviewDto.getOrderId());
        review.setLawyerId(order.getLawyerUserId());
        review.setUserId(userId);
        review.setCommentContent(reviewDto.getReviewContent());
        review.setScore(reviewDto.getOverallRating());
        review.setBusinessId(reviewDto.getOrderId()); // 订单ID作为业务ID
        review.setBusinessType(5); // 订单评价
        review.setIsAnonymous(reviewDto.getIsAnonymous() != null ? reviewDto.getIsAnonymous() : 0);
        review.setLikeCount(0);

        
        // 处理评价图片：将图片URL存入store_img表，并将图片ID存入store_comment的img_id字段
        if (reviewDto.getReviewImages() != null && !reviewDto.getReviewImages().isEmpty()) {
            StringBuilder imgIdBuilder = new StringBuilder();
            Integer orderId = reviewDto.getOrderId();
            
            for (int i = 0; i < reviewDto.getReviewImages().size(); i++) {
                String imgUrl = reviewDto.getReviewImages().get(i);
                if (StringUtils.isNotEmpty(imgUrl)) {
                    StoreImg storeImg = new StoreImg();
                    storeImg.setImgType(8); // 用户评论图片类型
                    storeImg.setBusinessId(orderId); // 订单ID作为业务ID
                    storeImg.setImgUrl(imgUrl);
                    storeImg.setImgSort(i + 1); // 图片排序
                    storeImg.setCreatedUserId(userId);
                    storeImg.setCreatedTime(new Date());
                    storeImg.setDeleteFlag(0);
                    storeImg.setStoreId(0);
                    int insertResult = storeImgMapper.insert(storeImg);
                    if (insertResult > 0 && storeImg.getId() != null) {
                        imgIdBuilder.append(storeImg.getId()).append(",");
                        log.info("创建评价图片成功，图片ID={}, 订单ID={}", storeImg.getId(), orderId);
                    } else {
                        log.warn("创建评价图片失败，图片URL={}, 订单ID={}", imgUrl, orderId);
                    }
                }
            }
            
            // 将图片ID用逗号分隔存入img_id字段
            if (imgIdBuilder.length() > 0) {
                String imgIdStr = imgIdBuilder.substring(0, imgIdBuilder.length() - 1);
                review.setImgId(imgIdStr);
                log.info("评价图片ID设置成功，imgId={}, 订单ID={}", imgIdStr, orderId);
            }
        }
        
        review.setCreatedUserId(userId);
        review.setCreatedTime(new Date());

        boolean success = this.save(review);
        if (success) {
            log.info("创建评价成功，评价ID={}", review.getId());
            // 更新律师评分
            updateLawyerServiceScore(order.getLawyerUserId());
            return R.data(review, "提交成功");
        } else {
            log.error("创建评价失败");
            return R.fail("创建评价失败");
        }
    }

    /**
     * 更新律师服务评分和好评/中评/差评数量
     */
    private void updateLawyerServiceScore(Integer lawyerUserId) {
        if (lawyerUserId == null) {
            log.warn("更新律师评分失败：律师ID为空");
            return;
        }

        try {
            // 从 store_comment 表计算平均评分（business_type=5）
            LambdaQueryWrapper<StoreComment> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(StoreComment::getLawyerId, lawyerUserId)
                    .eq(StoreComment::getBusinessType, 5)
                    .eq(StoreComment::getDeleteFlag, 0)
                    .isNotNull(StoreComment::getScore);
            List<StoreComment> reviews = this.list(queryWrapper);
            
            Double averageRating = null;
            if (!reviews.isEmpty()) {
                double sum = reviews.stream()
                        .filter(r -> r.getScore() != null)
                        .mapToDouble(StoreComment::getScore)
                        .sum();
                averageRating = sum / reviews.size();
            }

            Double serviceScore;
            if (averageRating != null) {
                serviceScore = Math.floor(averageRating * 10.0) / 10.0;
                serviceScore = Math.max(0.0, Math.min(5.0, serviceScore));
            } else {
                serviceScore = 0.0;
            }

            // 统计好评、中评、差评数量
            long goodCount = reviews.stream()
                    .filter(r -> r.getScore() != null && r.getScore() >= 4.5 && r.getScore() <= 5)
                    .count();
            long mediumCount = reviews.stream()
                    .filter(r -> r.getScore() != null && r.getScore() >= 3.0 && r.getScore() < 4.5)
                    .count();
            long badCount = reviews.stream()
                    .filter(r -> r.getScore() != null && r.getScore() >= 0.5 && r.getScore() < 3.0)
                    .count();

            // 更新律师评分
            LambdaUpdateWrapper<LawyerUser> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(LawyerUser::getId, lawyerUserId);
            updateWrapper.set(LawyerUser::getServiceScore, serviceScore);
            updateWrapper.set(LawyerUser::getGoodReviewCount, (int) goodCount);
            updateWrapper.set(LawyerUser::getMediumReviewCount, (int) mediumCount);
            updateWrapper.set(LawyerUser::getBadReviewCount, (int) badCount);
            int result = lawyerUserMapper.update(null, updateWrapper);

            if (result > 0) {
                log.info("更新律师评分成功，律师ID={}, 平均评分={}, 服务评分={}, 好评数={}, 中评数={}, 差评数={}",
                        lawyerUserId, averageRating, serviceScore, goodCount, mediumCount, badCount);
            }
        } catch (Exception e) {
            log.error("更新律师评分异常，律师ID={}, 错误信息={}", lawyerUserId, e.getMessage(), e);
        }
    }

    @Override
    public R<OrderReviewDetailVo> getOrderReviewDetail(Integer orderId, Integer currentUserId) {
        log.info("StoreCommentServiceImpl.getOrderReviewDetail?orderId={}, currentUserId={}", orderId, currentUserId);

        if (orderId == null) {
            return R.fail("订单ID不能为空");
        }

        // 根据orderId从store_comment表查询评价详情
        // 条件：business_id=orderId, store_id为空, business_type=5
        LambdaQueryWrapper<StoreComment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreComment::getBusinessId, orderId)
                .isNull(StoreComment::getStoreId)
                .eq(StoreComment::getBusinessType, 5)
                .eq(StoreComment::getDeleteFlag, 0);
        
        StoreComment review = this.getOne(queryWrapper);
        if (review == null) {
            log.warn("评价不存在，orderId={}", orderId);
            return R.fail("评价不存在");
        }

        // 构建 OrderReviewVo
        OrderReviewVo reviewVo = new OrderReviewVo();
        reviewVo.setId(review.getId());
        reviewVo.setOrderId(orderId);
        reviewVo.setUserId(review.getUserId());
        reviewVo.setReviewContent(review.getCommentContent());
        reviewVo.setOverallRating(review.getScore());
        reviewVo.setIsAnonymous(review.getIsAnonymous());
        reviewVo.setLikeCount(review.getLikeCount());
        reviewVo.setCreatedTime(review.getCreatedTime());

        // 查询订单信息获取订单编号
        LawyerConsultationOrder order = lawyerConsultationOrderMapper.selectById(orderId);
        if (order != null) {
            reviewVo.setOrderNumber(order.getOrderNumber());
            reviewVo.setLawyerUserId(order.getLawyerUserId());
        }

        // 查询用户信息
        if (review.getUserId() != null) {
            LifeUser lifeUser = lifeUserMapper.selectById(review.getUserId());
            if (lifeUser != null) {
                reviewVo.setUserName(lifeUser.getUserName());
                reviewVo.setUserAvatar(lifeUser.getUserImage());
            }
        }

        // 查询律师信息
        Integer lawyerId = review.getLawyerId();
        if (lawyerId == null && order != null) {
            lawyerId = order.getLawyerUserId();
        }
        if (lawyerId != null) {
            LawyerUser lawyerUser = lawyerUserMapper.selectById(lawyerId);
            if (lawyerUser != null) {
                reviewVo.setLawyerUserId(lawyerId);
                reviewVo.setLawyerName(lawyerUser.getName());
                reviewVo.setLawyerAvatar(lawyerUser.getHeadImg());
                
                // 查询律所信息
                if (lawyerUser.getFirmId() != null) {
                    try {
                        LawFirm lawFirm = lawFirmMapper.selectById(lawyerUser.getFirmId());
                        if (lawFirm != null && StringUtils.isNotEmpty(lawFirm.getFirmName())) {
                            reviewVo.setLawFirmName(lawFirm.getFirmName());
                        }
                    } catch (Exception e) {
                        log.warn("查询律所信息失败，firmId={}", lawyerUser.getFirmId(), e);
                    }
                }
            }
        }

        // 解析评分信息（从otherScore字段）
        if (StringUtils.isNotEmpty(review.getOtherScore())) {
            try {
                List<com.alibaba.fastjson.JSONObject> scoreList = JSONArray.parseArray(review.getOtherScore(), com.alibaba.fastjson.JSONObject.class);
                if (scoreList != null && !scoreList.isEmpty()) {
                    for (com.alibaba.fastjson.JSONObject scoreObj : scoreList) {
                        if (scoreObj != null) {
                            String name = scoreObj.getString("name");
                            String rateScore = scoreObj.getString("rateScore");
                            if (StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(rateScore)) {
                                try {
                                    Double scoreValue = Double.parseDouble(rateScore);
                                    if ("服务态度".equals(name)) {
                                        reviewVo.setServiceAttitudeRating(scoreValue);
                                    } else if ("响应时间".equals(name)) {
                                        reviewVo.setResponseTimeRating(scoreValue);
                                    } else if ("专业能力".equals(name)) {
                                        reviewVo.setProfessionalAbilityRating(scoreValue);
                                    }
                                } catch (NumberFormatException e) {
                                    log.warn("解析评分失败，name={}, rateScore={}", name, rateScore, e);
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.warn("解析otherScore失败，otherScore={}", review.getOtherScore(), e);
            }
        }

        // 查询评价图片（从store_img表，img_type=8, business_id=orderId）
        List<String> imageUrls = new ArrayList<>();
        if (StringUtils.isNotEmpty(review.getImgId())) {
            String[] imgIds = review.getImgId().split(",");
            if (imgIds.length > 0) {
                List<Integer> imgIdList = new ArrayList<>();
                for (String imgIdStr : imgIds) {
                    if (StringUtils.isNotEmpty(imgIdStr.trim())) {
                        try {
                            imgIdList.add(Integer.parseInt(imgIdStr.trim()));
                        } catch (NumberFormatException e) {
                            log.warn("图片ID格式错误，imgId={}", imgIdStr, e);
                        }
                    }
                }
                if (!imgIdList.isEmpty()) {
                    LambdaQueryWrapper<StoreImg> imgWrapper = new LambdaQueryWrapper<>();
                    imgWrapper.in(StoreImg::getId, imgIdList)
                            .eq(StoreImg::getDeleteFlag, 0)
                            .orderByAsc(StoreImg::getImgSort);
                    List<StoreImg> storeImgs = storeImgMapper.selectList(imgWrapper);
                    if (CollectionUtils.isNotEmpty(storeImgs)) {
                        imageUrls = storeImgs.stream()
                                .map(StoreImg::getImgUrl)
                                .filter(url -> StringUtils.isNotEmpty(url))
                                .collect(Collectors.toList());
                    }
                }
            }
        }
        reviewVo.setReviewImages(imageUrls);

        // 检查当前用户是否已点赞
        if (currentUserId != null) {
            LambdaQueryWrapper<LifeLikeRecord> likeWrapper = new LambdaQueryWrapper<>();
            likeWrapper.eq(LifeLikeRecord::getType, "7")
                    .eq(LifeLikeRecord::getDianzanId, String.valueOf(currentUserId))
                    .eq(LifeLikeRecord::getHuifuId, String.valueOf(review.getId()))
                    .eq(LifeLikeRecord::getDeleteFlag, 0);
            long likeCount = lifeLikeRecordMapper.selectCount(likeWrapper);
            reviewVo.setIsLiked(likeCount > 0 ? 1 : 0);
        } else {
            reviewVo.setIsLiked(0);
        }

        // 查询评论列表（business_type=6，business_id=评价ID）
        Integer reviewId = review.getId();
        R<List<ReviewCommentVo>> commentsResult = getReviewCommentListByReviewId(reviewId, currentUserId);
        List<ReviewCommentVo> comments = new ArrayList<>();
        if (commentsResult.getCode() == 200 && commentsResult.getData() != null) {
            comments = commentsResult.getData();
        }

        // 统计评论总数（包括首评和回复）
        int totalCommentCount = comments.size();
        for (ReviewCommentVo comment : comments) {
            if (comment.getReplies() != null) {
                totalCommentCount += comment.getReplies().size();
            }
        }

        // 构建返回结果
        OrderReviewDetailVo detailVo = new OrderReviewDetailVo();
        detailVo.setReview(reviewVo);
        detailVo.setComments(comments);
        detailVo.setTotalCommentCount(totalCommentCount);
        detailVo.setLikeCount(reviewVo.getLikeCount() != null ? reviewVo.getLikeCount() : 0);
        detailVo.setIsLiked(reviewVo.getIsLiked() != null ? reviewVo.getIsLiked() : 0);

        log.info("查询评价详情成功，orderId={}, reviewId={}", orderId, reviewId);
        return R.data(detailVo);
    }

    @Override
    public R<Boolean> likeOrderReview(Integer reviewId, Integer userId) {
        log.info("StoreCommentServiceImpl.likeOrderReview?reviewId={}, userId={}", reviewId, userId);

        // 验证评价是否存在
        StoreComment review = this.getById(reviewId);
        if (review == null || review.getDeleteFlag() == 1 || review.getBusinessType() != 5) {
            return R.fail("评价不存在或已删除");
        }

        // 检查是否已点赞（type=7 表示订单评价点赞）
        LambdaQueryWrapper<LifeLikeRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LifeLikeRecord::getType, "7")
                .eq(LifeLikeRecord::getDianzanId, String.valueOf(userId))
                .eq(LifeLikeRecord::getHuifuId, String.valueOf(reviewId))
                .eq(LifeLikeRecord::getDeleteFlag, 0);
        List<LifeLikeRecord> records = lifeLikeRecordMapper.selectList(queryWrapper);

        if (CollectionUtils.isEmpty(records)) {
            // 插入点赞记录
            LifeLikeRecord likeRecord = new LifeLikeRecord();
            likeRecord.setDianzanId(String.valueOf(userId));
            likeRecord.setHuifuId(String.valueOf(reviewId));
            likeRecord.setType("7");
            likeRecord.setCreatedTime(new Date());
            likeRecord.setCreatedUserId(userId);
            lifeLikeRecordMapper.insert(likeRecord);

            // 更新评价点赞数
            LambdaUpdateWrapper<StoreComment> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(StoreComment::getId, reviewId);
            updateWrapper.setSql("like_count = like_count + 1");
            int result = storeCommentMapper.update(null, updateWrapper);

            if (result > 0) {
                return R.data(true, "点赞成功");
            } else {
                return R.fail("点赞失败");
            }
        } else {
            return R.data(true, "已点赞");
        }
    }

    @Override
    public R<Boolean> cancelLikeOrderReview(Integer reviewId, Integer userId) {
        log.info("StoreCommentServiceImpl.cancelLikeOrderReview?reviewId={}, userId={}", reviewId, userId);

        // 查询点赞记录
        LambdaQueryWrapper<LifeLikeRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LifeLikeRecord::getType, "7")
                .eq(LifeLikeRecord::getDianzanId, String.valueOf(userId))
                .eq(LifeLikeRecord::getHuifuId, String.valueOf(reviewId))
                .eq(LifeLikeRecord::getDeleteFlag, 0);
        List<LifeLikeRecord> records = lifeLikeRecordMapper.selectList(queryWrapper);

        if (!CollectionUtils.isEmpty(records)) {
            // 删除点赞记录（逻辑删除）
            for (LifeLikeRecord record : records) {
                lifeLikeRecordMapper.deleteById(record.getId());
            }

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

            if (result > 0) {
                return R.data(true, "取消点赞成功");
            } else {
                return R.fail("取消点赞失败");
            }
        } else {
            return R.data(true, "未点赞");
        }
    }

    @Override
    public R<IPage<OrderReviewVo>> getOrderReviewList(int page, int size, Integer orderId, Integer lawyerUserId, Integer userId, Integer currentUserId) {
        log.info("StoreCommentServiceImpl.getOrderReviewList?page={}, size={}, orderId={}, lawyerUserId={}, userId={}, currentUserId={}",
                page, size, orderId, lawyerUserId, userId, currentUserId);

        // 构建查询条件
        LambdaQueryWrapper<StoreComment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreComment::getBusinessType, 5)
                .eq(StoreComment::getDeleteFlag, 0);
        
        if (orderId != null) {
            queryWrapper.eq(StoreComment::getOrderId, orderId);
        }
        if (lawyerUserId != null) {
            queryWrapper.eq(StoreComment::getLawyerId, lawyerUserId);
        }
        if (userId != null) {
            queryWrapper.eq(StoreComment::getUserId, userId);
        }
        
        queryWrapper.orderByDesc(StoreComment::getCreatedTime);

        // 分页查询
        Page<StoreComment> pageObj = new Page<>(page, size);
        IPage<StoreComment> commentPage = this.page(pageObj, queryWrapper);

        // 转换为 OrderReviewVo（需要关联用户和律师信息）
        // TODO: 需要自定义查询或手动构建 OrderReviewVo，关联用户和律师信息
        Page<OrderReviewVo> resultPage = new Page<>(page, size);
        resultPage.setTotal(commentPage.getTotal());
        resultPage.setPages(commentPage.getPages());
        
        List<OrderReviewVo> voList = new ArrayList<>();
        for (StoreComment comment : commentPage.getRecords()) {
            OrderReviewVo vo = new OrderReviewVo();
            vo.setId(comment.getId());
            vo.setOrderId(comment.getOrderId());
            vo.setUserId(comment.getUserId());
            vo.setLawyerUserId(comment.getLawyerId());
            vo.setOverallRating(comment.getScore());
            vo.setReviewContent(comment.getCommentContent());
            vo.setIsAnonymous(comment.getIsAnonymous());
            vo.setLikeCount(comment.getLikeCount());
            vo.setCreatedTime(comment.getCreatedTime());
            // TODO: 需要查询并设置用户名称、头像、律师信息等
            voList.add(vo);
        }
        resultPage.setRecords(voList);

        return R.data(resultPage);
    }

    @Override
    public R<OrderReviewVo> getOrderReviewByOrderId(Integer orderId, Integer currentUserId) {
        log.info("StoreCommentServiceImpl.getOrderReviewByOrderId?orderId={}, currentUserId={}", orderId, currentUserId);

        LambdaQueryWrapper<StoreComment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreComment::getOrderId, orderId)
                .eq(StoreComment::getBusinessType, 5)
                .eq(StoreComment::getDeleteFlag, 0)
                .orderByDesc(StoreComment::getCreatedTime)
                .last("LIMIT 1");
        
        StoreComment comment = this.getOne(queryWrapper);
        if (comment == null) {
            return R.fail("评价不存在");
        }

        // 转换为 OrderReviewVo
        OrderReviewVo vo = new OrderReviewVo();
        vo.setId(comment.getId());
        vo.setOrderId(comment.getOrderId());
        vo.setUserId(comment.getUserId());
        vo.setLawyerUserId(comment.getLawyerId());
        vo.setOverallRating(comment.getScore());
        vo.setReviewContent(comment.getCommentContent());
        vo.setIsAnonymous(comment.getIsAnonymous());
        vo.setLikeCount(comment.getLikeCount());
        vo.setCreatedTime(comment.getCreatedTime());
        // TODO: 需要查询并设置用户名称、头像、律师信息等

        return R.data(vo);
    }

    // ==================== 评价评论相关方法实现（迁移自 ReviewCommentService）====================

    @Override
    public R<StoreComment> createReviewComment(StoreComment comment) {
        log.info("StoreCommentServiceImpl.createReviewComment?comment={}", comment);

        // 参数校验
        if (comment == null) {
            return R.fail("评论信息不能为空");
        }
        if (comment.getBusinessId() == null) {
            return R.fail("评价ID不能为空");
        }
        if (comment.getCommentContent() == null || comment.getCommentContent().trim().isEmpty()) {
            return R.fail("评论内容不能为空");
        }
        Integer userId = comment.getUserId();
        if (userId == null) {
            return R.fail("用户ID不能为空");
        }

        // 验证评价是否存在（business_type=5）
        StoreComment review = this.getById(comment.getBusinessId());
        if (review == null || review.getDeleteFlag() == 1 || review.getBusinessType() != 5) {
            return R.fail("评价不存在或已删除");
        }

        // 设置评论属性
        comment.setBusinessType(6); // 订单评价的评论
        comment.setBusinessId(review.getId()); // 评价ID作为业务ID
        comment.setOrderId(review.getOrderId()); // 从评价中获取订单ID
        comment.setLawyerId(review.getLawyerId()); // 从评价中获取律师ID
        comment.setLikeCount(0);
        comment.setReplyId(null); // 首评没有reply_id
        comment.setCreatedUserId(userId);
        comment.setCreatedTime(new Date());

        boolean success = this.save(comment);
        if (success) {
            log.info("创建评论成功，评论ID={}", comment.getId());
            return R.data(comment, "评论成功");
        } else {
            log.error("创建评论失败");
            return R.fail("创建评论失败");
        }
    }

    @Override
    public R<List<ReviewCommentVo>> getReviewCommentListByReviewId(Integer reviewId, Integer currentUserId) {
        log.info("StoreCommentServiceImpl.getReviewCommentListByReviewId?reviewId={}, currentUserId={}", reviewId, currentUserId);

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

        // 查询评论列表（business_type=6，business_id=reviewId，reply_id为null表示首评）
        LambdaQueryWrapper<StoreComment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreComment::getBusinessId, reviewId)
                .eq(StoreComment::getBusinessType, 6)
                .isNull(StoreComment::getReplyId) // 首评
                .eq(StoreComment::getDeleteFlag, 0)
                .orderByDesc(StoreComment::getCreatedTime);
        
        List<StoreComment> comments = this.list(queryWrapper);

        // 转换为 ReviewCommentVo 并加载回复列表
        List<ReviewCommentVo> voList = new ArrayList<>();
        for (StoreComment comment : comments) {
            ReviewCommentVo vo = new ReviewCommentVo();
            vo.setId(comment.getId());
            vo.setReviewId(comment.getBusinessId());
            vo.setSendUserId(comment.getUserId());
            vo.setCommentContent(comment.getCommentContent());
            vo.setLikeCount(comment.getLikeCount());
            vo.setCreatedTime(comment.getCreatedTime());
            // TODO: 需要查询并设置用户名称、头像等
            
            // 检查是否已点赞
            if (currentUserId != null) {
                LambdaQueryWrapper<LifeLikeRecord> likeWrapper = new LambdaQueryWrapper<>();
                likeWrapper.eq(LifeLikeRecord::getType, "8")
                        .eq(LifeLikeRecord::getDianzanId, String.valueOf(currentUserId))
                        .eq(LifeLikeRecord::getHuifuId, String.valueOf(comment.getId()))
                        .eq(LifeLikeRecord::getDeleteFlag, 0);
                vo.setIsLiked(lifeLikeRecordMapper.selectCount(likeWrapper) > 0 ? 1 : 0);
            } else {
                vo.setIsLiked(0);
            }

            // 查询回复列表
            R<List<ReviewCommentVo>> repliesResult = getReviewReplyListByHeadId(comment.getId(), currentUserId);
            if (repliesResult.getCode() == 200) {
                vo.setReplies(repliesResult.getData());
            }

            voList.add(vo);
        }

        return R.data(voList);
    }

    @Override
    public R<Boolean> likeReviewComment(ReviewCommentRequestDto requestDto) {
        log.info("StoreCommentServiceImpl.likeReviewComment?requestDto={}", requestDto);

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

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

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

        // 检查是否已点赞（type=8 表示评论点赞）
        LambdaQueryWrapper<LifeLikeRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LifeLikeRecord::getType, "8")
                .eq(LifeLikeRecord::getDianzanId, String.valueOf(userId))
                .eq(LifeLikeRecord::getHuifuId, String.valueOf(commentId))
                .eq(LifeLikeRecord::getDeleteFlag, 0);
        List<LifeLikeRecord> records = lifeLikeRecordMapper.selectList(queryWrapper);

        if (CollectionUtils.isEmpty(records)) {
            // 插入点赞记录
            LifeLikeRecord likeRecord = new LifeLikeRecord();
            likeRecord.setDianzanId(String.valueOf(userId));
            likeRecord.setHuifuId(String.valueOf(commentId));
            likeRecord.setType("8");
            likeRecord.setCreatedTime(new Date());
            likeRecord.setCreatedUserId(userId);
            lifeLikeRecordMapper.insert(likeRecord);

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

            if (result > 0) {
                return R.data(true, "点赞成功");
            } else {
                return R.fail("点赞失败");
            }
        } else {
            return R.data(true, "已点赞");
        }
    }

    @Override
    public R<Boolean> cancelLikeReviewComment(ReviewCommentRequestDto requestDto) {
        log.info("StoreCommentServiceImpl.cancelLikeReviewComment?requestDto={}", requestDto);

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

        // 查询点赞记录
        LambdaQueryWrapper<LifeLikeRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LifeLikeRecord::getType, "8")
                .eq(LifeLikeRecord::getDianzanId, String.valueOf(userId))
                .eq(LifeLikeRecord::getHuifuId, String.valueOf(commentId))
                .eq(LifeLikeRecord::getDeleteFlag, 0);
        List<LifeLikeRecord> records = lifeLikeRecordMapper.selectList(queryWrapper);

        if (!CollectionUtils.isEmpty(records)) {
            // 删除点赞记录（逻辑删除）
            for (LifeLikeRecord record : records) {
                lifeLikeRecordMapper.deleteById(record.getId());
            }

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

            if (result > 0) {
                return R.data(true, "取消点赞成功");
            } else {
                return R.fail("取消点赞失败");
            }
        } else {
            return R.data(true, "未点赞");
        }
    }

    @Override
    public R<StoreComment> createReviewReply(ReviewReplyDto replyDto) {
        log.info("StoreCommentServiceImpl.createReviewReply?replyDto={}", replyDto);

        // 参数校验
        if (replyDto == null) {
            return R.fail("回复信息不能为空");
        }
        if (replyDto.getCommentId() == null) {
            return R.fail("评论ID不能为空");
        }
        if (replyDto.getReplyContent() == null || replyDto.getReplyContent().trim().isEmpty()) {
            return R.fail("回复内容不能为空");
        }
        Integer userId = replyDto.getUserId();
        if (userId == null) {
            return R.fail("用户ID不能为空");
        }

        // 验证首评是否存在
        StoreComment headComment = this.getById(replyDto.getCommentId());
        if (headComment == null || headComment.getDeleteFlag() == 1 || headComment.getBusinessType() != 6) {
            return R.fail("评论不存在或已删除");
        }
        // 验证是否为首评（reply_id为null表示首评）
        if (headComment.getReplyId() != null) {
            return R.fail("只能回复首评");
        }

        // 创建回复
        StoreComment reply = new StoreComment();
        reply.setBusinessId(headComment.getBusinessId()); // 评价ID
        reply.setBusinessType(6); // 订单评价的评论
        reply.setUserId(userId);
        reply.setCommentContent(replyDto.getReplyContent());
        reply.setOrderId(headComment.getOrderId());
        reply.setLawyerId(headComment.getLawyerId());
        reply.setReplyId(replyDto.getCommentId()); // 指向首评ID
        reply.setLikeCount(0);
        reply.setCreatedUserId(userId);
        reply.setCreatedTime(new Date());

        boolean success = this.save(reply);
        if (success) {
            log.info("创建回复成功，回复ID={}", reply.getId());
            return R.data(reply, "回复成功");
        } else {
            log.error("创建回复失败");
            return R.fail("创建回复失败");
        }
    }

    @Override
    public R<List<ReviewCommentVo>> getReviewReplyListByHeadId(Integer headId, Integer currentUserId) {
        log.info("StoreCommentServiceImpl.getReviewReplyListByHeadId?headId={}, currentUserId={}", headId, currentUserId);

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

        // 查询回复列表（business_type=6，reply_id=headId）
        LambdaQueryWrapper<StoreComment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreComment::getReplyId, headId)
                .eq(StoreComment::getBusinessType, 6)
                .eq(StoreComment::getDeleteFlag, 0)
                .orderByAsc(StoreComment::getCreatedTime);
        
        List<StoreComment> replies = this.list(queryWrapper);

        // 转换为 ReviewCommentVo
        List<ReviewCommentVo> voList = new ArrayList<>();
        for (StoreComment reply : replies) {
            ReviewCommentVo vo = new ReviewCommentVo();
            vo.setId(reply.getId());
            vo.setReviewId(reply.getBusinessId());
            vo.setSendUserId(reply.getUserId());
            vo.setCommentContent(reply.getCommentContent());
            vo.setLikeCount(reply.getLikeCount());
            vo.setCreatedTime(reply.getCreatedTime());
            // TODO: 需要查询并设置用户名称、头像等
            
            // 检查是否已点赞
            if (currentUserId != null) {
                LambdaQueryWrapper<LifeLikeRecord> likeWrapper = new LambdaQueryWrapper<>();
                likeWrapper.eq(LifeLikeRecord::getType, "8")
                        .eq(LifeLikeRecord::getDianzanId, String.valueOf(currentUserId))
                        .eq(LifeLikeRecord::getHuifuId, String.valueOf(reply.getId()))
                        .eq(LifeLikeRecord::getDeleteFlag, 0);
                vo.setIsLiked(lifeLikeRecordMapper.selectCount(likeWrapper) > 0 ? 1 : 0);
            } else {
                vo.setIsLiked(0);
            }

            voList.add(vo);
        }

        return R.data(voList);
    }

    @Override
    public R<Boolean> deleteReviewReply(Integer replyId, Integer userId) {
        log.info("StoreCommentServiceImpl.deleteReviewReply?replyId={}, userId={}", replyId, userId);

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

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

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

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

        if (success) {
            log.info("删除回复成功，回复ID={}", replyId);
            return R.data(true, "删除成功");
        } else {
            log.error("删除回复失败，回复ID={}", replyId);
            return R.fail("删除回复失败");
        }
    }
}
