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.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.mapper.StoreCommentAppealMapper;
import shop.alien.mapper.StoreCommentMapper;
import shop.alien.mapper.StoreUserMapper;

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
public class BadReviewAppealJob {

    private final RestTemplate restTemplate;

    private final StoreCommentAppealMapper storeCommentAppealMapper;

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

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

    private String loginUrl = "http://192.168.2.78:9000/ai/user-auth-core/api/v1/auth/login";


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

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

    private String analyzeUrl = "http://192.168.2.78:9000/ai/auto-review/api/v1/analyze";

    private String resultUrl = "http://192.168.2.78:9000/ai/auto-review";



    /**
     * 差评申述置信度分析接口地址
     * 例如: 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 invokeAnalyzeTask(accessToken);
    }


    @XxlJob("getAppealCompletedResult")
    public R<String> getAppealCompletedResult() {
        String accessToken = fetchAiServiceToken();
        if (!StringUtils.hasText(accessToken)) {
            return R.fail("调用差评申诉辅助系统 登录接口失败");
        }
        return getNegativeReviewAppealCompletedResult(accessToken);
    }

    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);
//                    JSONObject details = analyzeJson.getJSONObject("details");
//                    String analysisStatus = details.get("analysis_status").toString();
//                    if (analysisStatus.equals("pending")) {
//                        log.error("差评申述置信度分析尚未完成");
//                        R.fail("差评申述置信度分析尚未完成");
//                        continue;
//                    }
                    JSONObject dataJsonObj = analyzeJson.getJSONObject("data");

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

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

                    StoreCommentAppeal sCommentAppeal = new StoreCommentAppeal();
                    sCommentAppeal.setRecordId(appeal.getRecordId());
                    // 判断得分大小
                    if (dataJsonObj.getDouble("user_confidence") > dataJsonObj.getDouble("merchant_confidence")){
                        sCommentAppeal.setAppealStatus(1);
                        sCommentAppeal.setFinalResult("已驳回");
                    } else {
                        sCommentAppeal.setAppealStatus(2);
                        sCommentAppeal.setFinalResult("已同意");
                        //假删除评论
                        StoreComment storeComment = new StoreComment();
                        storeComment.setId(appeal.getCommentId());
                        storeComment.setDeleteFlag(1);
                        storeCommentMapper.updateById(storeComment);
                    }
                    sCommentAppeal.setAppealAiApproval(dataJsonObj.toJSONString());

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

                    // 发送通知
                    LifeNotice lifeMessage = new LifeNotice();
                    StoreUser storeUser = storeUserMapper.selectOne(new QueryWrapper<StoreUser>().eq("store_id", appeal.getStoreId()));
                    lifeMessage.setReceiverId("store_" + storeUser.getPhone());
                    String text = "您的评论申诉结果为" + sCommentAppeal.getFinalResult();
                    lifeMessage.setContext(text);
                    lifeMessage.setSenderId("system");
                    lifeMessage.setIsRead(0);
                    lifeMessage.setNoticeType(1);
                    lifeNoticeMapper.insert(lifeMessage);

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

            // 商家图片：支持多张，转成 Base64 数组
            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(",")) {
                    String base64 = convertImageToBase64(imageUrl.trim());
                    if (StringUtils.hasText(base64)) {
                        merchantImages.add(base64);
                    }
                }
            }
            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(base64);
                    }
                }
            }
            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(0);
                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";
    }

}
