"""
猴子补丁模块
用于修复第三方库的已知问题
"""
from loguru import logger

# 标记补丁是否已应用，避免重复
_PATCHES_APPLIED = {
    'qdrant': False,
    'openai': False
}


def patch_qdrant_vector_store():
    """
    修补 QdrantVectorStore 的兼容性问题
    
    问题：某些版本的 QdrantVectorStore 在 Pydantic 模型中定义了必需的 path 字段，
    但 __init__ 方法不接受 path 参数，导致使用 client 参数时验证失败
    
    解决方案：检测是否需要 path 参数，并记录该信息供调用方使用
    注意：不再使用 model_rebuild()，因为会破坏 Pydantic 私有属性
    """
    global _PATCHES_APPLIED
    
    if _PATCHES_APPLIED['qdrant']:
        logger.debug("QdrantVectorStore 补丁检测已完成，跳过")
        return
    
    try:
        from llama_index.vector_stores.qdrant import QdrantVectorStore
        
        # 检查是否是 Pydantic 模型且有 path 字段
        has_path_field = hasattr(QdrantVectorStore, 'model_fields') and 'path' in QdrantVectorStore.model_fields
        
        if has_path_field:
            path_field = QdrantVectorStore.model_fields['path']
            if path_field.is_required():
                logger.info("检测到 QdrantVectorStore path 字段为必需，调用时需要传入 path=None")
        
        _PATCHES_APPLIED['qdrant'] = True
        return QdrantVectorStore
        
    except Exception as e:
        logger.warning(f"检测 QdrantVectorStore 配置失败: {e}")
        _PATCHES_APPLIED['qdrant'] = True
        return None


def patch_openai_llm():
    """
    修补 OpenAI LLM 以支持自定义模型（如 deepseek-chat）
    
    问题：OpenAI LLM 会验证模型名称，不支持自定义模型
    
    解决方案：禁用模型验证或将自定义模型标记为有效
    """
    global _PATCHES_APPLIED
    
    if _PATCHES_APPLIED['openai']:
        logger.debug("OpenAI LLM 补丁已应用，跳过")
        return
    
    try:
        from llama_index.llms.openai import OpenAI
        
        # 保存原始的 __init__
        _original_init = OpenAI.__init__
        
        def patched_init(self, *args, **kwargs):
            """禁用严格的模型验证"""
            # 添加 strict 参数以禁用验证（如果支持）
            if 'strict' not in kwargs:
                kwargs['strict'] = False
            
            try:
                return _original_init(self, *args, **kwargs)
            except Exception as e:
                # 如果是模型验证错误，尝试设置 default_headers
                error_msg = str(e).lower()
                if 'model' in error_msg and ('unknown' in error_msg or 'valid' in error_msg or 'provide' in error_msg):
                    logger.warning(f"检测到模型验证错误，尝试绕过: {e}")
                    # 移除 strict 参数，让它使用默认行为
                    kwargs.pop('strict', None)
                    return _original_init(self, *args, **kwargs)
                raise
        
        # 应用补丁
        OpenAI.__init__ = patched_init
        _PATCHES_APPLIED['openai'] = True
        logger.debug("已应用 OpenAI LLM 模型验证兼容性补丁")
        
    except Exception as e:
        logger.warning(f"应用 OpenAI LLM 补丁失败: {e}")


def apply_all_patches():
    """应用所有补丁"""
    patch_qdrant_vector_store()
    patch_openai_llm()
