package com.nanyan.securitylink.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nanyan.securitylink.common.MsgCode;
import com.nanyan.securitylink.config.AppConfig;
import com.nanyan.securitylink.dto.AIRequestDTO;
import com.nanyan.securitylink.entity.*;
import com.nanyan.securitylink.execption.BaseException;
import com.nanyan.securitylink.service.AIService;
import com.nanyan.securitylink.vo.AIResponse;
import com.nanyan.securitylink.vo.AnswerVO;
import com.nanyan.securitylink.vo.CodeVO;
import com.nanyan.securitylink.vo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@Service
public class AIServiceImpl implements AIService {
    @Autowired
    AppConfig appConfig;
    @Autowired
    RestTemplate restTemplate;
    private static final Map<String, String> NEWS_LABEL_MAP = new HashMap<>();
    private static final Map<String, String> NATURAL_DISASTER_LABEL_MAP = new HashMap<>();

    static {
        NEWS_LABEL_MAP.put("其他","TagOther");
        NEWS_LABEL_MAP.put("枪击","TagShooting");
        NEWS_LABEL_MAP.put("抢劫","TagRobbery");
        NEWS_LABEL_MAP.put("事故爆炸","TagExplosion");
        NEWS_LABEL_MAP.put("恐怖袭击","TagTerroristAttack");
        NEWS_LABEL_MAP.put("纵火","TagArson");
        NEWS_LABEL_MAP.put("大规模伤亡事件","TagMassCasualtyIncident");
        NEWS_LABEL_MAP.put("人质事件","TagHostageSituation");
        NEWS_LABEL_MAP.put("毒气泄漏","TagToxicGasLeak");
        NEWS_LABEL_MAP.put("生物危害","TagBiologicalHazard");
        NEWS_LABEL_MAP.put("交通事故","TagTrafficAccident");
        NEWS_LABEL_MAP.put("建筑物倒塌","TagBuildingCollapse");
        NEWS_LABEL_MAP.put("食品安全事件","TagFoodSafety");
        NEWS_LABEL_MAP.put("社会冲突","TagSocialConflict");
        NEWS_LABEL_MAP.put("群体性事件","TagMassGatheringIncident");
        NEWS_LABEL_MAP.put("环境污染","TagEnvironmentalPollution");
        NEWS_LABEL_MAP.put("抗议示威","TagProtestDemonstration");
        NEWS_LABEL_MAP.put("集体维权","TagCollectiveAdvocacy");
        NEWS_LABEL_MAP.put("活动失控骚乱","TagUncontrolledEventRiot");
        NEWS_LABEL_MAP.put("地域冲突","TagTerritorialConflict");
        NEWS_LABEL_MAP.put("性别冲突","TagGenderConflict");
        NEWS_LABEL_MAP.put("宗教冲突","TagReligiousConflict");
        NEWS_LABEL_MAP.put("民族冲突","TagEthnicConflict");
        NEWS_LABEL_MAP.put("阶级冲突","TagClassConflict");
        NEWS_LABEL_MAP.put("食物中毒","TagFoodPoisoning");
        NEWS_LABEL_MAP.put("地震","TagEarthquake");
        NEWS_LABEL_MAP.put("火山爆发","TagVolcanicEruption");
        NEWS_LABEL_MAP.put("山体滑坡","TagLandslide");
        NEWS_LABEL_MAP.put("泥石流","TagMudslide");
        NEWS_LABEL_MAP.put("雪崩","TagAvalanche");
        NEWS_LABEL_MAP.put("水坝决口","TagDamBreach");
        NEWS_LABEL_MAP.put("水坝溃坝","TagDamBurst");
        NEWS_LABEL_MAP.put("台风/飓风","TagTyphoonHurricane");
        NEWS_LABEL_MAP.put("龙卷风","TagTornadoWarning");
        NEWS_LABEL_MAP.put("暴雨","TagRainstorm");
        NEWS_LABEL_MAP.put("洪水","TagFlood");
        NEWS_LABEL_MAP.put("寒潮","TagColdWave");
        NEWS_LABEL_MAP.put("高温热浪","TagHeatWave");
        NEWS_LABEL_MAP.put("干旱","TagDrought");
        NEWS_LABEL_MAP.put("沙尘暴","TagDustStorm");
        NEWS_LABEL_MAP.put("冻雨","TagFreezingRain");
        NEWS_LABEL_MAP.put("冰雹","TagHail");
        NEWS_LABEL_MAP.put("雷暴","TagThunderstormWarning");
        NEWS_LABEL_MAP.put("大风","TagHighWind");
        NEWS_LABEL_MAP.put("山林火灾","TagForestFire");
        NEWS_LABEL_MAP.put("冰川融化","TagGlacialMelting");
        NEWS_LABEL_MAP.put("海啸","TagTsunami");
        NEWS_LABEL_MAP.put("霾","TagHazeWarning");
        NEWS_LABEL_MAP.put("化学品泄漏","TagChemicalSpill");
        NEWS_LABEL_MAP.put("核事故","TagNuclearAccident");
        NEWS_LABEL_MAP.put("矿难","TagMiningAccident");
        NEWS_LABEL_MAP.put("油轮泄漏","TagOilSpill");
        NEWS_LABEL_MAP.put("火灾","TagFire");
        NEWS_LABEL_MAP.put("工业污染","TagIndustrialPollution");
        NEWS_LABEL_MAP.put("工业事故","TagIndustriaAccident");
        NEWS_LABEL_MAP.put("传染病爆发","TagDiseaseOutbreak");
        NEWS_LABEL_MAP.put("公共卫生事件","TagPublicHealthEmergency");
        NEWS_LABEL_MAP.put("持刀伤人","TagKnifeAttack");
        NEWS_LABEL_MAP.put("恐怖爆炸","TerroristBombing");
        NEWS_LABEL_MAP.put("暴力冲突","TagViolentClashes");
        NEWS_LABEL_MAP.put("战争","TagWar");
        NEWS_LABEL_MAP.put("游行抗议","TagProtest");


        NATURAL_DISASTER_LABEL_MAP.put("地震","earthquake");
        NATURAL_DISASTER_LABEL_MAP.put("火山爆发","volcanicEruption");
        NATURAL_DISASTER_LABEL_MAP.put("海啸","tsunami");
        NATURAL_DISASTER_LABEL_MAP.put("台风/飓风","typhoonHurricane");
        NATURAL_DISASTER_LABEL_MAP.put("龙卷风","tornadowarning");
        NATURAL_DISASTER_LABEL_MAP.put("洪水","flood");
        NATURAL_DISASTER_LABEL_MAP.put("干旱","drought");
        NATURAL_DISASTER_LABEL_MAP.put("山体滑坡","landslide");
        NATURAL_DISASTER_LABEL_MAP.put("泥石流","mudslide");
        NATURAL_DISASTER_LABEL_MAP.put("雪崩","avalanche");
        NATURAL_DISASTER_LABEL_MAP.put("森林火灾","forestFire");
        NATURAL_DISASTER_LABEL_MAP.put("冰川融化","glacialMelting");
        NATURAL_DISASTER_LABEL_MAP.put("沙尘暴","dustStorm");
        NATURAL_DISASTER_LABEL_MAP.put("高温热浪","heatWave");
        NATURAL_DISASTER_LABEL_MAP.put("寒潮","coldWave");
        NATURAL_DISASTER_LABEL_MAP.put("暴雨","rainstorm");
        NATURAL_DISASTER_LABEL_MAP.put("工业事故","IndustriaAccident");
        NATURAL_DISASTER_LABEL_MAP.put("交通事故","TrafficAccident");
        NATURAL_DISASTER_LABEL_MAP.put("火灾","Fire");
        NATURAL_DISASTER_LABEL_MAP.put("爆炸","Explosion");
        NATURAL_DISASTER_LABEL_MAP.put("核事故","NuclearAccident");
        NATURAL_DISASTER_LABEL_MAP.put("化学品泄漏","ChemicalSpill");
        NATURAL_DISASTER_LABEL_MAP.put("油轮泄漏","OilSpill");
        NATURAL_DISASTER_LABEL_MAP.put("矿难","MiningAccident");
        NATURAL_DISASTER_LABEL_MAP.put("食物中毒","FoodPoisoning");
        NATURAL_DISASTER_LABEL_MAP.put("公共卫生事件","PublicHealthEmergency");
        NATURAL_DISASTER_LABEL_MAP.put("建筑物倒塌","BuildingCollapse");
        NATURAL_DISASTER_LABEL_MAP.put("恐怖袭击","Terrorism");
        NATURAL_DISASTER_LABEL_MAP.put("水坝溃坝","DamBurst");
        NATURAL_DISASTER_LABEL_MAP.put("游行抗议","Protest");
        NATURAL_DISASTER_LABEL_MAP.put("冰雹","hail");
        NATURAL_DISASTER_LABEL_MAP.put("冻雨","freezingRain");
        NATURAL_DISASTER_LABEL_MAP.put("霾","hazeWarning");
        NATURAL_DISASTER_LABEL_MAP.put("雷暴","thunderstormWarning");
        NATURAL_DISASTER_LABEL_MAP.put("大风","highWind");
    }

