"""
Cypher 错误修复模块

功能：修复常见的 Cypher 语法错误和格式问题
"""

import re
import logging

logger = logging.getLogger(__name__)


def parse_cypher_error(error_message: str, cypher: str) -> dict:
    """
    解析Cypher错误信息，提取错误类型、位置等详细信息
    """
    error_info = {
        "error_type": "unknown",
        "error_message": error_message,
        "error_position": None,
        "suggested_fix": None
    }
    
    error_lower = error_message.lower()
    
    # ========== 识别错误类型 ==========
    if "unexpected" in error_lower or "expected" in error_lower:
        error_info["error_type"] = "syntax_unexpected"
    elif "invalid" in error_lower:
        error_info["error_type"] = "syntax_invalid"
    elif "missing" in error_lower:
        error_info["error_type"] = "syntax_missing"
    elif "cannot" in error_lower or "can't" in error_lower:
        error_info["error_type"] = "semantic_error"
    elif "unknown" in error_lower or "not found" in error_lower:
        error_info["error_type"] = "schema_error"
    elif "syntax" in error_lower:
        error_info["error_type"] = "syntax_error"
    
    # ========== 提取错误位置（如果错误信息中包含位置信息） ==========
    # Neo4j错误信息可能包含位置，如 "line 1, column 10"
    position_match = re.search(r'line\s+(\d+)[,\s]+column\s+(\d+)', error_message, re.IGNORECASE)
    if position_match:
        line_num = int(position_match.group(1))
        col_num = int(position_match.group(2))
        error_info["error_position"] = {"line": line_num, "column": col_num}
        
        # 提取错误位置的上下文
        lines = cypher.split('\n')
        if line_num <= len(lines):
            error_line = lines[line_num - 1]
            error_info["error_context"] = error_line
            if col_num <= len(error_line):
                # 标记错误位置
                marker = ' ' * (col_num - 1) + '^'
                error_info["error_marker"] = marker
    
    # ========== 提取错误相关的关键词 ==========
    # 提取错误信息中提到的标签、关系、关键字等
    keywords = []
    # 匹配可能的标签名（大写字母开头的单词）
    label_matches = re.findall(r'\b([A-Z][a-zA-Z0-9_]+)\b', error_message)
    keywords.extend(label_matches)
    # 匹配引号中的内容
    quoted_matches = re.findall(r'["\']([^"\']+)["\']', error_message)
    keywords.extend(quoted_matches)
    error_info["keywords"] = list(set(keywords))
    
    return error_info


def force_undirected_relationships(cypher: str) -> str:
    """
    强制将所有有方向的关系转换为无方向关系
    """
    if not cypher:
        return cypher
    
    # 替换所有有方向的关系为无方向关系
    # 匹配模式：-[:RELATIONSHIP]-> 或 <-[:RELATIONSHIP]-
    # 替换为：-[:RELATIONSHIP]-
    
    # 替换 -> 为 -（在关系类型之后）
    # 需要小心处理，只替换关系箭头，不替换其他地方的 ->
    # 使用正则表达式匹配关系模式
    fixed = cypher
    
    # 替换 -[:RELATIONSHIP]-> 为 -[:RELATIONSHIP]-
    fixed = re.sub(r'(\[:[^\]]+\])->', r'\1-', fixed)
    
    # 替换 <-[:RELATIONSHIP]- 为 -[:RELATIONSHIP]-
    fixed = re.sub(r'<-(\[:[^\]]+\])-', r'-\1-', fixed)
    
    # 替换 -> 在关系模式中（处理可变长度关系，如 [*1..3]->）
    fixed = re.sub(r'(\[[^\]]+\])->', r'\1-', fixed)
    
    # 替换 <- 在关系模式中（处理可变长度关系，如 <-[*1..3]-）
    fixed = re.sub(r'<-(\[[^\]]+\])-', r'-\1-', fixed)
    
    # 如果进行了替换，记录日志
    if fixed != cypher:
        logger.info(f"[关系方向转换] 检测到有方向关系，已自动转换为无方向关系")
        logger.debug(f"[关系方向转换] 原始: {cypher[:200]}...")
        logger.debug(f"[关系方向转换] 转换后: {fixed[:200]}...")
    
    return fixed


