 from typing import List, Optional
import asyncio
from src.jixia.engines.data_abstraction import DataProvider
from src.jixia.models.financial_data_models import StockQuote, HistoricalPrice, CompanyProfile, FinancialNews
from src.jixia.engines.rapidapi_adapter import RapidAPIDataProvider
from src.jixia.engines.openbb_adapter import OpenBBDataProvider

class DataAbstractionLayer:
    """金融数据抽象层管理器"""
    
    def __init__(self):
        self.providers: List[DataProvider] = []
        self._initialize_providers()
    
    def _initialize_providers(self):
        """初始化所有可用的数据提供商"""
        # 根据配置和环境动态加载适配器
        try:
            self.providers.append(OpenBBDataProvider())
        except Exception as e:
            print(f"警告: OpenBBDataProvider 初始化失败: {e}")
        
        try:
            self.providers.append(RapidAPIDataProvider())
        except Exception as e:
            print(f"警告: RapidAPIDataProvider 初始化失败: {e}")
        
        # 按优先级排序
        self.providers.sort(key=lambda p: p.priority)
        print(f"数据抽象层初始化完成，已加载 {len(self.providers)} 个数据提供商")
        for provider in self.providers:
            print(f"  - {provider.name} (优先级: {provider.priority})")
    
    def get_quote(self, symbol: str) -> Optional[StockQuote]:
        """获取股票报价（带故障转移）"""
        for provider in self.providers:
            try:
                quote = provider.get_quote(symbol)
                if quote:
                    print(f"✅ 通过 {provider.name} 获取到 {symbol} 的报价")
                    return quote
            except Exception as e:
                print(f"警告: {provider.name} 获取报价失败: {e}")
                continue
        print(f"❌ 所有数据提供商都无法获取 {symbol} 的报价")
        return None
    
    async def get_quote_async(self, symbol: str) -> Optional[StockQuote]:
        """异步获取股票报价（带故障转移）"""
        for provider in self.providers:
            try:
                # 如果提供商支持异步方法，则使用异步方法
                if hasattr(provider, 'get_quote_async'):
                    quote = await provider.get_quote_async(symbol)
                else:
                    # 否则在执行器中运行同步方法
                    quote = await asyncio.get_event_loop().run_in_executor(
                        None, provider.get_quote, symbol
                    )
                if quote:
                    print(f"✅ 通过 {provider.name} 异步获取到 {symbol} 的报价")
                    return quote
            except Exception as e:
                print(f"警告: {provider.name} 异步获取报价失败: {e}")
                continue
        print(f"❌ 所有数据提供商都无法异步获取 {symbol} 的报价")
        return None
    
    def get_historical_prices(self, symbol: str, days: int = 30) -> List[HistoricalPrice]:
        """获取历史价格数据（带故障转移）"""
        for provider in self.providers:
            try:
                prices = provider.get_historical_prices(symbol, days)
                if prices:
                    print(f"✅ 通过 {provider.name} 获取到 {symbol} 的历史价格数据")
                    return prices
            except Exception as e:
                print(f"警告: {provider.name} 获取历史价格失败: {e}")
                continue
        print(f"❌ 所有数据提供商都无法获取 {symbol} 的历史价格数据")
        return []
    
    def get_company_profile(self, symbol: str) -> Optional[CompanyProfile]:
        """获取公司概况（带故障转移）"""
        for provider in self.providers:
            try:
                profile = provider.get_company_profile(symbol)
                if profile:
                    print(f"✅ 通过 {provider.name} 获取到 {symbol} 的公司概况")
                    return profile
            except Exception as e:
                print(f"警告: {provider.name} 获取公司概况失败: {e}")
                continue
        print(f"❌ 所有数据提供商都无法获取 {symbol} 的公司概况")
        return None
    
    def get_news(self, symbol: str, limit: int = 10) -> List[FinancialNews]:
        """获取相关新闻（带故障转移）"""
        for provider in self.providers:
            try:
                news = provider.get_news(symbol, limit)
                if news:
                    print(f"✅ 通过 {provider.name} 获取到 {symbol} 的相关新闻")
                    return news
            except Exception as e:
                print(f"警告: {provider.name} 获取新闻失败: {e}")
                continue
        print(f"❌ 所有数据提供商都无法获取 {symbol} 的相关新闻")
        return []