"""
CLI 命令处理器模块
使用依赖注入容器提供统一的服务管理
"""
import sys
from pathlib import Path
from typing import TYPE_CHECKING

from src.di import get_container
from src.config import get_config_manager
from .display import print_banner, display_query_result, display_retrieve_result

if TYPE_CHECKING:
    from src.services import RAGService


def _get_service() -> "RAGService":
    """
    从依赖注入容器获取 RAGService 实例
    
    Returns:
        RAGService 实例
    """
    container = get_container()
    return container.get("rag_service")


def _get_config():
    """获取配置实例"""
    return get_config_manager()


def cmd_index(args):
    """
    索引构建命令处理器
    
    Args:
        args: 命令行参数
    """
    print_banner()
    print(f"📚 开始构建索引...\n")
    
    config = _get_config()
    
    # 确定数据目录
    data_dir = args.dir or str(config.paths.knowledge_dir)
    
    print(f"数据目录: {data_dir}")
    print(f"存储路径: {config.paths.vector_storage_dir}")
    print(f"强制重建: {'是' if args.force else '否'}\n")
    
    # 从容器获取服务并调用
    service = _get_service()
    result = service.build_index(data_dir, force_rebuild=args.force)
    
    if result.get("success"):
        print("\n" + "="*60)
        print("🎉 索引构建成功！")
        print("="*60)
        print(f"\n💡 提示：现在可以使用以下命令进行查询：")
        print(f'   python cli.py query --question "你的问题"')
    else:
        print("\n" + "="*60)
        print("❌ 索引构建失败")
        print("="*60)
        if result.get("error"):
            print(f"错误信息: {result['error']}")
        sys.exit(1)


def cmd_query(args):
    """
    查询命令处理器
    
    Args:
        args: 命令行参数
    """
    print_banner()
    
    # 从容器获取服务
    service = _get_service()
    
    # 如果是交互模式
    if args.interactive:
        print("🔄 进入交互查询模式 (输入 'quit' 或 'exit' 退出)\n")
        
        while True:
            try:
                # 获取用户输入
                question = input("\n💬 请输入问题: ").strip()
                
                # 检查退出命令
                if question.lower() in ['quit', 'exit', 'q']:
                    print("\n👋 再见！")
                    break
                
                # 跳过空输入
                if not question:
                    continue
                
                # 执行查询
                print(f"\n🔍 查询中... (模式: {args.mode or '默认'})\n")
                result = service.query(question=question, top_k=args.top_k, mode=args.mode)
                
                # 显示结果
                display_query_result(result, show_sources=args.sources)
                
            except KeyboardInterrupt:
                print("\n\n👋 再见！")
                break
            except Exception as e:
                print(f"\n❌ 发生错误: {e}")
    
    # 单次查询模式
    else:
        if not args.question:
            print("❌ 错误：请使用 --question 参数指定问题，或使用 --interactive 进入交互模式")
            sys.exit(1)
        
        print(f"💬 问题: {args.question}\n")
        print(f"🔍 查询中... (模式: {args.mode or '默认'})\n")
        
        # 执行查询
        result = service.query(question=args.question, top_k=args.top_k, mode=args.mode)
        
        # 显示结果
        display_query_result(result, show_sources=args.sources)


def cmd_retrieve(args):
    """
    检索命令处理器（仅检索，不使用LLM）
    
    Args:
        args: 命令行参数
    """
    print_banner()
    
    # 从容器获取服务
    service = _get_service()
    
    # 如果是交互模式
    if args.interactive:
        print("🔄 进入交互检索模式 (输入 'quit' 或 'exit' 退出)\n")
        
        while True:
            try:
                # 获取用户输入
                question = input("\n💬 请输入检索内容: ").strip()
                
                # 检查退出命令
                if question.lower() in ['quit', 'exit', 'q']:
                    print("\n👋 再见！")
                    break
                
                # 跳过空输入
                if not question:
                    continue
                
                # 执行检索
                print(f"\n🔍 检索中... (模式: {args.mode or '默认'})\n")
                result = service.retrieve(question=question, top_k=args.top_k, mode=args.mode)
                
                # 显示结果
                display_retrieve_result(result)
                
            except KeyboardInterrupt:
                print("\n\n👋 再见！")
                break
            except Exception as e:
                print(f"\n❌ 发生错误: {e}")
    
    # 单次检索模式
    else:
        if not args.question:
            print("❌ 错误：请使用 --question 参数指定检索内容，或使用 --interactive 进入交互模式")
            sys.exit(1)
        
        print(f"💬 检索内容: {args.question}\n")
        print(f"🔍 检索中... (模式: {args.mode or '默认'})\n")
        
        # 执行检索
        result = service.retrieve(question=args.question, top_k=args.top_k, mode=args.mode)
        
        # 显示结果
        display_retrieve_result(result)


