#!/usr/bin/env python3
"""
OpenBB 集成引擎
为八仙论道提供更丰富的金融数据支撑
"""

from typing import Dict, List, Any, Optional
from dataclasses import dataclass


@dataclass
class ImmortalConfig:
    """八仙配置数据类"""
    primary: str
    specialty: str

@dataclass
class APIResult:
    """API调用结果数据类"""
    success: bool
    data: Optional[Any] = None
    provider_used: Optional[str] = None
    error: Optional[str] = None

class OpenBBEngine:
    """OpenBB 集成引擎"""
    
    def __init__(self):
        """
        初始化 OpenBB 引擎
        """
        # 延迟导入 OpenBB，避免未安装时报错
        self._obb = None
        
        # 八仙专属数据源分配
        self.immortal_sources: Dict[str, ImmortalConfig] = {
            '吕洞宾': ImmortalConfig(  # 乾-技术分析专家
                primary='yfinance',
                specialty='technical_analysis'
            ),
            '何仙姑': ImmortalConfig(  # 坤-风险控制专家
                primary='yfinance',
                specialty='risk_metrics'
            ),
            '张果老': ImmortalConfig(  # 兑-历史数据分析师
                primary='yfinance',
                specialty='historical_data'
            ),
            '韩湘子': ImmortalConfig(  # 艮-新兴资产专家
                primary='yfinance',
                specialty='sector_analysis'
            ),
            '汉钟离': ImmortalConfig(  # 离-热点追踪
                primary='yfinance',
                specialty='market_movers'
            ),
            '蓝采和': ImmortalConfig(  # 坎-潜力股发现
                primary='yfinance',
                specialty='screener'
            ),
            '曹国舅': ImmortalConfig(  # 震-机构分析
                primary='yfinance',
                specialty='institutional_holdings'
            ),
            '铁拐李': ImmortalConfig(  # 巽-逆向投资
                primary='yfinance',
                specialty='short_interest'
            )
        }
        
        print("✅ OpenBB 引擎初始化完成")
        
    def _ensure_openbb(self):
        """Lazy import OpenBB v4 obb router."""
        if self._obb is not None:
            return True
        try:
            from openbb import obb  # type: ignore
            self._obb = obb
            return True
        except Exception:
            self._obb = None
            return False
        
    def get_immortal_data(self, immortal_name: str, data_type: str, symbol: str = 'AAPL') -> APIResult:
        """
        为特定八仙获取专属数据
        
        Args:
            immortal_name: 八仙名称
            data_type: 数据类型
            symbol: 股票代码
            
        Returns:
            API调用结果
        """
        if immortal_name not in self.immortal_sources:
            return APIResult(success=False, error=f'Unknown immortal: {immortal_name}')
        
        immortal_config = self.immortal_sources[immortal_name]
        
        print(f"🧙‍♂️ {immortal_name} 请求 {data_type} 数据 (股票: {symbol})")
        
        # 根据数据类型调用不同的 OpenBB 函数
        try:
            if not self._ensure_openbb():
                return APIResult(success=False, error='OpenBB 未安装，请先安装 openbb>=4 并在 requirements.txt 启用')
            obb = self._obb
            if data_type == 'price':
                result = obb.equity.price.quote(symbol=symbol, provider=immortal_config.primary)
                return APIResult(
                    success=True,
                    data=getattr(result, 'results', getattr(result, 'to_dict', lambda: None)()),
                    provider_used=immortal_config.primary
                )
            elif data_type == 'historical':
                result = obb.equity.price.historical(symbol=symbol, provider=immortal_config.primary)
                return APIResult(
                    success=True,
                    data=getattr(result, 'results', getattr(result, 'to_dict', lambda: None)()),
                    provider_used=immortal_config.primary
                )
            elif data_type == 'profile':
                result = obb.equity.profile(symbol=symbol, provider=immortal_config.primary)
                return APIResult(
                    success=True,
                    data=getattr(result, 'results', getattr(result, 'to_dict', lambda: None)()),
                    provider_used=immortal_config.primary
                )
            elif data_type == 'news':
                result = obb.news.company(symbol=symbol)
                return APIResult(
                    success=True,
                    data=getattr(result, 'results', getattr(result, 'to_dict', lambda: None)()),
                    provider_used='news_api'
                )
            elif data_type == 'earnings':
                result = obb.equity.earnings.earnings_historical(symbol=symbol, provider=immortal_config.primary)
                return APIResult(
                    success=True,
                    data=getattr(result, 'results', getattr(result, 'to_dict', lambda: None)()),
                    provider_used=immortal_config.primary
                )
            elif data_type == 'dividends':
                result = obb.equity.fundamental.dividend(symbol=symbol, provider=immortal_config.primary)
                return APIResult(
                    success=True,
                    data=getattr(result, 'results', getattr(result, 'to_dict', lambda: None)()),
                    provider_used=immortal_config.primary
                )
            elif data_type == 'screener':
                # 使用简单的筛选器作为替代
                result = obb.equity.screener.etf(
                    provider=immortal_config.primary
                )
                return APIResult(
                    success=True,
                    data=getattr(result, 'results', getattr(result, 'to_dict', lambda: None)()),
                    provider_used=immortal_config.primary
                )
            else:
                return APIResult(success=False, error=f'Unsupported data type: {data_type}')
                
        except Exception as e:
            return APIResult(success=False, error=f'OpenBB 调用失败: {str(e)}')
    
    def simulate_jixia_debate(self, topic_symbol: str = 'TSLA') -> Dict[str, APIResult]:
        """
        模拟稷下学宫八仙论道
        
        Args:
            topic_symbol: 辩论主题股票代码
            
        Returns:
            八仙辩论结果
        """
        print(f"🏛️ 稷下学宫八仙论道 - 主题: {topic_symbol} (OpenBB 版本)")
        print("=" * 60)
        
        debate_results: Dict[str, APIResult] = {}
        
        # 数据类型映射
        data_type_mapping = {
            'technical_analysis': 'historical',  # 技术分析使用历史价格数据
            'risk_metrics': 'price',             # 风险控制使用当前价格数据
            'historical_data': 'historical',     # 历史数据分析使用历史价格数据
            'sector_analysis': 'profile',        # 新兴资产分析使用公司概况
            'market_movers': 'news',             # 热点追踪使用新闻
            'screener': 'screener',              # 潜力股发现使用筛选器
            'institutional_holdings': 'profile', # 机构分析使用公司概况
            'short_interest': 'profile'          # 逆向投资使用公司概况
        }
        
        # 八仙依次发言
        for immortal_name, config in self.immortal_sources.items():
            print(f"\n🎭 {immortal_name} ({config.specialty}) 发言:")
            
            data_type = data_type_mapping.get(config.specialty, 'price')
            result = self.get_immortal_data(immortal_name, data_type, topic_symbol)
            
            if result.success:
                debate_results[immortal_name] = result
                print(f"   💬 观点: 基于{result.provider_used}数据的{config.specialty}分析")
                # 显示部分数据示例
                if result.data:
                    if isinstance(result.data, list) and len(result.data) > 0:
                        sample = result.data[0]
                        print(f"   📊 数据示例: {sample}")
                    elif hasattr(result.data, '__dict__'):
                        # 如果是对象，显示前几个属性
                        attrs = vars(result.data)
                        sample = {k: v for k, v in list(attrs.items())[:3]}
                        print(f"   📊 数据示例: {sample}")
                    else:
                        print(f"   📊 数据示例: {result.data}")
            else:
                print(f"   😔 暂时无法获取数据: {result.error}")
        
        return debate_results

if __name__ == "__main__":
    # 测试 OpenBB 引擎
    print("🧪 OpenBB 引擎测试")
    engine = OpenBBEngine()
    engine.simulate_jixia_debate('AAPL')