package shop.alien.job.store;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import shop.alien.entity.store.*;
import shop.alien.entity.result.R;
import shop.alien.mapper.LifeNoticeMapper;
import shop.alien.util.type.LifeNoticeUtil;
import shop.alien.mapper.StoreCommentAppealMapper;
import shop.alien.mapper.StoreCommentMapper;
import shop.alien.mapper.StoreUserMapper;
import shop.alien.mapper.CommonRatingMapper;
import shop.alien.mapper.CommonCommentMapper;
import shop.alien.mapper.LifeLikeRecordMapper;
import shop.alien.mapper.StoreInfoMapper;
import shop.alien.util.common.constant.CommentSourceTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import java.util.stream.Collectors;

import java.net.URI;
import java.net.URISyntaxException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 调用AI差评申诉辅助系统服务类
 *
 * @author fcw
 * @date 2025/11/20 14:21
 */
@Slf4j
@Component
@RequiredArgsConstructor
@EnableScheduling
public class BadReviewAppealJob {

    private final RestTemplate restTemplate;

    private final StoreCommentAppealMapper storeCommentAppealMapper;

    private final StoreCommentMapper storeCommentMapper;
    private final StoreUserMapper storeUserMapper;
    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeNoticeUtil lifeNoticeUtil;
    private final CommonRatingMapper commonRatingMapper;
    private final CommonCommentMapper commonCommentMapper;
    private final LifeLikeRecordMapper lifeLikeRecordMapper;
    private final StoreInfoMapper storeInfoMapper;

//    @Value("${third-party-login.base-url}")
//    private String loginUrl;

    @Value("${third-party-user-name-admin.base-url}")
    private String userName;

    @Value("${third-party-pass-word.base-url}")
    private String passWord;

    @Value("${third-party-login.base-url}")
    private String loginUrl;

    @Value("${third-party-analyzeUrl.base-url}")
    private String analyzeUrl;

    @Value("${third-party-resultUrl.base-url}")
    private String resultUrl;

    /**
     * 差评申述置信度分析接口地址
     * 例如: http://192.168.2.250:9004/api/v1/analyze 或通过网关: http://192.168.2.250:9000/ai/auto_review/api/v1/analyze
     */
//    @Value("${bad-review-analyze.base-url}")
//    private String analyzeUrl;

    /**
     * 调用AI服务获取Token
     */
    @XxlJob("getBadReviewAppealJob")
    public R<String> getBadReviewAppealJob() {
//        String accessToken = fetchAiServiceToken();
//        if (!StringUtils.hasText(accessToken)) {
//            return R.fail("调用差评申诉辅助系统登录任务执行失败 返回异常");
//        }
        return R.success("");
    }


    @XxlJob("getAppealCompletedResult")
    public R<String> getAppealCompletedResult() {
//        String accessToken = fetchAiServiceToken();
//        if (!StringUtils.hasText(accessToken)) {
//            return R.fail("调用差评申诉辅助系统登录任务执行失败 返回异常");
//        }
        return R.success("");
    }

