package com.warmer.web.service.impl;

import com.warmer.base.service.KeywordExtractionService;
import com.warmer.base.util.Neo4jUtil;
import com.warmer.web.request.GraphQuery;
import com.warmer.web.service.IntelligentSearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 智能搜索服务实现类
 * 
 * @author tanc
 */
@Service
public class IntelligentSearchServiceImpl implements IntelligentSearchService {

    @Autowired
    private KeywordExtractionService keywordExtractionService;
    @Autowired
    private com.warmer.web.service.CustomDictService customDictService;

    @Override
    public Map<String, Object> intelligentSearch(String text, String domain) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 1. 关键词提取
            List<String> keywords = extractKeywords(text);
            
            // 2. 在知识图谱中搜索匹配的节点和关系
            Map<String, Object> searchResult = searchInKnowledgeGraph(keywords, domain);
            
            // 3. 整合结果
            result.put("success", true);
            result.put("originalText", text);
            result.put("domain", domain);
            result.put("extractedKeywords", keywords);
            result.put("nodes", searchResult.get("nodes"));
            result.put("links", searchResult.get("relationships")); // 前端期望的字段名
            result.put("relationships", searchResult.get("relationships")); // 保持兼容性
            result.put("matchedCount", searchResult.get("matchedCount"));
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "搜索过程中发生错误: " + e.getMessage());
            result.put("originalText", text);
            result.put("domain", domain);
            result.put("nodes", new ArrayList<>());
            result.put("links", new ArrayList<>());
            result.put("relationships", new ArrayList<>());
        }
        
        return result;
    }
    

    
    /**
     * 判断是否为停用词
     */
    private boolean isStopWord(String word) {
        Set<String> stopWords = new HashSet<>(Arrays.asList(
            "的", "了", "在", "是", "我", "有", "和", "就", "不", "人", "都", "一", "一个", "上", "也", "很", "到", "说", "要", "去", "你", "会", "着", "没有", "看", "好", "自己", "这",
            "the", "a", "an", "and", "or", "but", "in", "on", "at", "to", "for", "of", "with", "by", "is", "are", "was", "were", "be", "been", "have", "has", "had", "do", "does", "did", "will", "would", "could", "should"
        ));
        return stopWords.contains(word.toLowerCase());
    }
    
    /**
     * 在知识图谱中搜索匹配的节点和关系
     */
    private Map<String, Object> searchInKnowledgeGraph(List<String> keywords, String domain) {
        Map<String, Object> result = new HashMap<>();
        List<HashMap<String, Object>> allNodes = new ArrayList<>();
        List<HashMap<String, Object>> allRelationships = new ArrayList<>();
        Set<String> processedNodeIds = new HashSet<>();
        int matchedCount = 0;
        
        if (keywords.isEmpty() || StringUtils.isEmpty(domain)) {
            result.put("nodes", allNodes);
            result.put("relationships", allRelationships);
            result.put("matchedCount", matchedCount);
            return result;
        }
        
        try {
            // 为每个关键词搜索匹配的节点
            for (String keyword : keywords) {
                // 构建Cypher查询语句，使用CONTAINS进行模糊匹配
                String cypherSql = String.format(
                    "MATCH (n:`%s`) WHERE n.name CONTAINS '%s' " +
                    "OPTIONAL MATCH (n)-[r]-(m:`%s`) " +
                    "RETURN n, r, m LIMIT 10", 
                    domain, keyword, domain
                );
                
                // 执行查询
                HashMap<String, Object> searchResult = Neo4jUtil.getGraphNodeAndShip(cypherSql);
                
                if (searchResult != null) {
                    // 处理节点 - Neo4jUtil返回的字段是 "node"
                    @SuppressWarnings("unchecked")
                    List<HashMap<String, Object>> nodes = (List<HashMap<String, Object>>) searchResult.get("node");
                    if (nodes != null) {
                        for (HashMap<String, Object> node : nodes) {
                            String nodeId = String.valueOf(node.get("uuid"));
                            if (!processedNodeIds.contains(nodeId)) {
                                allNodes.add(node);
                                processedNodeIds.add(nodeId);
                                matchedCount++;
                            }
                        }
                    }
                    
                    // 处理关系 - Neo4jUtil返回的字段是 "relationship"
                    @SuppressWarnings("unchecked")
                    List<HashMap<String, Object>> relationships = (List<HashMap<String, Object>>) searchResult.get("relationship");
                    if (relationships != null) {
                        allRelationships.addAll(relationships);
                    }
                }
            }
            
            // 如果没有找到匹配的节点，尝试更宽泛的搜索
            if (allNodes.isEmpty() && !keywords.isEmpty()) {
                // 搜索包含任意关键词的节点
                String keywordPattern = String.join("|", keywords);
                String cypherSql = String.format(
                    "MATCH (n:`%s`) WHERE n.name =~ '.*(%s).*' " +
                    "RETURN n LIMIT 20", 
                    domain, keywordPattern
                );
                
                List<HashMap<String, Object>> nodes = Neo4jUtil.getGraphNode(cypherSql);
                if (nodes != null) {
                    allNodes.addAll(nodes);
                    matchedCount = nodes.size();
                }
            }
            
        } catch (Exception e) {
            // 记录错误但不抛出异常，返回空结果
            System.err.println("搜索知识图谱时发生错误: " + e.getMessage());
        }
        
        // 去重关系
        allRelationships = allRelationships.stream()
            .collect(Collectors.toMap(
                rel -> rel.get("uuid"),
                rel -> rel,
                (existing, replacement) -> existing
            ))
            .values()
            .stream()
            .collect(Collectors.toList());
        
        // 确保返回空列表而不是null
        result.put("nodes", allNodes != null ? allNodes : new ArrayList<>());
        result.put("relationships", allRelationships != null ? allRelationships : new ArrayList<>());
        result.put("matchedCount", matchedCount);
        
        return result;
    }

    @Override
    public Map<String, Object> searchNodesByKeyword(String keyword, String domain) {
        try {
            // 如果没有指定领域，尝试在所有领域中搜索
            if (domain == null || domain.trim().isEmpty()) {
                // 可以在这里实现跨领域搜索逻辑
                // 暂时返回空结果
                return createEmptySearchResult();
            }
            
            // 构建Cypher查询语句，使用CONTAINS进行模糊匹配
            String cypherSql = String.format(
                "MATCH (n:`%s`) WHERE n.name CONTAINS '%s' " +
                "OPTIONAL MATCH (n)-[r]-(m:`%s`) " +
                "RETURN n, r, m LIMIT 10", 
                domain, keyword, domain
            );
            
            // 执行查询
            return Neo4jUtil.getGraphNodeAndShip(cypherSql);
        } catch (Exception e) {
            System.err.println("搜索节点时出错: " + e.getMessage());
            return createEmptySearchResult();
        }
    }

    @Override
    public Map<String, Object> createEmptySearchResult() {
        Map<String, Object> result = new HashMap<>();
        result.put("nodes", new ArrayList<>());
        result.put("relationships", new ArrayList<>());
        return result;
    }

    @Override
    public List<Map<String, Object>> removeDuplicateNodes(List<Map<String, Object>> nodes) {
        Map<String, Map<String, Object>> uniqueNodes = new HashMap<>();
        for (Map<String, Object> node : nodes) {
            String nodeId = String.valueOf(node.get("uuid"));
            if (nodeId != null && !uniqueNodes.containsKey(nodeId)) {
                uniqueNodes.put(nodeId, node);
            }
        }
        return new ArrayList<>(uniqueNodes.values());
    }

    @Override
    public List<Map<String, Object>> removeDuplicateRelations(List<Map<String, Object>> relations) {
        Map<String, Map<String, Object>> uniqueRelations = new HashMap<>();
        for (Map<String, Object> relation : relations) {
            String relationKey = relation.get("sourceId") + "-" + relation.get("targetId") + "-" + relation.get("relation");
            if (!uniqueRelations.containsKey(relationKey)) {
                uniqueRelations.put(relationKey, relation);
            }
        }
        return new ArrayList<>(uniqueRelations.values());
    }

    @Override
    public GraphQuery processIntelligentSearch(GraphQuery query) {
        // 处理智能搜索请求的逻辑
        if (query != null && query.getOriginalText() != null) {
            // 提取关键词并设置到查询对象中
            List<String> keywords = extractKeywords(query.getOriginalText());
            // 设置提取的关键词到查询对象中
            if (keywords != null && !keywords.isEmpty()) {
                query.setKeywords(keywords.toArray(new String[0]));
            }
        }
        return query;
    }

    @Override
    public List<KeywordExtractionService.KeywordInfo> getKeywordExtractionResult(String text) {
        return keywordExtractionService.extractKeywordsWithInfo(text);
    }

    @Override
    public List<KeywordExtractionService.KeywordInfo> getKeywordExtractionResultMap(String text) {
        return keywordExtractionService.extractKeywordsWithInfo(text);
    }

    @Override
    public List<String> extractKeywords(String text) {
        // 保障DB词典已加载到HanLP，避免每次都改代码
        customDictService.loadAllToHanLPIfNeeded();
        return keywordExtractionService.extractKeywords(text);
        
        /* 本地简单实现（如果不想使用KeywordExtractionService可以使用这个）
        if (StringUtils.isEmpty(text)) {
            return new ArrayList<>();
        }
        
        // 移除标点符号和特殊字符，保留中文、英文和数字
        String cleanText = text.replaceAll("[\\p{Punct}\\s]+", " ");
        
        // 分词（简单按空格分割，实际项目中可以使用jieba等分词工具）
        String[] words = cleanText.split("\\s+");
        
        List<String> keywords = new ArrayList<>();
        for (String word : words) {
            word = word.trim();
            if (!StringUtils.isEmpty(word) && word.length() > 1) {
                // 过滤掉常见的停用词
                if (!isStopWord(word)) {
                    keywords.add(word);
                }
            }
        }
        
        // 去重并返回
        return keywords.stream().distinct().collect(Collectors.toList());
        */
    }
    
    @Override
    public List<String> getSearchSuggestions(String query, String domain) {
        List<String> suggestions = new ArrayList<>();
        
        try {
            if (query == null || query.trim().isEmpty() || domain == null || domain.trim().isEmpty()) {
                return suggestions;
            }
            
            // 构建Cypher查询，获取包含查询关键词的节点名称
            String cypherSql = String.format(
                "MATCH (n:`%s`) WHERE n.name CONTAINS '%s' " +
                "RETURN DISTINCT n.name as name LIMIT 10", 
                domain, query.trim()
            );
            
            // 执行查询
            List<HashMap<String, Object>> results = Neo4jUtil.getGraphTable(cypherSql);
            
            if (results != null && !results.isEmpty()) {
                for (HashMap<String, Object> result : results) {
                    Object nameObj = result.get("name");
                    if (nameObj != null) {
                        String name = nameObj.toString();
                        // 移除可能的引号
                        name = name.replaceAll("^\"|\"$", "");
                        if (!name.isEmpty()) {
                            suggestions.add(name);
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("获取搜索建议时出错: " + e.getMessage());
        }
        
        return suggestions;
    }
}