def cmd_status(args):
    """
    状态查看命令处理器
    
    Args:
        args: 命令行参数
    """
    print_banner()
    print("📊 系统状态信息\n")
    
    # 从容器获取服务
    service = _get_service()
    
    # 获取索引状态
    status_result = service.get_status(verbose=args.verbose)
    
    if not status_result.get("success"):
        print(f"❌ 获取状态失败: {status_result.get('error', '未知错误')}")
        sys.exit(1)
    
    stats = status_result.get("stats", {})
    
    print("="*60)
    print("索引状态:")
    print("="*60)
    
    # 显示检索模式
    if stats.get("retrieval_mode"):
        print(f"🔍 检索模式: {stats['retrieval_mode']}")
        print()
    
    # 向量索引状态
    print("📊 向量索引:")
    if stats.get("vector_index_exists"):
        print(f"  ✅ 已存在")
        if stats.get("storage_type") == "qdrant":
            print(f"  📁 存储类型: Qdrant")
            print(f"  📦 集合名称: {stats.get('collection_name')}")
            print(f"  📈 向量数量: {stats.get('vectors_count')}")
        else:
            print(f"  📁 存储类型: 本地")
            print(f"  📂 存储路径: {stats.get('storage_dir')}")
            print(f"  📄 文件数量: {stats.get('file_count')}")
        
        if stats.get("vector_index_loaded"):
            print(f"  💾 加载状态: 已加载")
        else:
            print(f"  💾 加载状态: 未加载")
        
        if args.verbose and stats.get("files"):
            print(f"\n  索引文件:")
            for file in stats["files"]:
                print(f"    - {file}")
    else:
        print(f"  ❌ 不存在")
        if stats.get("message"):
            print(f"     {stats['message']}")
    
    # BM25索引状态
    print()
    print("📊 BM25索引:")
    if stats.get("bm25_enabled"):
        if stats.get("bm25_index_exists"):
            print(f"  ✅ 已存在")
            print(f"  📂 存储路径: {stats.get('bm25_storage_dir')}")
            print(f"  🌐 分词语言: {stats.get('bm25_language')}")
            if stats.get("bm25_index_loaded"):
                print(f"  💾 加载状态: 已加载")
            else:
                print(f"  💾 加载状态: 未加载")
        else:
            print(f"  ❌ 不存在")
    else:
        print(f"  ⚠️  未启用")
    
    print("="*60)
    
    # 显示配置信息
    if args.config:
        print("\n⚙️  系统配置:")
        print("="*60)
        config_result = service.get_config()
        if config_result.get("success"):
            config_info = config_result.get("config", {})
            for key, value in config_info.items():
                print(f"{key}: {value}")
        else:
            print(f"❌ 获取配置失败: {config_result.get('error', '未知错误')}")
        print("="*60)


def cmd_delete(args):
    """
    删除索引命令处理器
    
    Args:
        args: 命令行参数
    """
    print_banner()
    print("🗑️  删除索引\n")
    
    # 确认操作
    if not args.yes:
        confirm = input("⚠️  确定要删除索引吗？此操作不可恢复！(yes/no): ").strip().lower()
        if confirm not in ['yes', 'y']:
            print("❌ 操作已取消")
            return
    
    # 从容器获取服务
    service = _get_service()
    
    # 删除索引
    result = service.delete_index(confirm=True)
    
    if result.get("success"):
        print("\n✅ 索引已成功删除")
    else:
        print(f"\n❌ 删除索引失败: {result.get('error', '未知错误')}")
        sys.exit(1)


def cmd_config(args):
    """
    配置管理命令处理器
    
    Args:
        args: 命令行参数
    """
    print_banner()
    print("⚙️  系统配置\n")
    
    print("="*60)
    print("当前配置:")
    print("="*60)
    
    # 从容器获取服务
    service = _get_service()
    
    config_result = service.get_config()
    if config_result.get("success"):
        config_info = config_result.get("config", {})
        for key, value in config_info.items():
            print(f"{key}: {value}")
    else:
        print(f"❌ 获取配置失败: {config_result.get('error', '未知错误')}")
        sys.exit(1)
    
    print("="*60)
    print("\n💡 提示：可以通过修改 .env 文件来更改配置")
    print("   配置文件路径: .env")