    private R<String> getNegativeReviewAppealCompletedResult(String accessToken) {


        HttpHeaders analyzeHeaders = new HttpHeaders();
        analyzeHeaders.setContentType(MediaType.APPLICATION_JSON);
        analyzeHeaders.set("Authorization", "Bearer " + accessToken);
        // 查询所有状态为处理中的申诉
        List<StoreCommentAppeal> pendingAppeals = storeCommentAppealMapper.getPendingAppeals();
        // 循环调用查询结果接口
        for (StoreCommentAppeal appeal : pendingAppeals) {
            String completedUrl = buildCompletedUrl(appeal.getRecordId());

            ResponseEntity<String> analyzeResp;

            RestTemplate restTemplateWithAuth = new RestTemplate();
            List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
            interceptors.add((request, body, execution) -> {
                request.getHeaders().set("Authorization", "Bearer " + accessToken);
                return execution.execute(request, body);
            });
            restTemplateWithAuth.setInterceptors(interceptors);

            ResponseEntity<String> response = null;

            try {
                analyzeResp = restTemplateWithAuth.getForEntity(completedUrl, String.class);

                if (analyzeResp != null && analyzeResp.getStatusCodeValue() == 200) {
                    String analyzeBody = analyzeResp.getBody();
                    log.info("差评申述置信度分析提交成功, 返回: {}", analyzeBody);

                    JSONObject analyzeJson = JSONObject.parseObject(analyzeBody);
                    Integer respCode = analyzeJson.getInteger("code");
                    JSONObject dataJsonObj = analyzeJson.getJSONObject("data");

                    // 检查AI响应码：202表示分析尚未完成
                    if (respCode != null && respCode == 202) {
                        JSONObject detailsObj = analyzeJson.getJSONObject("details");
                        String status = detailsObj != null ? detailsObj.getString("analysis_status") : "unknown";
                        log.info("差评申述置信度分析尚未完成（code=202），申诉ID: {}，recordId: {}，状态: {}，等待下次轮询", 
                            appeal.getId(), appeal.getRecordId(), status);
                        continue;
                    }

                    // 检查AI响应码：200表示分析完成
                    if (respCode == null || respCode != 200) {
                        log.warn("差评申述置信度分析返回非200响应码，申诉ID: {}，code: {}，message: {}", 
                            appeal.getId(), respCode, analyzeJson.getString("message"));
                        continue;
                    }

                    if (dataJsonObj == null) {
                        log.error("差评申述置信度分析返回数据为空，申诉ID: {}", appeal.getId());
                        continue;
                    }

                    // 检查分析状态
                    String analysisStatus = dataJsonObj.getString("analysis_status");
                    if (!"completed".equals(analysisStatus)) {
                        log.info("差评申述置信度分析尚未完成，申诉ID: {}，recordId: {}，状态: {}", 
                            appeal.getId(), appeal.getRecordId(), analysisStatus);
                        continue;
                    }

                    // 获取置信度值
                    Double userConfidence = dataJsonObj.getDouble("user_confidence");
                    Double merchantConfidence = dataJsonObj.getDouble("merchant_confidence");

                    if (userConfidence == null || merchantConfidence == null) {
                        log.error("差评申述置信度分析返回置信度为空，申诉ID: {}，user_confidence: {}，merchant_confidence: {}", 
                            appeal.getId(), userConfidence, merchantConfidence);
                        continue;
                    }

                    // 谁分数多算谁赢，平分的话算用户赢
                    log.info("差评申述置信度分析结果，申诉ID: {}，user_confidence: {}，merchant_confidence: {}", 
                        appeal.getId(), userConfidence, merchantConfidence);

                    StoreCommentAppeal sCommentAppeal = new StoreCommentAppeal();
                    sCommentAppeal.setRecordId(appeal.getRecordId());
                    sCommentAppeal.setAppealAiApproval(dataJsonObj.toJSONString());

                    // 谁分数多算谁赢，平分的话算用户赢
                    if (merchantConfidence > userConfidence) {
                        //  商家分数 > 用户分数，商家赢（同意）
                        sCommentAppeal.setAppealStatus(2);
                        sCommentAppeal.setFinalResult("已同意");
                        log.info("差评申述置信度判断：商家赢（user_confidence: {} >= merchant_confidence: {}），申诉通过，申诉ID: {}",
                            userConfidence, merchantConfidence, appeal.getId());
                        
                        // 删除评价和评论（与 StoreCommentAppealServiceImpl 逻辑一致）
                        Integer ratingId = appeal.getCommentId(); // commentId 存储的是评价ID（common_rating.id）
                        if (ratingId != null) {
                            deleteRatingAndComments(ratingId);
                        }
                    } else {
                        //  用户分数 >= 商家分数，用户赢（驳回）
                        sCommentAppeal.setAppealStatus(1);
                        sCommentAppeal.setFinalResult("已驳回");
                        log.info("差评申述置信度判断：用户赢（user_confidence: {} < merchant_confidence: {}），申诉驳回，申诉ID: {}",
                            userConfidence, merchantConfidence, appeal.getId());
                    }

                    storeCommentAppealMapper.updateByRecordId(appeal.getRecordId(),
                            sCommentAppeal.getAppealStatus(),
                            sCommentAppeal.getFinalResult());

                    // 发送通知
                    LifeNotice lifeMessage = new LifeNotice();
                    StoreUser storeUser = storeUserMapper.selectOne(new QueryWrapper<StoreUser>().eq("store_id", appeal.getStoreId()));
                    if (storeUser == null) {
                        log.warn("发送申诉通知失败，未找到店铺用户，申诉ID: {}，店铺ID: {}", appeal.getId(), appeal.getStoreId());
                        continue;
                    }
                    String title = "申诉通知";
                    lifeMessage.setTitle(title);
                    lifeMessage.setReceiverId("store_" + storeUser.getPhone());
                    String text = "您的评论申诉结果为" + sCommentAppeal.getFinalResult();
                    lifeMessage.setContext(text);
                    lifeMessage.setSenderId("system");
                    lifeMessage.setIsRead(0);
                    lifeMessage.setNoticeType(1);
                    lifeNoticeUtil.fillUserTypeAndRefId(lifeMessage);
                    int insertResult = lifeNoticeMapper.insert(lifeMessage);
                    if (insertResult > 0) {
                        log.info("申诉通知发送成功，申诉ID: {}，通知标题: {}", appeal.getId(), title);
                    } else {
                        log.error("申诉通知发送失败，申诉ID: {}，通知标题: {}", appeal.getId(), title);
                    }

                } else {
                    if (analyzeResp != null) {
                        log.error("调用差评申述置信度分析接口失败, http状态: {}", analyzeResp.getStatusCode());
                        R.fail("调用差评申述置信度分析接口失败, http状态: " + analyzeResp.getStatusCode());
                    }
                }
            } catch (Exception e) {
                log.error("调用差评申述查询结果接口异常", e);
            }
        }
        return R.success("调用差评申述置信度分析结果接口完成");
    }




