package com.ruoyi.project.utils;

import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.common.Term;
import com.ruoyi.project.domain.*;
import com.ruoyi.project.mapper.*;
import org.ahocorasick.trie.Emit;
import org.ahocorasick.trie.Trie;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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


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

    @Autowired
    private TrsSensitiveWordsTenantMapper trsSensitiveWordsTenantMapper;


    @Autowired
    private TrsResultsLogMapper trsResultsLogMapper;
    @Autowired
    private TrsPolicyWordsMapper trsPolicyWordsMapper;
    @Autowired
    private TrsPolicyWordsTenantMapper trsPolicyWordsTenantMapper;
    public List<TrsResults> getJiaodui(String content, String title, String type){
        // 缓存敏感词的正确词和错误类型
        Map<String, String> correctWordMap = new HashMap<>();
        Map<String, String> errorTypeMap = new HashMap<>();
        Trie trie = loadSensitiveWords(correctWordMap, errorTypeMap);

        Map<String, String> policyErrorRuleMap = new HashMap<>();
        Map<String, String> policyErrorTypeMap = new HashMap<>();
        Map<String, String> nullMap = new HashMap<>();
        Trie policyTrie = loadPolicyWords(policyErrorRuleMap, policyErrorTypeMap);

        List<TrsResults> results = detect(trie, content, title, correctWordMap, errorTypeMap, type);
        List<TrsResults> policyResults = detect(policyTrie, content, title, nullMap, policyErrorTypeMap, type);

        results.addAll(policyResults);
        return results;
    }

    public List<TrsResults> detect(Trie trie, String content,
                                   String title, Map<String, String> correctWordMap, Map<String, String> errorTypeMap, String type) {
        return detectContent(trie, content, title, correctWordMap, errorTypeMap, type);
    }

    private  List<TrsResults> detectContent(Trie trie, String content,
                                            String title, Map<String, String> correctWordMap, Map<String, String> errorTypeMap, String type) {
        List<TrsResults> results = new ArrayList<>();
        for (Emit emit : trie.parseText(content)) {
            String wrongWord = emit.getKeyword();
            String correctWord = correctWordMap.getOrDefault(wrongWord, "未知");
            // 如果匹配到的词在白名单中，则跳过
            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){
                    TrsResults r = new TrsResults();
                    r.setWrongWord(wrongWord);
                    r.setCorrectWord(correctWordMap.getOrDefault(wrongWord, "未知"));
                    r.setErrorType(errorTypeMap.getOrDefault(wrongWord, "未知"));
                    r.setContext(extractContext(content, emit.getStart(), emit.getEnd()));
                    r.setStatus("待处理");
                    results.add(r);
                }

            }
        }

        if("1".equals(type)){
            //审校日志
            TrsResultsLog trsResultsLog = new TrsResultsLog();
            trsResultsLog.setContent(content);
            trsResultsLog.setTitle(title);
            trsResultsLog.setTime(new Date());
            if(results.size()>0){
                trsResultsLog.setStatus("有结果");
                trsResultsLog.setErrortype(results.get(0).getErrorType());
            }else {
                trsResultsLog.setStatus("无结果");
            }
            trsResultsLogMapper.insertTrsResultsLog(trsResultsLog);
        }

        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) {
        Trie.TrieBuilder builder = Trie.builder();

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

        TrsSensitiveWordsTenant trsSensitiveWordsTenant = new TrsSensitiveWordsTenant();
        trsSensitiveWordsTenant.setStatus("已通过");
        List<TrsSensitiveWordsTenant> sensitiveWordsTenants = trsSensitiveWordsTenantMapper.selectTrsSensitiveWordsList(trsSensitiveWordsTenant);
        for (TrsSensitiveWordsTenant sensitiveWord : sensitiveWordsTenants) {
            String wrongWord = sensitiveWord.getWrongWord();
            builder.addKeyword(wrongWord);
            correctWordMap.put(wrongWord, sensitiveWord.getCorrectWord());
//            errorTypeMap.put(wrongWord, sensitiveWord.getErrorType());
            errorTypeMap.put(wrongWord, "common");
        }
        return builder.build();
    }

    public Trie loadPolicyWords(Map<String, String> policyErrorRuleMap, Map<String, String> policyErrorTypeMap) {
        Trie.TrieBuilder builder = Trie.builder();
        TrsPolicyWords results = new TrsPolicyWords();
        results.setStatus("已通过");
        List<TrsPolicyWords> results1 = trsPolicyWordsMapper.selectTrsPolicyWordsList(results);
        for (TrsPolicyWords sensitiveWord : results1) {
            String wrongWord = sensitiveWord.getWrongWord();
            builder.addKeyword(wrongWord);
//            policyErrorRuleMap.put(wrongWord, sensitiveWord.getErrorRule());
//            policyErrorTypeMap.put(wrongWord, sensitiveWord.getErrorType());
            policyErrorTypeMap.put(wrongWord, "political");
        }

        TrsPolicyWordsTenant trsPolicyWordsTenant = new TrsPolicyWordsTenant();
        trsPolicyWordsTenant.setStatus("已通过");
        List<TrsPolicyWordsTenant> trsPolicyWordsTenants = trsPolicyWordsTenantMapper.selectTrsPolicyWordsList(trsPolicyWordsTenant);
        for (TrsPolicyWordsTenant sensitiveWord : trsPolicyWordsTenants) {
            String wrongWord = sensitiveWord.getWrongWord();
            builder.addKeyword(wrongWord);
//            policyErrorRuleMap.put(wrongWord, sensitiveWord.getErrorRule());
//            policyErrorTypeMap.put(wrongWord, sensitiveWord.getErrorType());
            policyErrorTypeMap.put(wrongWord, "political");
        }
        return builder.build();
    }

}
