"""
验证BM25修复是否成功
"""
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

from src.config import get_config_manager
from src.storage import BM25StoreManager
from src.tokenizers import create_tokenizer

def main():
    print("=== 验证 BM25 修复 ===\n")
    
    # 获取配置
    config = get_config_manager()
    
    print(f"1. 配置检查:")
    print(f"   检索模式: {config.retrieval.mode}")
    print(f"   BM25启用: {config.retrieval.use_bm25}")
    
    # 创建BM25存储管理器
    bm25_manager = BM25StoreManager(config=config)
    
    print(f"\n2. 检查BM25存储目录:")
    bm25_dir = config.paths.bm25_storage_dir
    print(f"   目录: {bm25_dir}")
    
    if bm25_dir.exists():
        files = list(bm25_dir.glob("*"))
        print(f"   文件数: {len(files)}")
        for f in files:
            print(f"   - {f.name}")
    
    print(f"\n3. 尝试加载BM25检索器...")
    
    try:
        # 创建分词器
        tokenizer = create_tokenizer(
            language=config.retrieval.bm25_language,
            use_stemmer=(config.retrieval.bm25_language == "english")
        )
        
        from src.retrievers import ChineseBM25Retriever
        
        # 尝试加载
        bm25_retriever = ChineseBM25Retriever.from_persist_dir(
            persist_dir=str(bm25_dir),
            tokenizer=tokenizer,
            verbose=True
        )
        
        if bm25_retriever:
            print(f"   ✅ ChineseBM25Retriever加载成功!")
            print(f"   节点数: {len(bm25_retriever._nodes)}")
            print(f"   BM25对象: {bm25_retriever.bm25}")
            
            # 检查BM25对象的属性
            if hasattr(bm25_retriever.bm25, 'num_docs'):
                print(f"   num_docs属性: {bm25_retriever.bm25.num_docs}")
            else:
                print(f"   ⚠️ num_docs属性不存在")
            
            # 尝试直接使用bm25s检索
            print(f"\n4. 直接测试bm25s检索...")
            try:
                import bm25s
                
                # 重新加载BM25索引
                bm25_obj = bm25s.BM25.load(str(bm25_dir), load_corpus=False)
                print(f"   ✅ bm25s.BM25.load成功")
                
                # 检查属性
                print(f"   BM25对象类型: {type(bm25_obj)}")
                
                # 尝试检索
                test_query = "人工智能"
                query_tokens = tokenizer(test_query)
                print(f"   查询: '{test_query}'")
                print(f"   查询分词: {query_tokens}")
                
                # 检查num_docs
                if hasattr(bm25_obj, 'num_docs'):
                    num_docs = bm25_obj.num_docs
                    print(f"   num_docs: {num_docs}")
                    
                    if num_docs is None or num_docs == 0:
                        print(f"   ⚠️ num_docs为{num_docs}，可能索引有问题")
                    else:
                        # 尝试检索
                        try:
                            results, scores = bm25_obj.retrieve([query_tokens], k=min(5, num_docs))
                            print(f"   ✅ 检索成功!")
                            print(f"   结果数: {len(results[0]) if results else 0}")
                            print(f"   分数: {scores[0] if scores else '无'}")
                        except Exception as e:
                            print(f"   ❌ 检索失败: {e}")
                else:
                    print(f"   ⚠️ num_docs属性不存在")
                    
            except Exception as e:
                print(f"   ❌ bm25s测试失败: {e}")
                import traceback
                traceback.print_exc()
            
            return True
        else:
            print(f"   ❌ ChineseBM25Retriever加载失败")
            return False
            
    except Exception as e:
        print(f"   ❌ 加载失败: {e}")
        import traceback
        traceback.print_exc()
        return False
    
    print(f"\n" + "="*50)
    print(f"验证完成")

if __name__ == "__main__":
    success = main()
    
    if success:
        print(f"\n✅ BM25修复基本成功!")
        print(f"   ChineseBM25Retriever可以加载")
        print(f"   但检索功能可能需要进一步调试")
    else:
        print(f"\n❌ BM25修复失败")
        print(f"   建议删除现有索引并重新构建")
        print(f"   删除命令: Remove-Item -Path '{config.paths.bm25_storage_dir}' -Recurse -Force")
        print(f"   重建命令: python cli.py build-index --data-dir ./my_knowledge_base")