    private R<String> invokeAnalyzeTask(String token) {
        log.info("开始调用差评申述置信度分析接口, url: {}", analyzeUrl);

        HttpHeaders analyzeHeaders = new HttpHeaders();
        analyzeHeaders.setContentType(MediaType.APPLICATION_JSON);
        analyzeHeaders.set("Authorization", "Bearer " + token);

        // 查询一段时间内的差评申述
        // 循环插入
        List<Map<String, Object>> appealList = storeCommentAppealMapper.getAppealList();

        if (appealList == null || appealList.isEmpty()) {
            log.info("没有需要处理的差评申述");
            return R.success("没有需要处理的差评申述");
        }

        for (Map<String, Object> storeCommentAppeal : appealList) {
            Map<String, Object> analyzeRequest = new HashedMap<>();

            // 商家申诉材料
            analyzeRequest.put("merchant_material",
                    storeCommentAppeal.get("appeal_reason") == null ? "" : storeCommentAppeal.get("appeal_reason").toString());

            // 用户差评内容
            analyzeRequest.put("user_material",
                    storeCommentAppeal.get("comment_content") == null ? "" : storeCommentAppeal.get("comment_content").toString());

            // 商家图片：支持多张，直接使用图片URL
            List<String> merchantImages = new ArrayList<>();
            String imgUrls = storeCommentAppeal.get("img_url") == null ? "" : storeCommentAppeal.get("img_url").toString();
            if (StringUtils.hasText(imgUrls)) {
                // 假设 img_url 是多个图片用逗号分隔的字符串
                for (String imageUrl : imgUrls.split(",")) {
                    merchantImages.add(imageUrl.trim());
                }
            }
            analyzeRequest.put("merchant_images", merchantImages);

            // 用户图片：同理
            List<String> userImages = new ArrayList<>();
            String userImgUrls = storeCommentAppeal.get("user_img_url") == null ? "" : storeCommentAppeal.get("user_img_url").toString();
            if (StringUtils.hasText(userImgUrls)) {
                for (String imageUrl : userImgUrls.split(",")) {
//                    String base64 = convertImageToBase64(imageUrl.trim());
//                    if (StringUtils.hasText(base64)) {
                        userImages.add(imageUrl.trim());
                    }
//                }
            }
            analyzeRequest.put("user_images", userImages);

            // 其他字段
            analyzeRequest.put("case_id", storeCommentAppeal.get("comment_id") == null ? "" : storeCommentAppeal.get("comment_id").toString());
            analyzeRequest.put("order_id", storeCommentAppeal.get("business_id") == null ? "" : storeCommentAppeal.get("business_id").toString());

            HttpEntity<Map<String, Object>> analyzeEntity = new HttpEntity<>(analyzeRequest, analyzeHeaders);

            ResponseEntity<String> analyzeResp = null;
            try {
                analyzeResp = restTemplate.postForEntity(analyzeUrl, analyzeEntity, String.class);
            } catch (org.springframework.web.client.HttpServerErrorException.ServiceUnavailable e) {
                log.error("调用差评申述置信度分析接口返回503 Service Unavailable错误: {}", e.getResponseBodyAsString());
                continue;
            } catch (Exception e) {
                log.error("调用差评申述置信度分析接口异常", e);
                continue;
            }

            if (analyzeResp != null && analyzeResp.getStatusCodeValue() == 200) {
                String analyzeBody = analyzeResp.getBody();
                log.info("差评申述置信度分析提交成功, 返回: {}", analyzeBody);

                JSONObject analyzeJson = JSONObject.parseObject(analyzeBody);
                JSONObject dataJsonObj = analyzeJson.getJSONObject("data");

                if (dataJsonObj == null) {
                    log.error("差评申述置信度分析返回数据为空");
                    R.fail("差评申述置信度分析返回数据为空");
                    continue;
                }

                // 获取record_id用于后续查询
                Integer recordId = dataJsonObj.getInteger("record_id");
                if (recordId == null) {
                    log.error("差评申述置信度分析返回record_id为空");
                    R.fail("差评申述置信度分析返回record_id为空");
                    continue;
                }

                //修改评论状态为"处理中"
                StoreCommentAppeal sCommentAppeal = new StoreCommentAppeal();
                sCommentAppeal.setId((Integer) storeCommentAppeal.get("id"));
                sCommentAppeal.setAppealStatus(3);
                sCommentAppeal.setRecordId(recordId);
                storeCommentAppealMapper.updateById(sCommentAppeal);

            } else {
                if (analyzeResp != null) {
                    log.error("调用差评申述置信度分析接口失败, http状态: {}", analyzeResp.getStatusCode());
                    R.fail("调用差评申述置信度分析接口失败, http状态: " + analyzeResp.getStatusCode());
                }
            }
        }
        return R.success("调用差评申述置信度分析接口完成");
    }

