#!/usr/bin/env python3
"""
TradingAgents免费版本主入口

该文件是TradingAgents MVP免费版本的主要入口点，使用免费数据源替代昂贵的付费API。
支持CLI和Web界面两种使用方式。

@author TradingAgents团队
@version MVP-1.0
@since 2024-12
"""

import os
import sys
import asyncio
import argparse
import logging
from datetime import datetime
from typing import Dict, Any, List, Optional
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))

from tradingagents.config.free_config import get_config, ConfigManager
from tradingagents.dataflows.free_alternatives import create_free_data_sources, DataSourceConfig
from tradingagents.agents.analysts.fundamentals_analyst_free import FreeFundamentalsAnalyst

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.StreamHandler(),
        logging.FileHandler('logs/tradingagents_free.log', encoding='utf-8')
    ]
)
logger = logging.getLogger(__name__)


class TradingAgentsFree:
    """
    TradingAgents免费版本主类
    
    @description 协调所有免费智能体和数据源的主要控制器
    @version MVP-1.0
    """
    
    def __init__(self, config_path: Optional[str] = None):
        """
        初始化TradingAgents免费版本
        
        @param {Optional[str]} config_path - 配置文件路径
        """
        # 确保日志目录存在
        os.makedirs('logs', exist_ok=True)
        
        # 加载配置
        if config_path:
            self.config_manager = ConfigManager(config_path)
        else:
            self.config_manager = ConfigManager()
        
        self.config = self.config_manager.get_config()
        
        # 初始化数据源
        self._init_data_sources()
        
        # 初始化智能体
        self._init_agents()
        
        logger.info("TradingAgents免费版本初始化完成")
        self._print_welcome_message()
    
    def _init_data_sources(self):
        """初始化免费数据源"""
        try:
            data_source_config = DataSourceConfig(
                alpha_vantage_api_key=self.config.data_sources.alpha_vantage_api_key,
                max_daily_calls=self.config.data_sources.alpha_vantage_max_calls_per_day,
                cache_ttl_hours=self.config.data_sources.cache_ttl_hours,
                user_agent=self.config.data_sources.sec_edgar_user_agent
            )
            
            self.data_sources = create_free_data_sources(data_source_config)
            logger.info("免费数据源初始化成功")
            
        except Exception as e:
            logger.error(f"数据源初始化失败: {e}")
            raise
    
    def _init_agents(self):
        """初始化智能体"""
        try:
            # 基本面分析师
            self.fundamentals_analyst = FreeFundamentalsAnalyst()
            
            # 后续可以添加更多智能体
            # self.technical_analyst = FreeTechnicalAnalyst()
            # self.news_analyst = FreeNewsAnalyst()
            # self.social_analyst = FreeSocialAnalyst()
            
            logger.info("智能体初始化成功")
            
        except Exception as e:
            logger.error(f"智能体初始化失败: {e}")
            raise
    
    def _print_welcome_message(self):
        """打印欢迎信息"""
        cost_estimate = self.config.get_cost_estimate()
        
        welcome_msg = f"""
╔══════════════════════════════════════════════════════════════╗
║                    TradingAgents MVP 免费版                    ║
║                     多智能体金融分析系统                        ║
╠══════════════════════════════════════════════════════════════╣
║ 版本: MVP-1.0                                                ║
║ 数据源: SEC Edgar + Alpha Vantage + Yahoo Finance (免费)      ║
║ 月成本: ${cost_estimate['monthly_cost_usd']:.0f} (节省 {cost_estimate['cost_savings_vs_finnhub']['savings_percentage']:.1f}%)                                    ║
║ 支持: CLI + Web界面                                          ║
╚══════════════════════════════════════════════════════════════╝

🚀 系统已就绪！使用 --help 查看可用命令
        """
        print(welcome_msg)
    
    async def analyze_stock(
        self, 
        ticker: str, 
        analysis_types: List[str] = None
    ) -> Dict[str, Any]:
        """
        分析单个股票
        
        @param {str} ticker - 股票代码
        @param {List[str]} analysis_types - 分析类型列表
        @returns {Dict[str, Any]} 分析结果
        """
        if analysis_types is None:
            analysis_types = ["fundamentals"]
        
        logger.info(f"开始分析股票: {ticker}")
        results = {
            "ticker": ticker.upper(),
            "analysis_date": datetime.now().isoformat(),
            "analysis_types": analysis_types,
            "results": {}
        }
        
        try:
            # 基本面分析
            if "fundamentals" in analysis_types:
                logger.info(f"执行基本面分析: {ticker}")
                fundamentals_result = await self.fundamentals_analyst.analyze_fundamentals(ticker)
                results["results"]["fundamentals"] = fundamentals_result
            
            # 技术分析 (待实现)
            if "technical" in analysis_types:
                logger.info(f"技术分析功能将在后续版本中实现")
                results["results"]["technical"] = {"status": "待实现"}
            
            # 新闻分析 (待实现)
            if "news" in analysis_types:
                logger.info(f"新闻分析功能将在后续版本中实现")
                results["results"]["news"] = {"status": "待实现"}
            
            # 社交分析 (待实现)
            if "social" in analysis_types:
                logger.info(f"社交分析功能将在后续版本中实现")
                results["results"]["social"] = {"status": "待实现"}
            
            logger.info(f"股票分析完成: {ticker}")
            return results
            
        except Exception as e:
            logger.error(f"股票分析失败: {e}")
            results["error"] = str(e)
            return results
    
    async def batch_analyze(
        self, 
        tickers: List[str], 
        analysis_types: List[str] = None,
        max_concurrent: int = 3
    ) -> Dict[str, Any]:
        """
        批量分析股票
        
        @param {List[str]} tickers - 股票代码列表
        @param {List[str]} analysis_types - 分析类型列表
        @param {int} max_concurrent - 最大并发数
        @returns {Dict[str, Any]} 批量分析结果
        """
        logger.info(f"开始批量分析: {len(tickers)}个股票")
        
        semaphore = asyncio.Semaphore(max_concurrent)
        
        async def analyze_single(ticker: str):
            async with semaphore:
                return await self.analyze_stock(ticker, analysis_types)
        
        # 并行执行分析
        tasks = [analyze_single(ticker) for ticker in tickers]
        results = await asyncio.gather(*tasks, return_exceptions=True)
        
        # 整理结果
        batch_results = {
            "batch_id": f"batch_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
            "total_stocks": len(tickers),
            "analysis_types": analysis_types or ["fundamentals"],
            "results": {},
            "errors": [],
            "summary": {}
        }
        
        successful_count = 0
        for i, result in enumerate(results):
            ticker = tickers[i]
            
            if isinstance(result, Exception):
                batch_results["errors"].append({
                    "ticker": ticker,
                    "error": str(result)
                })
            else:
                batch_results["results"][ticker] = result
                if "error" not in result:
                    successful_count += 1
        
        # 生成摘要
        batch_results["summary"] = {
            "successful": successful_count,
            "failed": len(tickers) - successful_count,
            "success_rate": successful_count / len(tickers) if tickers else 0
        }
        
        logger.info(f"批量分析完成: {successful_count}/{len(tickers)}个成功")
        return batch_results
    
    def print_analysis_result(self, result: Dict[str, Any]):
        """
        打印分析结果
        
        @param {Dict[str, Any]} result - 分析结果
        """
        ticker = result.get("ticker", "UNKNOWN")
        print(f"\n{'='*60}")
        print(f"📊 {ticker} 股票分析报告")
        print(f"{'='*60}")
        print(f"分析时间: {result.get('analysis_date', 'N/A')}")
        print(f"分析类型: {', '.join(result.get('analysis_types', []))}")
        
        if "error" in result:
            print(f"❌ 分析失败: {result['error']}")
            return
        
        results = result.get("results", {})
        
        # 基本面分析结果
        if "fundamentals" in results:
            fundamentals = results["fundamentals"]
            print(f"\n📈 基本面分析")
            print(f"   综合评分: {fundamentals.fundamental_score}/100")
            print(f"   投资建议: {fundamentals.recommendation}")
            print(f"   置信度: {fundamentals.confidence_level:.1%}")
            print(f"   数据质量: {fundamentals.data_quality_score}/100")
            
            print(f"\n   分项评分:")
            print(f"   • 估值: {fundamentals.valuation_score}/100")
            print(f"   • 盈利能力: {fundamentals.profitability_score}/100")
            print(f"   • 财务健康: {fundamentals.financial_health_score}/100")
            print(f"   • 增长潜力: {fundamentals.growth_score}/100")
            
            if fundamentals.key_strengths:
                print(f"\n   主要优势:")
                for strength in fundamentals.key_strengths:
                    print(f"   ✅ {strength}")
            
            if fundamentals.key_weaknesses:
                print(f"\n   主要劣势:")
                for weakness in fundamentals.key_weaknesses:
                    print(f"   ⚠️ {weakness}")
            
            if fundamentals.risk_factors:
                print(f"\n   风险因素:")
                for risk in fundamentals.risk_factors:
                    print(f"   🚨 {risk}")
        
        # 其他分析结果
        for analysis_type, analysis_result in results.items():
            if analysis_type != "fundamentals":
                print(f"\n📊 {analysis_type}分析: {analysis_result.get('status', '已完成')}")
    
    def print_batch_summary(self, batch_result: Dict[str, Any]):
        """
        打印批量分析摘要
        
        @param {Dict[str, Any]} batch_result - 批量分析结果
        """
        print(f"\n{'='*60}")
        print(f"📊 批量分析摘要")
        print(f"{'='*60}")
        print(f"批次ID: {batch_result.get('batch_id', 'N/A')}")
        print(f"总股票数: {batch_result.get('total_stocks', 0)}")
        print(f"成功分析: {batch_result.get('summary', {}).get('successful', 0)}")
        print(f"失败分析: {batch_result.get('summary', {}).get('failed', 0)}")
        print(f"成功率: {batch_result.get('summary', {}).get('success_rate', 0):.1%}")
        
        # 显示成功的分析结果摘要
        results = batch_result.get("results", {})
        if results:
            print(f"\n📈 分析结果摘要:")
            for ticker, result in results.items():
                if "results" in result and "fundamentals" in result["results"]:
                    fundamentals = result["results"]["fundamentals"]
                    print(f"   {ticker}: {fundamentals.fundamental_score}/100 ({fundamentals.recommendation})")
        
        # 显示错误
        errors = batch_result.get("errors", [])
        if errors:
            print(f"\n❌ 分析失败:")
            for error in errors:
                print(f"   {error['ticker']}: {error['error']}")
    
    async def run_web_interface(self, port: int = None):
        """
        启动Web界面
        
        @param {int} port - Web服务端口
        """
        if port is None:
            port = self.config.web_port
        
        try:
            # 这里将在后续实现Streamlit和Chainlit界面
            print(f"🌐 Web界面功能将在第二阶段实现")
            print(f"   计划支持:")
            print(f"   • Streamlit数据可视化界面 (端口 {port})")
            print(f"   • Chainlit对话式界面 (端口 {port + 1})")
            
        except Exception as e:
            logger.error(f"Web界面启动失败: {e}")
            raise
    
    def get_system_status(self) -> Dict[str, Any]:
        """
        获取系统状态
        
        @returns {Dict[str, Any]} 系统状态信息
        """
        try:
            # 检查数据源状态
            data_source_status = {}
            for name, source in self.data_sources.items():
                try:
                    # 简单的健康检查
                    data_source_status[name] = "正常"
                except Exception as e:
                    data_source_status[name] = f"异常: {e}"
            
            # 检查配置状态
            is_production_ready = self.config.is_production_ready()
            cost_estimate = self.config.get_cost_estimate()
            
            return {
                "system_version": "MVP-1.0",
                "status": "运行中",
                "data_sources": data_source_status,
                "production_ready": is_production_ready,
                "cost_estimate": cost_estimate,
                "config_valid": True,
                "agents_loaded": {
                    "fundamentals_analyst": "已加载",
                    "technical_analyst": "待实现",
                    "news_analyst": "待实现",
                    "social_analyst": "待实现"
                }
            }
            
        except Exception as e:
            logger.error(f"获取系统状态失败: {e}")
            return {
                "system_version": "MVP-1.0",
                "status": "异常",
                "error": str(e)
            }


