package shop.alien.util.common.safe;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.*;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class TextModerationUtil {


    @Value("${ali.yundun.accessKeyID}")
    private String accessKeyId;

    @Value("${ali.yundun.secret}")
    private String accessKeySecret;

    @Value("${ali.yundun.textEndpoint}")
    private String textEndpoint;

    @Value("${ali.yundun.regionId}")
    private String regionId;

    /**
     * 创建请求客户端
     * @return  Client
     * @throws Exception 创建客户端异常
     */
    public Client createClient() throws Exception {
        Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(accessKeySecret);
        //接入区域和地址请根据实际情况修改
        config.setRegionId(regionId);
        config.setEndpoint(textEndpoint);
        //读取时超时时间，单位毫秒（ms）。
        config.setReadTimeout(6000);
        //连接时超时时间，单位毫秒（ms）。
        config.setConnectTimeout(3000);
        //设置http代理。
        //config.setHttpProxy("http://xx.xx.xx.xx:xxxx");
        //设置https代理。
        //config.setHttpsProxy("https://xx.xx.xx.xx:xxxx");
        return new Client(config);
    }

    /**
     * 根据业务类型执行文本审核
     * @param text 待审核文本
     * @param servicesList 文本审核服务枚举
     * @return 审核结果VO
     * @throws Exception 调用服务异常
     */
    public TextModerationResultVO invokeFunction(String text, List<String> servicesList) throws Exception {
        if (CollectionUtil.isEmpty(servicesList)) {
            throw new IllegalArgumentException("至少需要一个审核服务");
        }

        Client client = createClient();
        
        TextModerationResultVO resultVO = new TextModerationResultVO();
        
        // 存储风险等级和原因的字符串
        StringBuilder riskWordsBuilder = new StringBuilder();
        String highestRiskLevel = "none"; // 默认未检测到风险
        
        try {
            for (String service : servicesList) {
                // 判断传入参service参数是否包含 chat_detection_pro、ad_compliance_detection_pro、llm_query_moderation、comment_detection_pro、
                if (isSpecialService(service)) {
                    // 处理特殊服务
                    highestRiskLevel = handleSpecialService(text, service, client, riskWordsBuilder, highestRiskLevel);
                } else {
                    // 判断service中包含 url_detection ，将文本中的url进行检测 提取url 传入进行检测
                    if ("url_detection".equals( service )) {
                        // 写一个文本提取url 的方法
                        List<String> urls = extractUrls(text);
                        if (CollectionUtil.isNotEmpty(urls)){
                            for (String url : urls) {
                                // 链接调取
                                highestRiskLevel = processTextModeration(client, url, service, riskWordsBuilder,highestRiskLevel);
                            }
                        }
                    }else {
                        // 文本调取
                        highestRiskLevel = processTextModeration(client, text, service, riskWordsBuilder,highestRiskLevel);
                    }
                }
            }
            // 设置结果VO
            resultVO.setRiskLevel(highestRiskLevel);
            resultVO.setRiskWords(riskWordsBuilder.toString());
        } catch (Exception e) {
            throw new RuntimeException("解析失败" + e);
        }
        return resultVO;
    }

    /**
     * 通用服务调取
     * @param text 文本
     * @param service  服务
     * @param client  客户端
     * @param riskWordsBuilder 危险词
     * @param highestRiskLevel 最高危险等级
     * @throws Exception 错误
     */
    private String processTextModeration(Client client, String text, String service, StringBuilder riskWordsBuilder,String highestRiskLevel) throws Exception {
        // 调用文本检测服务
        TextModerationResponse response = callTextModeration(client, text, service);
        if (response != null) {
            if (response.getStatusCode() == 200) {
                TextModerationResponseBody result = response.getBody();
                Integer code = result.getCode();
                if (code != null && code == 200) {
                    TextModerationResponseBody.TextModerationResponseBodyData data = result.getData();
                    String reason = data.getReason();
                    if (reason != null) {
                        try {
                            JSONObject reasonObj = JSON.parseObject(reason);
                            String riskLevel = reasonObj.getString("riskLevel");
                            if ("high".equals(riskLevel)) {
                                highestRiskLevel = riskLevel;
                                String riskWords = reasonObj.getString("riskWords");
                                if (riskWords != null && !riskWords.isEmpty()) {
                                    riskWordsBuilder.append(riskWords).append(",");
                                }
                            }
                        } catch (Exception e) {
                            // 解析失败，忽略该条原因
                        }
                    }
                }
            }
        }
        return highestRiskLevel;
    }

    /**
     * 处理TextModerationPlus服务
     * @param text 文本
     * @param service  服务
     * @param client  客户端
     * @param riskWordsBuilder 危险词
     * @param highestRiskLevel 最高危险等级
     * @throws Exception 错误
     */
    private String handleSpecialService(String text, String service, Client client, StringBuilder riskWordsBuilder, String highestRiskLevel) throws Exception {
        // 调用plus服务并获取响应
        TextModerationPlusResponse response = callTextModerationPlusService(client, text, service);
        // 根据response 返回参数处理结果 返回vo所需的参数
        TextModerationPlusResponseBody body = response.body;
        TextModerationPlusResponseBody.TextModerationPlusResponseBodyData data = body.getData();
        if (data != null) {
            // 分级：riskLevel
            String riskLevel = data.getRiskLevel();
            // high：高风险 medium：中风险 low：低风险 none：未检测到风险
            if ("high".equals(riskLevel)) {
                highestRiskLevel = riskLevel;
                List<TextModerationPlusResponseBody.TextModerationPlusResponseBodyDataResult> resultList = data.getResult();
                for (TextModerationPlusResponseBody.TextModerationPlusResponseBodyDataResult result : resultList) {
                    // 文字内容检测运算后返回的标签，可能会检出多个标签和分值。
                    String label = result.getLabel();
                    // 检测到的敏感词，多个词用逗号分隔，部分标签不会返回敏感词。
                    String riskWords = result.getRiskWords();
                    String description = result.getDescription();
                    if (StringUtils.isNotEmpty(riskWords)){
                        riskWordsBuilder.append(riskWords).append(",");
                    }
                    // 获取 集合 getCustomizedHit 中 所有KeyWords 拼接为字符串并追加到 riskWordsBuilder
                    if (CollectionUtil.isNotEmpty(result.getCustomizedHit())){
                        result.getCustomizedHit().forEach(hit -> riskWordsBuilder.append(hit.getKeyWords()).append(","));
                    }
                    //置信分值，0到100分，保留到小数点后2位。部分标签无置信分。
                    Float confidence = result.getConfidence();

                }
            }
        }
        return highestRiskLevel;
    }

    /**
     * 调用TextModerationPlus服务
     * @param text 文本
     * @param service  服务
     * @param client  客户端
     * @return 检测结果
     * @throws Exception 检测异常
     */
    private TextModerationPlusResponse callTextModerationPlusService(Client client, String text, String service) throws Exception {
        // 包含调取plus服务
        TextModerationPlusRequest textModerationPlusRequest = new TextModerationPlusRequest();
        textModerationPlusRequest.setService(service);
        // 构建服务参数
        textModerationPlusRequest.setServiceParameters(buildServiceParameters(text));
        return client.textModerationPlus(textModerationPlusRequest);
    }

    /**
     * 调取普通服务
     * @param text 文本
     * @param service  服务
     * @param client  客户端
     * @return 检测结果
     * @throws Exception 检测异常
     */
    private TextModerationResponse callTextModeration(Client client, String text, String service) throws Exception {
        // 创建RuntimeObject实例并设置运行参数。
        RuntimeOptions runtime = new RuntimeOptions();
        runtime.readTimeout = 10000;
        runtime.connectTimeout = 10000;
        //检测参数构造
        JSONObject serviceParameters = new JSONObject();
        serviceParameters.put("content", text);
        // 调取普通服务
        TextModerationRequest textModerationRequest = new TextModerationRequest();
        textModerationRequest.setService(service);
        textModerationRequest.setServiceParameters(serviceParameters.toJSONString());
        return client.textModerationWithOptions(textModerationRequest, runtime);
    }

    /**
     * 提取URL
     * @param text 文本
     * @return URL列表
     */
    private List<String> extractUrls(String text) {
        List<String> urls = Lists.newArrayList();

        // 使用改进后的正则表达式匹配URL
        Pattern urlPattern = Pattern.compile("(https?://\\S+)(:\\d+)?(/\\S*)?");

        Matcher matcher = urlPattern.matcher(text);

        while (matcher.find()) {
            urls.add(matcher.group());
        }

        return urls;
    }


    private String buildServiceParameters(String text) {
        // 创建服务参数JSON
        JSONObject serviceParameters = new JSONObject();
        serviceParameters.put("content", text);
        return serviceParameters.toJSONString();
    }
    /**
     * 判断服务是否为特殊服务
     * @param service 服务名称
     * @return 是否为特殊服务
     */
    public static boolean isSpecialService(String service) {
        return TextReviewServiceEnum.CHAT_DETECTION_PRO.getService().equals(service)
                || TextReviewServiceEnum.AD_COMPLIANCE_DETECTION_PRO.getService().equals(service)
                || TextReviewServiceEnum.LLM_QUERY_MODERATION.getService().equals(service)
                || TextReviewServiceEnum.COMMENT_DETECTION_PRO.getService().equals(service);
    }

}