    /**
     * 将图片URL转换为Base64编码
     *
     * @param imageUrl 图片URL
     * @return Base64编码字符串
     */
    private String convertImageToBase64(String imageUrl) {
        // 1. 检查是否为空
        if (!StringUtils.hasText(imageUrl)) {
            log.warn("图片URL为空");
            return "";
        }

        // 2. 对URL进行编码处理（解决特殊字符问题）
        String encodedUrl = encodeImageUrl(imageUrl);

        // 3. 验证URL格式
        if (!isValidUrl(encodedUrl)) {
            log.warn("无效的图片URL: {}", imageUrl);
            return "";
        }

        try {
            // 4. 下载图片并转换Base64
            byte[] imageBytes = restTemplate.getForObject(encodedUrl, byte[].class);
            if (imageBytes != null) {
                return java.util.Base64.getEncoder().encodeToString(imageBytes);
            }
        } catch (org.springframework.web.client.HttpClientErrorException.NotFound e) {
            log.warn("图片不存在 (404), URL: {}", imageUrl);
            return "";
        } catch (Exception e) {
            log.error("图片转换为Base64失败, URL: {}", imageUrl, e);
            return "";
        }
        return "";
    }

    // 新增方法：对URL中的特殊字符进行编码
    private String encodeImageUrl(String imageUrl) {
        try {
            URI uri = new URI(imageUrl);
            String scheme = uri.getScheme();
            String host = uri.getHost();
            String path = uri.getPath();
            String query = uri.getQuery();

            // 对路径中的特殊字符进行编码
            String encodedPath = java.net.URLEncoder.encode(path, "UTF-8")
                    .replace("%2F", "/")  // 保留斜杠
                    .replace("+", "%20"); // 空格编码

            StringBuilder encodedUrl = new StringBuilder();
            encodedUrl.append(scheme).append("://").append(host).append(encodedPath);

            if (query != null) {
                encodedUrl.append("?").append(query);
            }

            return encodedUrl.toString();
        } catch (Exception e) {
            log.warn("URL编码失败，使用原始URL: {}", imageUrl);
            return imageUrl;
        }
    }



    // 辅助方法：验证URL格式合法性
    private boolean isValidUrl(String url) {
        try {
            // 尝试构造URI，验证格式
            new URI(url);
            // 进一步检查是否以http/https开头（可选，根据业务需求）
            return url.startsWith("http://") || url.startsWith("https://");
        } catch (URISyntaxException e) {
            return false;
        }
    }