async def main():
    """主函数"""
    parser = argparse.ArgumentParser(
        description="TradingAgents MVP免费版本 - 多智能体金融分析系统",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
使用示例:
  python main_free.py --analyze AAPL                    # 分析单个股票
  python main_free.py --batch AAPL,MSFT,GOOGL         # 批量分析
  python main_free.py --web                            # 启动Web界面
  python main_free.py --status                         # 查看系统状态
        """
    )
    
    # 分析参数
    parser.add_argument(
        "--analyze", "-a",
        type=str,
        help="分析单个股票 (例如: AAPL)"
    )
    
    parser.add_argument(
        "--batch", "-b",
        type=str,
        help="批量分析股票，用逗号分隔 (例如: AAPL,MSFT,GOOGL)"
    )
    
    parser.add_argument(
        "--types", "-t",
        type=str,
        default="fundamentals",
        help="分析类型，用逗号分隔 (默认: fundamentals)"
    )
    
    # 系统参数
    parser.add_argument(
        "--web", "-w",
        action="store_true",
        help="启动Web界面"
    )
    
    parser.add_argument(
        "--port", "-p",
        type=int,
        help="Web界面端口 (默认: 8501)"
    )
    
    parser.add_argument(
        "--status", "-s",
        action="store_true",
        help="显示系统状态"
    )
    
    parser.add_argument(
        "--config", "-c",
        type=str,
        help="配置文件路径"
    )
    
    parser.add_argument(
        "--debug", "-d",
        action="store_true",
        help="启用调试模式"
    )
    
    args = parser.parse_args()
    
    # 设置日志级别
    if args.debug:
        logging.getLogger().setLevel(logging.DEBUG)
    
    try:
        # 初始化系统
        trading_agents = TradingAgentsFree(args.config)
        
        # 显示系统状态
        if args.status:
            status = trading_agents.get_system_status()
            print(f"\n📊 系统状态:")
            print(f"   版本: {status.get('system_version')}")
            print(f"   状态: {status.get('status')}")
            print(f"   生产就绪: {'是' if status.get('production_ready') else '否'}")
            print(f"   月成本: ${status.get('cost_estimate', {}).get('monthly_cost_usd', 0):.0f}")
            
            print(f"\n📡 数据源状态:")
            for name, status_info in status.get('data_sources', {}).items():
                print(f"   {name}: {status_info}")
            
            print(f"\n🤖 智能体状态:")
            for name, agent_status in status.get('agents_loaded', {}).items():
                print(f"   {name}: {agent_status}")
            
            return
        
        # 启动Web界面
        if args.web:
            await trading_agents.run_web_interface(args.port)
            return
        
        # 分析单个股票
        if args.analyze:
            analysis_types = [t.strip() for t in args.types.split(",")]
            result = await trading_agents.analyze_stock(args.analyze, analysis_types)
            trading_agents.print_analysis_result(result)
            return
        
        # 批量分析
        if args.batch:
            tickers = [t.strip().upper() for t in args.batch.split(",")]
            analysis_types = [t.strip() for t in args.types.split(",")]
            
            print(f"🚀 开始批量分析 {len(tickers)} 个股票...")
            batch_result = await trading_agents.batch_analyze(tickers, analysis_types)
            
            trading_agents.print_batch_summary(batch_result)
            
            # 询问是否显示详细结果
            if input("\n是否显示详细分析结果? (y/N): ").lower() == 'y':
                for ticker, result in batch_result.get("results", {}).items():
                    trading_agents.print_analysis_result(result)
            
            return
        
        # 如果没有指定操作，显示帮助
        parser.print_help()
        
    except KeyboardInterrupt:
        print("\n\n👋 用户中断，系统退出")
    except Exception as e:
        logger.error(f"系统运行失败: {e}")
        print(f"❌ 系统运行失败: {e}")
        sys.exit(1)


if __name__ == "__main__":
    # 运行主程序
    asyncio.run(main())