package com.ruoyi.project.utils;

import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.common.Term;
import com.ruoyi.common.utils.IpUtils;
import com.ruoyi.project.domain.*;
import com.ruoyi.project.mapper.TrsPolicyWordsMapper;
import com.ruoyi.project.mapper.TrsResultsLogMapper;
import com.ruoyi.project.mapper.TrsSensitiveWordsMapper;
import com.ruoyi.project.mapper.TrsWordResultsMapper;
import com.ruoyi.project.service.ITrsWordResultsService;
import org.ahocorasick.trie.Emit;
import org.ahocorasick.trie.Trie;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.ruoyi.common.utils.ShiroUtils.getSysUser;


/**
 * 字典工具类
 *
 * @author ruoyi
 */
@Component
public class TrsPUtils
{
    @Autowired
    private TrsSensitiveWordsMapper trsSensitiveWordsMapper;

    @Autowired
    private TrsResultsLogMapper trsResultsLogMapper;

    @Autowired
    private TrsWordResultsMapper trsWordResultsMapper;
    @Autowired
    private TrsPolicyWordsMapper trsPolicyWordsMapper;


    public void getJiaodui(String content, String title, String type, HttpServletRequest request, TrsResultsLog trsResultsLog){
        // 缓存敏感词的正确词和错误类型
        Map<String, String> correctWordMap = new HashMap<>();
        Map<String, String> errorTypeMap = new HashMap<>();
        Map<String, String> errorGradeMap = new HashMap<>();
        Trie trie = loadSensitiveWords(correctWordMap, errorTypeMap, errorGradeMap);

        Map<String, String> policyErrorRuleMap = new HashMap<>();
        Map<String, String> policyErrorTypeMap = new HashMap<>();
        Map<String, String> policyErrorGradeMap = new HashMap<>();
        Map<String, String> policySourceMap = new HashMap<>();
        Map<String, String> policyUrlMap = new HashMap<>();
        Map<String, String> nullMap = new HashMap<>();
        Trie policyTrie = loadPolicyWords(policyErrorRuleMap, policyErrorTypeMap, policySourceMap, policyUrlMap, policyErrorGradeMap);
        content = Jsoup.parse(content).text();

        List<TrsWordResults> results = detect(trsResultsLog.getId(),trie, content, title, correctWordMap, errorTypeMap, type, "political", null,null, errorGradeMap);
        List<TrsWordResults> policyResults = detect(trsResultsLog.getId(),policyTrie, content, title, nullMap, policyErrorTypeMap, type,"political", policySourceMap,policyUrlMap, policyErrorGradeMap);
        results.addAll(policyResults);

        //审校日志
        if("无结果".equals(trsResultsLog.getStatus()) && results.size()>0){
            trsResultsLog.setStatus("有结果");
            trsResultsLog.setErrortype(results.get(0).getErrorType());
            trsResultsLogMapper.updateTrsResultsLog(trsResultsLog);
        }

    }

    public List<TrsWordResults> detect(Long logId, Trie trie, String content,
                                       String title, Map<String, String> correctWordMap, Map<String, String> errorTypeMap, String type, String typeStr, Map<String, String> sourceMap, Map<String, String> policyUrlMap, Map<String, String> errorGradeMap) {
        return detectContent(logId, trie, content, title, correctWordMap, errorTypeMap, type, typeStr, sourceMap, policyUrlMap, errorGradeMap);
    }

    private  List<TrsWordResults> detectContent(Long logId, Trie trie, String content,
                                                String title, Map<String, String> correctWordMap, Map<String, String> errorTypeMap, String type, String typeStr, Map<String, String> sourceMap, Map<String, String> policyUrlMap, Map<String, String> errorGradeMap) {


        List<TrsWordResults> results = new ArrayList<>();
        for (Emit emit : trie.parseText(content)) {
            String wrongWord = emit.getKeyword();
            String correctWord = correctWordMap.getOrDefault(wrongWord, "");
            if(wrongWord.equals(correctWord))continue;
            // 如果匹配到的词在白名单中，则跳过
            if (isInWhitelist(content, emit.getStart(), emit.getEnd() + 1)) {
                continue;
            }
            // 只匹配独立的词，确保不是误匹配
//            Matcher matcher = Pattern.compile("\\b" + Pattern.quote(wrongWord) + "\\b").matcher(content);
            Matcher matcher = Pattern.compile(Pattern.quote(wrongWord) ).matcher(content);
            if (matcher.find()) {
                // 先对文章进行分词
                boolean flag = true;
                String subString = extractContext(content, emit.getStart(), emit.getEnd());
                if(subString!=null&&subString.contains(correctWord)&&subString.contains(wrongWord)&&!wrongWord.contains(correctWord)){
                    flag=false;
                }
                List<String> words = segmentText(wrongWord);
                for(String word:words){
                    if (!wrongWord.contains(word)) {
                        flag=false;
                    }
                }
                List<String> subStringseg = segmentText(subString);
                //List<String> correctWordseg = segmentText(correctWord);
                if (!subStringseg.contains(wrongWord)) {
                    if(!subStringseg.containsAll(words))
                        flag=false;
                }
                /*if (!subStringseg.contains(wrongWord)&&!subStringseg.stream().anyMatch(words::contains)) {
                    flag=false;
                }*/
                if(flag){
                    TrsWordResults r = new TrsWordResults();
                    r.setLogId(logId);
                    r.setWrongWord(wrongWord);
                    r.setCorrectWord(correctWordMap.getOrDefault(wrongWord, ""));
                    r.setSitename(typeStr);
                    r.setTime(new Date());
                    if (null!=errorTypeMap){
                        r.setErrorType(errorTypeMap.getOrDefault(wrongWord, ""));
                    }
                    if (null!=errorGradeMap){
                        r.setErrorGrade(errorGradeMap.getOrDefault(wrongWord, ""));
                    }
                    if(null!=sourceMap){
                        r.setSource(sourceMap.getOrDefault(wrongWord, ""));
                    }
                    if(null!=policyUrlMap){
                        r.setUrl(policyUrlMap.getOrDefault(wrongWord, ""));
                    }
                    r.setContent(extractContext(content, emit.getStart(), emit.getEnd()));
                    trsWordResultsMapper.insertTrsWordResults(r);
                    results.add(r);
                }
                //记录错词日志
            }
        }

        return results;
    }