def fix_cypher_based_on_error(cypher: str, error_info: dict) -> str:
    """
    基于实际错误信息智能修复Cypher
    """
    if not error_info or not error_info.get("error_type"):
        return None
    
    error_type = error_info["error_type"]
    error_message = error_info.get("error_message", "")
    fixed = cypher
    
    # ========== 根据错误类型进行修复 ==========
    
    # 1. 语法错误：多余的括号
    if "unexpected" in error_message.lower() and ("(" in error_message or ")" in error_message):
        # 尝试修复多余的括号
        # 匹配 `-[:REL]- ( (n:Label)` 这种模式
        fixed = re.sub(r'(\[:[^\]]+\])-\s+\(\s*\(', r'\1-(', fixed)
        fixed = re.sub(r'\)\s*-\s*(\[:[^\]]+\])-\s+\(\s*\(', r')-\1-(', fixed)
        if fixed != cypher:
            logger.info(f"[智能修复] 修复多余括号错误")
            return fixed
    
    # 2. 语法错误：缺少括号
    if "missing" in error_message.lower() and ("(" in error_message or ")" in error_message):
        # 检查括号是否匹配
        open_count = fixed.count('(')
        close_count = fixed.count(')')
        if open_count > close_count:
            # 缺少右括号，在末尾添加
            fixed = fixed + ')' * (open_count - close_count)
            logger.info(f"[智能修复] 添加缺失的右括号: {open_count - close_count} 个")
            return fixed
        elif close_count > open_count:
            # 多余的右括号，但这种情况较难自动修复，返回None
            logger.warning(f"[智能修复] 检测到多余的右括号，无法自动修复")
            return None
    
    # 3. 语法错误：关系定义问题
    if "relationship" in error_message.lower() or "relationship type" in error_message.lower():
        # 检查关系定义格式
        # 修复 `-[:REL]- (n:Label)` -> `-[:REL]-(n:Label)`
        fixed = re.sub(r'(\[:[^\]]+\])-\s+\(', r'\1-(', fixed)
        if fixed != cypher:
            logger.info(f"[智能修复] 修复关系定义格式")
            return fixed
    
    # 4. Schema错误：节点标签或关系类型不存在
    if error_info["error_type"] == "schema_error":
        keywords = error_info.get("keywords", [])
        # 这里可以尝试其他修复策略
        logger.debug(f"[智能修复] Schema错误，关键词: {keywords}")
        # Schema错误通常需要LLM修正，这里不自动修复
        return None
    
    # 5. 语法错误：位置相关的修复
    if error_info.get("error_position"):
        pos = error_info["error_position"]
        line_num = pos.get("line", 1)
        col_num = pos.get("column", 1)
        
        lines = fixed.split('\n')
        if line_num <= len(lines):
            error_line = lines[line_num - 1]
            # 检查错误位置附近的字符
            if col_num <= len(error_line):
                char_at_error = error_line[col_num - 1] if col_num > 0 else ''
                context = error_line[max(0, col_num-10):min(len(error_line), col_num+10)]
                
                # 如果是多余的字符，尝试删除
                if char_at_error in ['(', ')', ' ', '-']:
                    # 检查是否是明显的多余字符
                    before = error_line[:col_num-1] if col_num > 0 else ''
                    after = error_line[col_num:] if col_num < len(error_line) else ''
                    
                    # 如果前后都是关系连接符，中间的字符可能是多余的
                    if re.search(r'[-\s]*$', before) and re.search(r'^[-\s]*', after):
                        # 尝试删除错误位置的字符
                        new_line = error_line[:col_num-1] + error_line[col_num:]
                        lines[line_num - 1] = new_line
                        fixed = '\n'.join(lines)
                        logger.info(f"[智能修复] 删除错误位置的字符: '{char_at_error}'")
                        return fixed
    
    # 6. 通用修复：尝试修复常见的格式问题
    # 修复关系后的多余空格
    fixed = re.sub(r'(\[:[^\]]+\])-\s+\(', r'\1-(', fixed)
    # 修复节点定义前的多余括号
    fixed = re.sub(r'\(\s+\(([a-zA-Z_][a-zA-Z0-9_]*\s*:)', r'(\1', fixed)
    
    if fixed != cypher:
        logger.info(f"[智能修复] 应用通用修复")
        return fixed
    
    # 无法自动修复
    return None


def fix_common_cypher_errors(cypher: str) -> str:
    """
    修复常见的Cypher语法错误
    """
    if not cypher:
        return cypher
    
    fixed = cypher
    
    # ========== 修复1：关系后多余的空格和括号 ==========
    # 匹配模式：`-[:REL]- ( (n:Label)` -> `-[:REL]-(n:Label)`
    # 或者 `-[:REL]- (n:Label)` -> `-[:REL]-(n:Label)`
    fixed = re.sub(r'(\[:[^\]]+\])-\s+\(\s*\(', r'\1-(', fixed)  # `-[:REL]- ( (` -> `-[:REL]-(`
    fixed = re.sub(r'(\[:[^\]]+\])-\s+\(([a-zA-Z_][a-zA-Z0-9_]*\s*:)', r'\1-(\2', fixed)  # `-[:REL]- (n:` -> `-[:REL]-(n:`
    
    # ========== 修复2：节点定义前多余的括号 ==========
    # 匹配模式：`( (n:Label)` -> `(n:Label)`
    fixed = re.sub(r'\(\s+\(([a-zA-Z_][a-zA-Z0-9_]*\s*:)', r'(\1', fixed)
    
    # ========== 修复3：MATCH语句中的多余空格和括号 ==========
    # 匹配模式：`MATCH ...)-[:REL]- ( (n:Label)` -> `MATCH ...)-[:REL]-(n:Label)`
    fixed = re.sub(r'\)\s*-\s*(\[:[^\]]+\])-\s+\(\s*\(', r')-\1-(', fixed)
    fixed = re.sub(r'\)\s*-\s*(\[:[^\]]+\])-\s+\(([a-zA-Z_][a-zA-Z0-9_]*\s*:)', r')-\1-(\2', fixed)
    
    # ========== 修复4：规范化关系定义后的空格 ==========
    # 确保关系定义后直接跟节点定义，如 `-[:REL]-(n:Label)` 而不是 `-[:REL]- (n:Label)`
    fixed = re.sub(r'(\[:[^\]]+\])-\s+\(', r'\1-(', fixed)
    
    if fixed != cypher:
        logger.info(f"[Cypher修复] 检测到并修复了常见语法错误")
        logger.debug(f"[Cypher修复] 原始: {cypher[:200]}...")
        logger.debug(f"[Cypher修复] 修复后: {fixed[:200]}...")
    
    return fixed