    private String fetchAiServiceToken() {
        log.info("登录Ai服务获取token...{}", loginUrl);
        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
        formData.add("username", userName);
        formData.add("password", passWord);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);

        try {
            ResponseEntity<String> response = restTemplate.postForEntity(loginUrl, requestEntity, String.class);
            if (response != null && response.getStatusCodeValue() == 200 && response.getBody() != null) {
                JSONObject jsonObject = JSONObject.parseObject(response.getBody());
                JSONObject dataJson = jsonObject.getJSONObject("data");
                return dataJson != null ? dataJson.getString("access_token") : null;
            }
            log.error("请求差评申诉辅助系统 登录接口失败 http状态：{}", response != null ? response.getStatusCode() : null);
        } catch (Exception e) {
            log.error("调用差评申诉辅助系统登录接口异常", e);
        }
        return null;
    }

    private String buildCompletedUrl(Integer recordId) {
        String baseUrl = resultUrl;
        if (!StringUtils.hasText(baseUrl)) {
            throw new IllegalStateException("差评申述分析接口地址未配置");
        }
        if (baseUrl.endsWith("/")) {
            baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
        }
        String completedBase = baseUrl.replace("/api/v1/analyze", "");
        if (!completedBase.endsWith("/")) {
            completedBase = completedBase + "/";
        }
        return completedBase + "api/v1/records/" + recordId + "/completed";
    }

    /**
     * 定时查询AI分析结果
     * 启动后延迟10秒，然后每10秒执行一次
     */
    @Scheduled(initialDelay = 10000, fixedRate = 10000)
    public void scheduledQueryAppealResult() {
        log.info("【定时任务】开始查询AI差评申诉分析结果...");
        try {
            String accessToken = fetchAiServiceToken();
            if (!StringUtils.hasText(accessToken)) {
                log.error("【定时任务】获取AI服务Token失败");
                return;
            }
            getNegativeReviewAppealCompletedResult(accessToken);
        } catch (Exception e) {
            log.error("【定时任务】查询AI差评申诉分析结果异常", e);
        }
        log.info("【定时任务】查询AI差评申诉分析结果完成");
    }

    /**
     * 删除评价和评论（审核通过时调用）
     * 与 StoreCommentAppealServiceImpl 中的逻辑保持一致
     *
     * @param ratingId 评价ID（common_rating.id）
     */
    private void deleteRatingAndComments(Integer ratingId) {
        try {
            // 1. 删除评价（逻辑删除 common_rating 表）
            CommonRating rating = commonRatingMapper.selectById(ratingId);
            if (rating != null) {
                int rows = commonRatingMapper.logicDeleteById(ratingId);
                log.info("【定时任务】删除评价结果，ratingId={}，影响行数={}", ratingId, rows);
            }

            // 2. 查询该评价下的所有评论ID（用于后续删除点赞记录）
            LambdaQueryWrapper<CommonComment> commentQueryWrapper = new LambdaQueryWrapper<>();
            commentQueryWrapper.eq(CommonComment::getSourceType, CommentSourceTypeEnum.STORE_COMMENT.getType())
                    .eq(CommonComment::getSourceId, ratingId)
                    .eq(CommonComment::getDeleteFlag, 0);
            List<CommonComment> comments = commonCommentMapper.selectList(commentQueryWrapper);
            List<Long> commentIds = comments.stream().map(CommonComment::getId).collect(Collectors.toList());

            // 3. 删除该评价下的所有评论
            int commentRows = commonCommentMapper.logicDeleteBySourceId(
                    CommentSourceTypeEnum.STORE_COMMENT.getType(), ratingId);
            log.info("【定时任务】删除评价下的评论结果，ratingId={}，影响行数={}", ratingId, commentRows);

            // 4. 删除评价的点赞记录（type=7 表示评价点赞）
            LambdaUpdateWrapper<LifeLikeRecord> ratingLikeWrapper = new LambdaUpdateWrapper<>();
            ratingLikeWrapper.eq(LifeLikeRecord::getType, "7")
                    .eq(LifeLikeRecord::getHuifuId, String.valueOf(ratingId))
                    .eq(LifeLikeRecord::getDeleteFlag, 0);
            ratingLikeWrapper.set(LifeLikeRecord::getDeleteFlag, 1);
            ratingLikeWrapper.set(LifeLikeRecord::getUpdatedTime, new java.util.Date());
            lifeLikeRecordMapper.update(null, ratingLikeWrapper);
            log.info("【定时任务】删除评价的点赞记录，ratingId={}", ratingId);

            // 5. 删除评论的点赞记录（type=1 表示评论点赞）
            if (!commentIds.isEmpty()) {
                for (Long commentId : commentIds) {
                    LambdaUpdateWrapper<LifeLikeRecord> commentLikeWrapper = new LambdaUpdateWrapper<>();
                    commentLikeWrapper.eq(LifeLikeRecord::getType, "1")
                            .eq(LifeLikeRecord::getHuifuId, String.valueOf(commentId))
                            .eq(LifeLikeRecord::getDeleteFlag, 0);
                    commentLikeWrapper.set(LifeLikeRecord::getDeleteFlag, 1);
                    commentLikeWrapper.set(LifeLikeRecord::getUpdatedTime, new java.util.Date());
                    lifeLikeRecordMapper.update(null, commentLikeWrapper);
                }
                log.info("【定时任务】删除评论的点赞记录，评论数={}", commentIds.size());
            }

            // 6. 重新统计店铺评分（删除评价后需要更新门店评分）
            if (rating != null && rating.getBusinessType() == 1) {
                updateStoreScore(rating.getBusinessId());
            }
        } catch (Exception e) {
            log.error("【定时任务】删除评价和评论异常，ratingId={}", ratingId, e);
        }
    }

    /**
     * 更新店铺评分（删除评价后重新计算门店评分）
     *
     * @param businessId 店铺ID
     */
    private void updateStoreScore(Integer businessId) {
        try {
            // 查询该店铺的所有有效评价
            LambdaQueryWrapper<CommonRating> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CommonRating::getBusinessType, 1)
                    .eq(CommonRating::getBusinessId, businessId)
                    .eq(CommonRating::getDeleteFlag, 0)
                    .eq(CommonRating::getIsShow, 1)
                    .eq(CommonRating::getAuditStatus, 1);
            List<CommonRating> ratings = commonRatingMapper.selectList(wrapper);

            int total = ratings.size();
            if (total == 0) {
                // 没有评价，设置默认评分为0
                StoreInfo storeInfo = new StoreInfo();
                storeInfo.setId(businessId);
                storeInfo.setScoreAvg(5.0);
                storeInfo.setScoreOne(0.0);
                storeInfo.setScoreTwo(0.0);
                storeInfo.setScoreThree(0.0);
                storeInfoMapper.updateById(storeInfo);
                log.info("【定时任务】店铺无有效评价，重置评分为0，businessId={}", businessId);
                return;
            }

            // 计算平均评分
            double scoreSum = ratings.stream().mapToDouble(r -> r.getScore() != null ? r.getScore() : 0.0).sum();
            double scoreOneSum = ratings.stream().mapToDouble(r -> r.getScoreOne() != null ? r.getScoreOne() : 0.0).sum();
            double scoreTwoSum = ratings.stream().mapToDouble(r -> r.getScoreTwo() != null ? r.getScoreTwo() : 0.0).sum();
            double scoreThreeSum = ratings.stream().mapToDouble(r -> r.getScoreThree() != null ? r.getScoreThree() : 0.0).sum();

            double scoreAvg = Math.round((scoreSum / total) * 100.0) / 100.0;
            double scoreOne = Math.round((scoreOneSum / total) * 100.0) / 100.0;
            double scoreTwo = Math.round((scoreTwoSum / total) * 100.0) / 100.0;
            double scoreThree = Math.round((scoreThreeSum / total) * 100.0) / 100.0;

            StoreInfo storeInfo = new StoreInfo();
            storeInfo.setId(businessId);
            storeInfo.setScoreAvg(scoreAvg);
            storeInfo.setScoreOne(scoreOne);
            storeInfo.setScoreTwo(scoreTwo);
            storeInfo.setScoreThree(scoreThree);
            storeInfoMapper.updateById(storeInfo);

            log.info("【定时任务】更新店铺评分成功，businessId={}，评价数={}，scoreAvg={}", businessId, total, scoreAvg);
        } catch (Exception e) {
            log.error("【定时任务】更新店铺评分失败，businessId={}，error={}", businessId, e.getMessage());
        }
    }

}