    // 提取上下文（示例：前后 20 字符）
    private  String extractContext(String text, int start, int end) {
        int contextSize = 20;
        int contextStart = Math.max(0, start - contextSize);
        int contextEnd = Math.min(text.length(), end + contextSize);
        return text.substring(contextStart, contextEnd);
    }

    public List<String> segmentText(String text) {
        List<Term> termList = HanLP.segment(text);
        List<String> words = new ArrayList<>();
        for (Term term : termList) {
            words.add(term.word);
        }
        return words;
    }

    private Set<String> whitelistPhrases = new HashSet<>();
    public void loadWhitelist() {
        // 这里可以从数据库或配置文件加载白名单
        /*whitelistPhrases.add("内蒙古自治区");
        whitelistPhrases.add("中国银行");
        whitelistPhrases.add("中华人民共和国");*/
        TrsSensitiveWords trsSensitiveWords = new TrsSensitiveWords();
        trsSensitiveWords.setFlag(0);
        trsSensitiveWordsMapper.selectTrsSensitiveWordsListBy(new TrsSensitiveWords()).forEach(sensitiveWord -> {
            whitelistPhrases.add(sensitiveWord.getWrongWord());
        });
    }
    private boolean isInWhitelist(String text, int start, int end) {
        for (String phrase : whitelistPhrases) {
            int phraseStart = start - (phrase.length() - (end - start)); // 计算完整短语的起点
            if (phraseStart >= 0 && phraseStart + phrase.length() <= text.length()) {
                String subText = text.substring(phraseStart, phraseStart + phrase.length());
                if (whitelistPhrases.contains(subText)) {
                    return true; // 如果匹配到白名单短语，则跳过
                }
            }
        }
        return false;
    }

    public Trie loadSensitiveWords(Map<String, String> correctWordMap, Map<String, String> errorTypeMap, Map<String, String> errorGradeMap) {
        Trie.TrieBuilder builder = Trie.builder();

        TrsSensitiveWords trsSensitiveWords = new TrsSensitiveWords();
        trsSensitiveWords.setStatus("已通过");
//        List<TrsSensitiveWords> sensitiveWords = trsSensitiveWordsMapper.selectTrsSensitiveWordsList_jiaodui(trsSensitiveWords);
        List<TrsSensitiveWords> sensitiveWords = new ArrayList<>();
        sensitiveWords.addAll(trsSensitiveWordsMapper.selectTrsSensitiveWordsList(trsSensitiveWords));
        for (TrsSensitiveWords sensitiveWord : sensitiveWords) {
            String wrongWord = sensitiveWord.getWrongWord();
            builder.addKeyword(wrongWord);
            correctWordMap.put(wrongWord, sensitiveWord.getCorrectWord());
            errorTypeMap.put(wrongWord, sensitiveWord.getErrorType());
            errorGradeMap.put(wrongWord, sensitiveWord.getErrorGrade());
//            errorTypeMap.put(wrongWord, "common");
        }
        return builder.build();
    }

    public Trie loadPolicyWords(Map<String, String> policyErrorRuleMap, Map<String, String> policyErrorTypeMap, Map<String, String> policySourceMap, Map<String, String> policyUrlMap, Map<String, String> policyErrorGradeMap) {
        Trie.TrieBuilder builder = Trie.builder();
        TrsPolicyWords results = new TrsPolicyWords();
        results.setStatus("已通过");
//        List<TrsPolicyWords> results1 = trsPolicyWordsMapper.selectTrsPolicyWordsList_jiaodui(results);
        List<TrsPolicyWords> results1 = new ArrayList<>();
        results1.addAll(trsPolicyWordsMapper.selectTrsPolicyWordsList(results));
        for (TrsPolicyWords sensitiveWord : results1) {
            String wrongWord = sensitiveWord.getWrongWord();
            builder.addKeyword(wrongWord);
//            policyErrorRuleMap.put(wrongWord, sensitiveWord.getErrorRule());
            policyErrorTypeMap.put(wrongWord, sensitiveWord.getErrorType());
            policySourceMap.put(wrongWord, sensitiveWord.getSource());
            policyUrlMap.put(wrongWord, sensitiveWord.getLinkurl());
            policyErrorGradeMap.put(wrongWord, sensitiveWord.getErrorGrade());
//            policyErrorTypeMap.put(wrongWord, "political");
        }
        return builder.build();
    }

}