    private final static ObjectMapper objectMapper = new ObjectMapper();
    //    private final static String DEEP_SEEK_URL = "https://api.deepseek.com/chat/completions";
    private final static String DEEP_SEEK_URL = "https://ark.cn-beijing.volces.com/api/v3/chat/completions";

    @Override
    public AIResponse<String> translate(AIRequestDTO AIRequestDTO) {

        ChatInputData chatInputData = new ChatInputData();
        buildTranslate(chatInputData, AIRequestDTO);
        String apiKey = getModelApiKey();
        ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey);

        if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) {
            AIResponse<String> aiResponse = new AIResponse<>();
            aiResponse.setFinish_reason(chatCompletionResponse.getChoices().get(0).getFinish_reason());
            String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
            content = content.replaceAll("```json","").replaceAll("```", "");
            aiResponse.setAnswer(content);
            return aiResponse;
        }
        return null;
    }

    public AIResponse<CodeVO> newsTags(AIRequestDTO aiRequestDTO) {

        ChatInputData chatInputData = new ChatInputData();
        buildNewsTag(chatInputData, aiRequestDTO);
        String apiKey = getModelApiKey();
        ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey);

        if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) {
            AIResponse<CodeVO> aiResponse = new AIResponse<>();
            String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
            aiResponse.setFinish_reason(chatCompletionResponse.getChoices().get(0).getFinish_reason());
            if(StringUtils.isNotEmpty(content)){
                content = content.replaceAll("```json","").replaceAll("```", "");
                String[] split = content.split(",", -1);
                List<CodeVO> result = new ArrayList<>();
                ResultVO<CodeVO> outputs = new ResultVO<>();
                outputs.setResult(result);
                aiResponse.setOutputs(outputs);
                for (String s : split) {
                    if(NEWS_LABEL_MAP.containsKey(s)){
                        CodeVO codeVO = new CodeVO();
                        codeVO.setCode(NEWS_LABEL_MAP.get(s));
                        codeVO.setName(s);
                        result.add(codeVO);
                    }
                }
            }
            return aiResponse;
        }
        return null;
    }

    @Override
    public AIResponse<CodeVO> naturalDisasterTag(AIRequestDTO aiRequestDTO) {
        ChatInputData chatInputData = new ChatInputData();
        buildNaturalDisasterTag(chatInputData, aiRequestDTO);
        String apiKey = getModelApiKey();
        ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey);
        if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) {
            AIResponse<CodeVO> aiResponse = new AIResponse<>();
            String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
            aiResponse.setFinish_reason(chatCompletionResponse.getChoices().get(0).getFinish_reason());
            if(StringUtils.isNotEmpty(content)){
                content = content.replaceAll("```json","").replaceAll("```", "");
                String[] split = content.split(",", -1);
                List<CodeVO> result = new ArrayList<>();
                ResultVO<CodeVO> outputs = new ResultVO<>();
                outputs.setResult(result);
                aiResponse.setOutputs(outputs);
                for (String s : split) {
                    if(NATURAL_DISASTER_LABEL_MAP.containsKey(s)){
                        CodeVO codeVO = new CodeVO();
                        codeVO.setCode(NATURAL_DISASTER_LABEL_MAP.get(s));
                        codeVO.setName(s);
                        result.add(codeVO);
                    }
                }
            }
            return aiResponse;
        }
        return null;
    }

    @Override
    public AIResponse<JSONObject> newsTagAndTranslate(AIRequestDTO aiRequestDTO) {
        ChatInputData chatInputData = new ChatInputData();
        buildNewsTagAndTranslate(chatInputData, aiRequestDTO);
        String apiKey = getModelApiKey();
        ChatCompletionResponse chatCompletionResponse = aiRequest(chatInputData, apiKey);
        if (CollectionUtils.isNotEmpty(chatCompletionResponse.getChoices())) {
            AIResponse<JSONObject> aiResponse = new AIResponse<>();
            String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
            if(StringUtils.isNotEmpty(content)){
                content = content.replaceAll("```json","").replaceAll("```", "");
                JSONArray objects = JSONArray.parseArray(content);
                ArrayList<JSONObject> jsonObjects = new ArrayList<>();
                for (int i = 0; i < objects.size(); i++) {
                    JSONObject jsonObject = objects.getJSONObject(i);
                    jsonObjects.add(jsonObject);
                    if(jsonObject.containsKey("news_tag")){
                        List<CodeVO> codes = new ArrayList<>();
                        JSONArray newsTags = jsonObject.getJSONArray("news_tag");
                        for (int j = 0; j < newsTags.size(); j++) {
                            String newsTag = newsTags.getString(j);
                            if(NEWS_LABEL_MAP.containsKey(newsTag)){
                                String c = NEWS_LABEL_MAP.get(newsTag);
                                CodeVO code = new CodeVO();
                                code.setCode(c);
                                code.setName(newsTag);
                                codes.add(code);
                            }
                        }
                        jsonObject.put("news_tag", JSONObject.toJSON(codes));
                    }
                }
                ResultVO<JSONObject> outputs = new ResultVO<>();
                AnswerVO<JSONObject> answer = new AnswerVO<>();
                answer.setResult(jsonObjects);
                answer.setFinish_reason(chatCompletionResponse.getChoices().get(0).getFinish_reason());
                outputs.setAnswer(answer);
                aiResponse.setOutputs(outputs);
            }
            return aiResponse;
        }
        return null;
    }

    private void buildNewsTagAndTranslate(ChatInputData chatInputData, AIRequestDTO aiRequestDTO) {
        setModel(chatInputData);
        chatInputData.setStream(false);
        List<Message> messages = new ArrayList<>();
        chatInputData.setMessages(messages);
        Message systemRole = getSystemMessageForNewsTagAndTranslate();
        messages.add(systemRole);
        Message userRole = getUserMessageForNewsTagAndTranslate(aiRequestDTO);
        messages.add(userRole);
    }

    private String getModelApiKey() {
        UserHeader userHeader = UserThreadLocal.get();
        String apiKey = appConfig.getApiTranslateKey();
        if(StringUtils.isNotEmpty(userHeader.getModelKey())){
            apiKey = userHeader.getModelKey();
        }
        return apiKey;
    }

    private void buildNaturalDisasterTag(ChatInputData chatInputData, AIRequestDTO aiRequestDTO) {
        setModel(chatInputData);
        chatInputData.setStream(false);
        List<Message> messages = new ArrayList<>();
        chatInputData.setMessages(messages);
        Message systemRole = getSystemMessageForNatureDisaster();
        messages.add(systemRole);
        Message userRole = getUserMessageForNaturalDisasterTag(aiRequestDTO);
        messages.add(userRole);
    }

    private static void setModel(ChatInputData chatInputData) {
        UserHeader userHeader = UserThreadLocal.get();
        if(StringUtils.isNotEmpty(userHeader.getModel())){
            chatInputData.setModel(userHeader.getModel());
        }else {
            chatInputData.setModel("ep-20250407100626-cz4xb");
        }
    }

    private void buildNewsTag(ChatInputData chatInputData, AIRequestDTO AIRequestDTO) {
        setModel(chatInputData);
        chatInputData.setStream(false);
        List<Message> messages = new ArrayList<>();
        chatInputData.setMessages(messages);
        Message systemRole = getSystemMessageForNewsTag();
        messages.add(systemRole);
        Message userRole = getUserMessageForNewsTag(AIRequestDTO);
        messages.add(userRole);
    }

    @NotNull
    private ChatCompletionResponse aiRequest(ChatInputData chatInputData, String apiKey) {
        String writeValueAsString = null;
        try {
            writeValueAsString = objectMapper.writeValueAsString(chatInputData);
        } catch (JsonProcessingException e) {
            throw new BaseException(MsgCode.JSON_ERROR);
        }
        log.info("json:{}", writeValueAsString);
        HttpEntity header = getHeader(apiKey);
        HttpEntity<String> entity = new HttpEntity<>(writeValueAsString, header.getHeaders());
        ResponseEntity<ChatCompletionResponse> response = restTemplate.postForEntity(DEEP_SEEK_URL, entity, ChatCompletionResponse.class);
        if (response.getStatusCode().is2xxSuccessful()) {
            log.info("translate response:{}", JSONObject.toJSONString(response.getBody()));
            return response.getBody();
        }
        throw new BaseException(MsgCode.TRANSLATE_ERROR);
    }

    private void buildTranslate(ChatInputData chatInputData, AIRequestDTO AIRequestDTO) {
        setModel(chatInputData);
        chatInputData.setStream(false);
        List<Message> messages = new ArrayList<>();
        chatInputData.setMessages(messages);
        Message systemRole = getDeepSeekMessage(AIRequestDTO);
        messages.add(systemRole);
    }

    @NotNull
    private static Message getDeepSeekMessage(AIRequestDTO AIRequestDTO) {
        Message systemRole = new Message();
        systemRole.setRole("user");
        systemRole.setContent("需要翻译的JSON:" + AIRequestDTO.getInputs().getRecord_json() + "\n" +
                "\n" +
                "你是一个 JSON 翻译员,能够将给定的 JSON 中的 value 值部分翻译成 `" + AIRequestDTO.getInputs().getLanguage() + "`。\n" +
                "\n" +
                "## 限制\n" +
                "- 严格按照要求进行翻译,不改变 JSON 的结构和无意义的 key 的 value。\n" +
                "- 仅翻译有意义的 value 部分,确保翻译准确、通顺。" +
                "- 无需任何其他说明。" +
                "- 数字、特殊符号(@#%&等)连接的单词无需翻译,其他还需翻译。"
        );
        return systemRole;
    }

    private static Message getUserMessageForNewsTagAndTranslate(AIRequestDTO AIRequestDTO) {
        Message userRole = new Message();
        userRole.setRole("user");
        userRole.setContent(AIRequestDTO.getInputs().getMsg_info());
        return userRole;
    }

    private static Message getUserMessageForNaturalDisasterTag(AIRequestDTO AIRequestDTO) {
        Message userRole = new Message();
        userRole.setRole("user");
        userRole.setContent(AIRequestDTO.getInputs().getWarn_info());
        return userRole;
    }

    private static Message getUserMessageForNewsTag(AIRequestDTO AIRequestDTO) {
        Message userRole = new Message();
        userRole.setRole("user");
        userRole.setContent(AIRequestDTO.getInputs().getMsg_info());
        return userRole;
    }

    @NotNull
    private static Message getSystemMessageForNewsTagAndTranslate() {
        Message systemRole = new Message();
        systemRole.setRole("system");
        systemRole.setContent("```xml\n" +
                "<instruction>\n" +
                "同时对多条新闻内容进行打上新闻标签分类和翻译成指定语言,仅当新闻标签评分达到或超过80分时才应用新闻标签,翻译必须进行,每条数据都唯一标识ID。输入为JSON数组,输出也为JSON数组。具体要求如下:\n" +
                "\n" +
                "1. **输入格式**:  \n" +
                "   - 输入是一个JSON数组,每个对象包含以下字段:  \n" +
                "     - `content`:新闻内容文本  \n" +
                "     - `id`:唯一标识ID  \n" +
                "     - `language`:目标翻译语言  \n" +
                "\n" +
                "2. **输出格式**:  \n" +
                "   - 输出是一个JSON数组,每个对象包含以下字段:\n" +
                "     - `content`:翻译后的新闻内容  \n" +
                "     - `id`:与输入相同的唯一标识ID  \n" +
                "     - `language`:目标翻译语言  \n" +
                "     - `news_tag`:新闻标签列表(仅当评分≥80分时应用)    \n" +
                "\n" +
                "3. **标签分类规则**:  \n" +
                "   - 新闻标签的评分范围为0-100分,仅当评分≥80分时才将标签添加到输出中。  \n" +
                "   - 翻译必须执行,无论标签评分如何。  \n" +
                "\n" +
                "4. **标签列表**:  \n" +
                "   - 人为灾害标签包括:枪击,抢劫,事故爆炸,恐怖袭击,纵火,大规模伤亡事件,人质事件,毒气泄漏,生物危害,交通事故,建筑物倒塌,食品安全事件,社会冲突,群体性事件,环境污染,抗议示威,集体维权,活动失控骚乱,地域冲突,性别冲突,宗教冲突,民族冲突,阶级冲突,食物中毒,地震,火山爆发,山体滑坡,泥石流,雪崩,水坝决口,水坝溃坝,台风/飓风,龙卷风,暴雨,洪水,寒潮,高温热浪,干旱,沙尘暴,冻雨,冰雹,雷暴,大风,山林火灾,冰川融化,海啸,霾,化学品泄漏,核事故,矿难,油轮泄漏,火灾,工业污染,工业事故,传染病爆发,公共卫生事件,持刀伤人,恐怖爆炸,暴力冲突,战争,游行抗议,其他。\n" +
                "\n" +
                "5. **注意事项**:  \n" +
                "   - 输出中不得包含任何XML标签。  \n" +
                "   - 确保每条数据的唯一标识ID与输入一致。  \n" +
                "   - 如果新闻内容无法分类或评分低于80分,则输出“其他”。\n" +
                "</instruction>\n" +
                "```"
        );
        return systemRole;
    }

    @NotNull
    private static Message getSystemMessageForNatureDisaster() {
        Message systemRole = new Message();
        systemRole.setRole("system");
        systemRole.setContent("```xml\n" +
                "<instruction>\n" +
                "根据给定的天气预警信息,打上相应的标签。标签列表包括:大风,雷暴,霾,冻雨,地震,火山爆发,海啸,台风/飓风,龙卷风,洪水,干旱,山体滑坡,泥石流,雪崩,森林火灾,冰川融化,沙尘暴,高温热浪,寒潮,暴雨,工业事故,交通事故,火灾,爆炸,核事故,化学品泄漏,油轮泄漏,矿难,食物中毒,公共卫生事件,建筑物倒塌,恐怖袭击,水坝溃坝,游行抗议,冰雹。\n" +
                "\n" +
                "<instructions>\n" +
                "1. 仔细阅读输入的天气预警信息,理解其描述的具体事件或现象。\n" +
                "2. 根据预警信息的内容,从提供的标签列表中选择最匹配的一个或多个标签。\n" +
                "3. 确保所选标签与预警信息描述的事件或现象完全一致,避免无关标签。\n" +
                "4. 如果预警信息描述的事件或现象不在标签列表中,则忽略该信息或选择最接近的标签。\n" +
                "5. 输出时仅列出匹配的标签,不要包含任何额外的解释或XML标签。\n" +
                "6. 如果预警信息包含多个事件或现象,请为每个事件或现象分别打上对应的标签。\n" +
                "\n" +
                "<examples>\n" +
                "<example>\n" +
                "输入:今日预计有强风,风速可达10级以上,请市民注意防范。\n" +
                "输出:大风\n" +
                "</example>\n" +
                "\n" +
                "<example>\n" +
                "输入:受台风影响,沿海地区将出现暴雨和大风天气,局部地区可能有洪水。\n" +
                "输出:台风/飓风,暴雨,洪水\n" +
                "</example>\n" +
                "\n" +
                "<example>\n" +
                "输入:某化工厂发生泄漏事故,导致周边空气质量下降,建议居民关闭门窗。\n" +
                "输出:化学品泄漏,工业事故\n" +
                "</example>\n" +
                "\n" +
                "<notes>\n" +
                "1. 标签之间用逗号分隔,不要使用空格或其他符号。\n" +
                "2. 如果预警信息描述的事件或现象与多个标签相关,请列出所有相关标签。\n" +
                "3. 确保标签的准确性,避免主观判断或猜测。\n" +
                "4. 输出格式应简洁明了,仅包含标签名称。\n" +
                "</notes>\n" +
                "</instruction>\n" +
                "```"
        );
        return systemRole;
    }

    @NotNull
    private static Message getSystemMessageForNewsTag() {
        Message systemRole = new Message();
        systemRole.setRole("system");
        systemRole.setContent("```xml\n" +
                "<instruction>\n" +
                "对新闻内容进行标签分类,仅当标签评分达到或超过80分时才应用该标签。可选的标签包括:枪击,抢劫,事故爆炸,恐怖袭击,纵火,大规模伤亡事件,人质事件,毒气泄漏,生物危害,交通事故,建筑物倒塌,食品安全事件,社会冲突,群体性事件,环境污染,抗议示威,集体维权,活动失控骚乱,地域冲突,性别冲突,宗教冲突,民族冲突,阶级冲突,食物中毒,地震,火山爆发,山体滑坡,泥石流,雪崩,水坝决口,水坝溃坝,台风/飓风,龙卷风,暴雨,洪水,寒潮,高温热浪,干旱,沙尘暴,冻雨,冰雹,雷暴,大风,山林火灾,冰川融化,海啸,霾,化学品泄漏,核事故,矿难,油轮泄漏,火灾,工业污染,工业事故,传染病爆发,公共卫生事件,持刀伤人,恐怖爆炸,暴力冲突,战争,游行抗议,其他。\n" +
                "\n" +
                "<instructions>\n" +
                "1. 仔细阅读新闻内容,理解其核心事件和背景。\n" +
                "2. 根据新闻内容,评估每个标签的适用性,并为每个标签打分(0-100分)。\n" +
                "3. 仅选择评分达到或超过80分的标签作为最终标签。\n" +
                "4. 如果新闻内容与任何标签的匹配度均低于80分,则输出“其他”。\n" +
                "5. 确保输出结果不包含任何XML标签,仅列出适用的标签名称,多个标签用逗号分隔。\n" +
                "6. 如果新闻内容涉及多个高评分标签,则按相关性从高到低排序。\n" +
                "\n" +
                "<examples>\n" +
                "<example>\n" +
                "输入:某市发生一起持枪抢劫银行事件,造成3人死亡,5人受伤。\n" +
                "输出:枪击, 抢劫, 大规模伤亡事件\n" +
                "</example>\n" +
                "\n" +
                "<example>\n" +
                "输入:某工厂发生化学气体泄漏,导致附近居民出现中毒症状。\n" +
                "输出:毒气泄漏\n" +
                "</example>\n" +
                "\n" +
                "<example>\n" +
                "输入:某地区因土地纠纷引发大规模抗议活动,警方与示威者发生冲突。\n" +
                "输出:社会冲突, 群体性事件\n" +
                "</example>\n" +
                "\n" +
                "<note>\n" +
                "1. 标签评分必须严格遵循80分的阈值,低于80分的标签不得使用。\n" +
                "2. 确保标签的准确性和相关性,避免过度标记或遗漏重要标签。\n" +
                "3. 对于模糊或不确定的内容,优先选择最相关的标签,避免猜测。\n" +
                "4. 输出结果必须简洁明了,仅包含适用的标签名称。\n" +
                "</note>\n" +
                "</instruction>\n" +
                "```"
        );
        return systemRole;
    }

    private HttpEntity getHeader(String token) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("Content-Type", "application/json");
        httpHeaders.set("Authorization", String.format("Bearer %s", token));
        return new HttpEntity<>(httpHeaders);
    }
}