package shop.alien.store.service;

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 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.stereotype.Service;
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.result.R;
import shop.alien.entity.store.*;
import shop.alien.mapper.*;
import shop.alien.util.type.LifeNoticeUtil;
import shop.alien.util.common.constant.CommentSourceTypeEnum;

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

/**
 * 评论申诉-用户补充 AI 分析任务服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StoreCommentAppealSupplementJobService {

    private final RestTemplate restTemplate;
    private final StoreCommentAppealMapper storeCommentAppealMapper;
    private final StoreCommentAppealSupplementMapper storeCommentAppealSupplementMapper;
    private final StoreUserMapper storeUserMapper;
    private final LifeUserMapper lifeUserMapper;
    private final LifeNoticeMapper lifeNoticeMapper;
    private final LifeNoticeUtil lifeNoticeUtil;
    private final CommonRatingMapper commonRatingMapper;
    private final CommonCommentMapper commonCommentMapper;
    private final LifeLikeRecordMapper lifeLikeRecordMapper;
    private final StoreInfoMapper storeInfoMapper;
    private final CommonRatingService commonRatingService;

    @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-ai-analyze.base-url}")
    private String analyzeUrl;

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

    /**
     * 提交待处理申诉至 AI 分析
     */
    public R<String> submitAppealAnalyze() {
        log.info("【用户补充申诉】开始执行 AI 差评申诉分析提交任务");
        return invokeAnalyzeTask();
    }

    /**
     * 轮询 AI 分析完成结果
     */
    public R<String> pollCompletedResult() {
        log.info("【用户补充申诉】开始查询 AI 分析结果");
        return pollAppealCompletedResult();
    }

    private R<String> pollAppealCompletedResult() {
        List<StoreCommentAppeal> pendingAppeals = storeCommentAppealMapper.getSupplementPendingAppeals();
        if (pendingAppeals == null || pendingAppeals.isEmpty()) {
            log.info("【用户补充申诉】没有待轮询的分析结果");
            return R.success("没有待轮询的分析结果");
        }
        log.info("【用户补充申诉】本次轮询申述数量（上限10条）: {}", pendingAppeals.size());

        RestTemplate restTemplateWithAuth = new RestTemplate();

        for (StoreCommentAppeal appeal : pendingAppeals) {
            String completedUrl = buildCompletedUrl(appeal.getRecordId());
            try {
                ResponseEntity<String> analyzeResp = restTemplateWithAuth.getForEntity(completedUrl, String.class);
                if (analyzeResp == null || analyzeResp.getStatusCodeValue() != 200) {
                    if (analyzeResp != null) {
                        log.error("【用户补充申诉】查询分析结果失败, http状态: {}", analyzeResp.getStatusCode());
                    }
                    continue;
                }

                String analyzeBody = analyzeResp.getBody();
                log.info("【用户补充申诉】查询分析结果, 申诉ID: {}, 返回: {}", appeal.getId(), analyzeBody);

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

                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;
                }

                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 updateAppeal = new StoreCommentAppeal();
                updateAppeal.setRecordId(appeal.getRecordId());
                updateAppeal.setAppealAiApproval(dataJsonObj.toJSONString());

                if (merchantConfidence > userConfidence) {
                    updateAppeal.setAppealStatus(2);
                    updateAppeal.setFinalResult("已同意");
                    log.info("【用户补充申诉】商家赢，申诉通过，申诉ID: {}", appeal.getId());
                    Integer ratingId = appeal.getCommentId();
                    if (ratingId != null) {
                        deleteRatingAndComments(ratingId);
                    }
                } else {
                    updateAppeal.setAppealStatus(1);
                    updateAppeal.setFinalResult("已驳回");
                    log.info("【用户补充申诉】用户赢，申诉驳回，申诉ID: {}", appeal.getId());
                    Integer ratingId = appeal.getCommentId();
                    if (ratingId != null) {
                        incrementRatingRejectNum(ratingId);
                    }
                }

                storeCommentAppealMapper.updateByRecordIdNew(appeal.getId(),
                        updateAppeal.getAppealStatus(), updateAppeal.getFinalResult());
                boolean merchantWins = merchantConfidence > userConfidence;
                sendAppealResultNotifications(appeal, merchantWins);
            } catch (Exception e) {
                log.error("【用户补充申诉】查询分析结果异常，申诉ID: {}", appeal.getId(), e);
            }
        }
        return R.success("【用户补充申诉】查询 AI 分析结果完成");
    }

    private void sendAppealResultNotifications(StoreCommentAppeal appeal, boolean merchantWins) {
        sendAppealResultNoticeToUser(appeal, merchantWins);
        sendAppealResultNoticeToStore(appeal, merchantWins);
    }

    private void sendAppealResultNoticeToUser(StoreCommentAppeal appeal, boolean merchantWins) {
        try {
            CommonRating rating = commonRatingMapper.selectById(appeal.getCommentId());
            if (rating == null || rating.getUserId() == null) {
                log.warn("【用户补充申诉】用户通知跳过：评价不存在或无用户，appealId={}", appeal.getId());
                return;
            }
            LifeUser lifeUser = lifeUserMapper.selectById(rating.getUserId().intValue());
            if (lifeUser == null || !StringUtils.hasText(lifeUser.getUserPhone())) {
                log.warn("【用户补充申诉】用户通知跳过：用户不存在或手机号为空，appealId={}", appeal.getId());
                return;
            }

            String message = merchantWins
                    ? "商家对你的评价申诉已通过审核，该条评价已删除。"
                    : "商家对你的评价申诉未通过审核，你的评价将继续展示。";

            String receiverId = "user_" + lifeUser.getUserPhone();
            JSONObject contextJson = new JSONObject();
            contextJson.put("message", message);
            contextJson.put("appealId", appeal.getId());
            contextJson.put("commentId", appeal.getCommentId());
            String title = merchantWins
                    ? "您的评价已被删除"
                    : "商家申诉已被驳回";
            insertSystemNotice(receiverId, appeal.getId(), title, contextJson.toJSONString());
            log.info("【用户补充申诉】用户申诉结果通知发送成功，appealId={}, merchantWins={}", appeal.getId(), merchantWins);
        } catch (Exception e) {
            log.error("【用户补充申诉】用户申诉结果通知发送失败，appealId={}", appeal.getId(), e);
        }
    }

    private void sendAppealResultNoticeToStore(StoreCommentAppeal appeal, boolean merchantWins) {
        try {
            StoreUser storeUser = storeUserMapper.selectOne(
                    new QueryWrapper<StoreUser>().eq("store_id", appeal.getStoreId()).eq("delete_flag", 0));
            if (storeUser == null || !StringUtils.hasText(storeUser.getPhone())) {
                log.warn("【用户补充申诉】商家通知跳过：未找到店铺用户，appealId={}", appeal.getId());
                return;
            }

            CommonRating rating = commonRatingMapper.selectById(appeal.getCommentId());
            LifeUser ratingUser = null;
            if (rating != null && rating.getUserId() != null) {
                ratingUser = lifeUserMapper.selectById(rating.getUserId().intValue());
            }
            String maskedNickName = desensitizeUserNickName(rating, ratingUser);

            String message = merchantWins
                    ? "你对 " + maskedNickName + " 的评价申诉已通过，该评价已下架。"
                    : "你对 " + maskedNickName + " 的评价申诉未通过，评价将继续展示。";

            String receiverId = "store_" + storeUser.getPhone();
            JSONObject contextJson = new JSONObject();
            contextJson.put("message", message);
            contextJson.put("appealId", appeal.getId());
            contextJson.put("commentId", appeal.getCommentId());


            String title = merchantWins
                    ? "申诉通过"
                    : "申诉驳回";

            insertSystemNotice(receiverId, appeal.getId(), title, contextJson.toJSONString());
            log.info("【用户补充申诉】商家申诉结果通知发送成功，appealId={}, merchantWins={}", appeal.getId(), merchantWins);
        } catch (Exception e) {
            log.error("【用户补充申诉】商家申诉结果通知发送失败，appealId={}", appeal.getId(), e);
        }
    }

    private void insertSystemNotice(String receiverId, Integer businessId, String title, String context) {
        LifeNotice lifeNotice = new LifeNotice();
        lifeNotice.setSenderId("system");
        lifeNotice.setReceiverId(receiverId);
        lifeNotice.setBusinessId(businessId);
        lifeNotice.setTitle(title);
        lifeNotice.setContext(context);
        lifeNotice.setNoticeType(1);
        lifeNotice.setIsRead(0);
        lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
        lifeNoticeMapper.insert(lifeNotice);
    }

    private String desensitizeUserNickName(CommonRating rating, LifeUser lifeUser) {
        if (rating != null && rating.getIsAnonymous() != null && rating.getIsAnonymous() == 1) {
            return "匿名用户";
        }
        String nick = lifeUser != null ? lifeUser.getUserName() : null;
        if (!StringUtils.hasText(nick)) {
            return "用户";
        }
        nick = nick.trim();
        if (nick.length() == 1) {
            return nick.charAt(0) + "*";
        }
        if (nick.length() == 2) {
            return nick.charAt(0) + "*";
        }
        return nick.charAt(0) + "**" + nick.charAt(nick.length() - 1);
    }

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

        HttpHeaders analyzeHeaders = new HttpHeaders();
        analyzeHeaders.setContentType(MediaType.APPLICATION_JSON);

        List<Map<String, Object>> appealList = storeCommentAppealMapper.getAppealListBetween45And72Hours();
        if (appealList == null || appealList.isEmpty()) {
            log.info("【用户补充申诉】没有申诉时间在45～72小时内的待处理申述");
            return R.success("没有申诉时间在45～72小时内的待处理申述");
        }
        log.info("【用户补充申诉】本次处理申述数量（申诉45～72小时，上限10条）: {}", appealList.size());

        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());
            Integer appealId = (Integer) storeCommentAppeal.get("id");
            analyzeRequest.put("user_review", buildUserReviewFromSupplement(appealId));

            List<String> merchantImages = new ArrayList<>();
            String imgUrls = storeCommentAppeal.get("img_url") == null ? "" : storeCommentAppeal.get("img_url").toString();
            if (StringUtils.hasText(imgUrls)) {
                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(",")) {
                    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;
            try {
                analyzeResp = restTemplate.postForEntity(analyzeUrl, analyzeEntity, String.class);
            } catch (org.springframework.web.client.HttpServerErrorException.ServiceUnavailable e) {
                log.error("【用户补充申诉】调用分析接口返回503: {}", e.getResponseBodyAsString());
                continue;
            } catch (Exception e) {
                log.error("【用户补充申诉】调用分析接口异常", e);
                continue;
            }

            if (analyzeResp == null || analyzeResp.getStatusCodeValue() != 200) {
                if (analyzeResp != null) {
                    log.error("【用户补充申诉】调用分析接口失败, http状态: {}", analyzeResp.getStatusCode());
                }
                continue;
            }

            String analyzeBody = analyzeResp.getBody();
            log.info("【用户补充申诉】分析提交成功, 返回: {}", analyzeBody);

            JSONObject analyzeJson = JSONObject.parseObject(analyzeBody);
            JSONObject dataJsonObj = analyzeJson.getJSONObject("data");
            if (dataJsonObj == null) {
                log.error("【用户补充申诉】分析返回数据为空");
                continue;
            }

            Integer recordId = dataJsonObj.getInteger("record_id");
            if (recordId == null) {
                log.error("【用户补充申诉】分析返回 record_id 为空");
                continue;
            }

            StoreCommentAppeal sCommentAppeal = new StoreCommentAppeal();
            sCommentAppeal.setId((Integer) storeCommentAppeal.get("id"));
            sCommentAppeal.setAppealStatus(3);
            sCommentAppeal.setRecordId(recordId);
            storeCommentAppealMapper.updateById(sCommentAppeal);
        }
        return R.success("【用户补充申诉】调用差评申述置信度分析接口完成");
    }

    private String buildUserReviewFromSupplement(Integer appealId) {
        if (appealId == null) {
            return "";
        }
        List<StoreCommentAppealSupplement> supplements = storeCommentAppealSupplementMapper.selectList(
                new LambdaQueryWrapper<StoreCommentAppealSupplement>()
                        .eq(StoreCommentAppealSupplement::getAppealId, appealId)
                        .eq(StoreCommentAppealSupplement::getDeleteFlag, 0)
                        .orderByAsc(StoreCommentAppealSupplement::getCreatedTime));
        return supplements.stream()
                .map(StoreCommentAppealSupplement::getSupplementContent)
                .filter(StringUtils::hasText)
                .collect(Collectors.joining("\n"));
    }

    private String buildCompletedUrl(Integer recordId) {
        String baseUrl = resultUrl;
        if (!StringUtils.hasText(baseUrl)) {
            throw new IllegalStateException("【用户补充申诉】分析结果接口地址未配置");
        }

        return baseUrl + "/" + recordId + "/completed";
    }

    private void incrementRatingRejectNum(Integer ratingId) {
        try {
            LambdaUpdateWrapper<CommonRating> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(CommonRating::getId, ratingId)
                    .setSql("reject_num = IFNULL(reject_num, 0) + 1");
            int rows = commonRatingMapper.update(null, wrapper);
            log.info("【用户补充申诉】申诉失败，评价拒绝次数+1，ratingId={}，影响行数={}", ratingId, rows);
        } catch (Exception e) {
            log.error("【用户补充申诉】更新评价拒绝次数失败，ratingId={}", ratingId, e);
        }
    }

    private void deleteRatingAndComments(Integer ratingId) {
        try {
            CommonRating rating = commonRatingMapper.selectById(ratingId);
            if (rating != null) {
                int rows = commonRatingMapper.logicDeleteById(ratingId);
                commonRatingService.updateStoreScoreAfterDelete(rating.getBusinessId());
                log.info("【用户补充申诉】删除评价，ratingId={}", ratingId);
            }

            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());

            int commentRows = commonCommentMapper.logicDeleteBySourceId(
                    CommentSourceTypeEnum.STORE_COMMENT.getType(), ratingId);
            log.info("【用户补充申诉】删除评价下评论，ratingId={}，影响行数={}", ratingId, commentRows);

            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);

            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);
                }
            }

//            if (rating != null && rating.getBusinessType() == 1) {
//                updateStoreScore(rating.getBusinessId());
//            }
        } catch (Exception e) {
            log.error("【用户补充申诉】删除评价和评论异常，ratingId={}", ratingId, e);
        }
    }

    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) {
                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);
                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();

            StoreInfo storeInfo = new StoreInfo();
            storeInfo.setId(businessId);
            storeInfo.setScoreAvg(Math.round((scoreSum / total) * 100.0) / 100.0);
            storeInfo.setScoreOne(Math.round((scoreOneSum / total) * 100.0) / 100.0);
            storeInfo.setScoreTwo(Math.round((scoreTwoSum / total) * 100.0) / 100.0);
            storeInfo.setScoreThree(Math.round((scoreThreeSum / total) * 100.0) / 100.0);
            storeInfoMapper.updateById(storeInfo);
        } catch (Exception e) {
            log.error("【用户补充申诉】更新店铺评分失败，businessId={}", businessId, e);
        }
    }

    @SuppressWarnings("unused")
    private String fetchAiServiceToken() {
        log.info("【用户补充申诉】登录 AI 服务获取 token, url: {}", 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;
    }
}
