"""
免费数据源替代模块
=================

本模块提供FinnHub付费API的免费替代方案，包括：
- SEC Edgar API（基本面数据）
- Alpha Vantage API（财务指标）
- Yahoo Finance（股价和基础数据）
- 免费新闻聚合

成本节省：$197/月 → $10-30/月
"""

import requests
import yfinance as yf
import pandas as pd
from typing import Dict, List, Optional, Any
import time
import logging
from datetime import datetime, timedelta
import json
from bs4 import BeautifulSoup
import feedparser
from urllib3.exceptions import SSLError
from requests.exceptions import RequestException
import functools

logger = logging.getLogger(__name__)

# 导入AkShare适配器作为备用方案
try:
    from .akshare_adapter import AkShareMasterAdapter, AkShareConfig
    AKSHARE_AVAILABLE = True
    logger.info("AkShare适配器已加载，可作为Yahoo Finance备用方案")
except ImportError:
    AKSHARE_AVAILABLE = False
    logger.warning("AkShare适配器未找到，将仅使用Yahoo Finance")

# 导入速率限制器
from .yahoo_rate_limiter import YahooFinanceRateLimiter, AlphaVantageRateLimiter

def robust_request(retries=3, backoff_factor=0.5):
    """
    一个装饰器，用于实现带有指数退避的健壮网络请求。
    专门捕获网络层和HTTP错误，并进行重试。
    """
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for i in range(retries):
                try:
                    return func(*args, **kwargs)
                except (RequestException, SSLError, yf.shared.YFNotImplementedError) as e:
                    logger.warning(f"请求失败 (尝试 {i+1}/{retries}): {e}")
                    if i == retries - 1:
                        logger.error(f"'{func.__name__}' 函数在 {retries} 次尝试后最终失败。")
                        raise  # 重新抛出异常，让上层处理
                    time.sleep(backoff_factor * (2 ** i))
            return None # 如果循环结束仍未成功
        return wrapper
    return decorator

class SECEdgarAPI:
    """SEC Edgar API集成 - 完全免费的基本面数据"""
    
    def __init__(self):
        self.base_url = "https://data.sec.gov/api/xbrl/companyfacts"
        self.headers = {
            "User-Agent": "TradingAgents/1.0 (contact@tradingagents.com)",
            "Accept-Encoding": "gzip, deflate",
            "Host": "data.sec.gov"
        }
    
    def get_company_facts(self, symbol: str) -> Dict[str, Any]:
        """
        获取公司基本面数据
        
        Args:
            symbol: 股票代码
            
        Returns:
            Dict: 包含财务数据的字典
        """
        try:
            # 获取CIK
            cik = self._get_cik(symbol)
            if not cik:
                return {}
            
            # 获取公司事实数据
            url = f"{self.base_url}/CIK{cik:010d}.json"
            response = requests.get(url, headers=self.headers)
            
            if response.status_code == 200:
                data = response.json()
                return self._parse_financial_data(data)
            else:
                logger.error(f"SEC API请求失败: {response.status_code}")
                return {}
                
        except Exception as e:
            logger.error(f"获取SEC数据时出错: {e}")
            return {}
    
    def _get_cik(self, symbol: str) -> Optional[int]:
        """通过股票代码获取CIK编号"""
        try:
            # 使用SEC公司tickers.json获取CIK
            url = "https://www.sec.gov/files/company_tickers.json"
            response = requests.get(url, headers=self.headers)
            
            if response.status_code == 200:
                data = response.json()
                for key, company in data.items():
                    if company.get('ticker', '').upper() == symbol.upper():
                        return company.get('cik_str')
            return None
            
        except Exception as e:
            logger.error(f"获取CIK时出错: {e}")
            return None
    
    def _parse_financial_data(self, data: Dict) -> Dict[str, Any]:
        """解析SEC财务数据"""
        try:
            facts = data.get('facts', {})
            us_gaap = facts.get('us-gaap', {})
            
            # 提取关键财务指标
            financial_data = {
                'revenue': self._extract_metric(us_gaap.get('Revenues', {})),
                'net_income': self._extract_metric(us_gaap.get('NetIncomeLoss', {})),
                'total_assets': self._extract_metric(us_gaap.get('Assets', {})),
                'total_debt': self._extract_metric(us_gaap.get('DebtCurrent', {})),
                'shareholders_equity': self._extract_metric(us_gaap.get('StockholdersEquity', {})),
                'cash_and_equivalents': self._extract_metric(us_gaap.get('CashAndCashEquivalentsAtCarryingValue', {}))
            }
            
            return financial_data
            
        except Exception as e:
            logger.error(f"解析SEC数据时出错: {e}")
            return {}
    
    def _extract_metric(self, metric_data: Dict) -> Optional[float]:
        """从SEC指标数据中提取最新值"""
        try:
            units = metric_data.get('units', {})
            usd_data = units.get('USD', [])
            
            if usd_data:
                # 获取最新的年报数据
                latest_data = sorted(usd_data, key=lambda x: x.get('end', ''), reverse=True)[0]
                return latest_data.get('val')
            
            return None
            
        except Exception as e:
            logger.error(f"提取指标数据时出错: {e}")
            return None


class AlphaVantageAPI:
    """Alpha Vantage API集成 - 免费层每日500次调用"""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://www.alphavantage.co/query"
        self.call_count = 0
        self.daily_limit = 500
    
    def get_overview(self, symbol: str) -> Dict[str, Any]:
        """获取公司概览数据"""
        if self.call_count >= self.daily_limit:
            logger.warning("Alpha Vantage API已达到日限制")
            return {}
        
        try:
            params = {
                'function': 'OVERVIEW',
                'symbol': symbol,
                'apikey': self.api_key
            }
            
            response = requests.get(self.base_url, params=params)
            self.call_count += 1
            
            if response.status_code == 200:
                data = response.json()
                
                # 检查是否有错误
                if 'Error Message' in data or 'Note' in data:
                    logger.warning(f"Alpha Vantage API错误: {data}")
                    return {}
                
                return self._parse_overview_data(data)
            
            return {}
            
        except Exception as e:
            logger.error(f"获取Alpha Vantage数据时出错: {e}")
            return {}
    
    def _parse_overview_data(self, data: Dict) -> Dict[str, Any]:
        """解析Alpha Vantage概览数据"""
        try:
            return {
                'market_cap': self._safe_float(data.get('MarketCapitalization')),
                'pe_ratio': self._safe_float(data.get('PERatio')),
                'peg_ratio': self._safe_float(data.get('PEGRatio')),
                'book_value': self._safe_float(data.get('BookValue')),
                'dividend_yield': self._safe_float(data.get('DividendYield')),
                'eps': self._safe_float(data.get('EPS')),
                'revenue_ttm': self._safe_float(data.get('RevenueTTM')),
                'profit_margin': self._safe_float(data.get('ProfitMargin')),
                'operating_margin': self._safe_float(data.get('OperatingMarginTTM')),
                'return_on_assets': self._safe_float(data.get('ReturnOnAssetsTTM')),
                'return_on_equity': self._safe_float(data.get('ReturnOnEquityTTM')),
                'beta': self._safe_float(data.get('Beta')),
                '52_week_high': self._safe_float(data.get('52WeekHigh')),
                '52_week_low': self._safe_float(data.get('52WeekLow'))
            }
            
        except Exception as e:
            logger.error(f"解析Alpha Vantage数据时出错: {e}")
            return {}
    
    def _safe_float(self, value: Any) -> Optional[float]:
        """安全转换为浮点数"""
        try:
            if value is None or value == 'None' or value == '':
                return None
            return float(value)
        except (ValueError, TypeError):
            return None


class EnhancedYahooFinance:
    """增强的Yahoo Finance数据获取 - 支持限制器和多重备用方案"""
    
    def __init__(self):
        self.cache = {}
        self.cache_duration = 300  # 5分钟缓存
        
        # 直接初始化Yahoo Finance限制器
        try:
            from .yahoo_rate_limiter import YahooFinanceRateLimiter
            self.yahoo_limiter = YahooFinanceRateLimiter()
            logger.info("Yahoo Finance速率限制器已初始化。")
        except Exception as e:
            self.yahoo_limiter = None
            logger.warning("未能初始化Yahoo Finance限制器，将不进行速率限制。")
        
        # 初始化AkShare适配器
        if AKSHARE_AVAILABLE:
            self.akshare_adapter = AkShareMasterAdapter(AkShareConfig())
        else:
            self.akshare_adapter = None
    
    def get_enhanced_data(self, symbol: str) -> Dict[str, Any]:
        """获取增强的股票数据 - 支持AkShare备用方案"""
        # 检查缓存
        cache_key = f"{symbol}_enhanced"
        if self._is_cached(cache_key):
            return self.cache[cache_key]['data']
        
        # 尝试Yahoo Finance（带有限制器和简单的重试逻辑）
        last_error = None
        for i in range(3): # 最多重试3次
            try:
                # 使用限制器控制请求频率
                if self.yahoo_limiter:
                    self.yahoo_limiter.wait_if_needed()
                
                ticker = yf.Ticker(symbol)
                info = ticker.info
                
                if not info or info.get('regularMarketPrice') is None:
                    raise ValueError(f"Yahoo Finance未找到股票 {symbol} 或返回数据不完整")
                
                # 如果成功，则处理并返回
                if self.yahoo_limiter: self.yahoo_limiter.record_success()

                hist = ticker.history(period="1y")
                financials = ticker.financials
                balance_sheet = ticker.balance_sheet
                cash_flow = ticker.cashflow
                
                enhanced_data = {
                    'basic_info': self._extract_basic_info(info),
                    'price_data': self._extract_price_data(hist),
                    'financial_ratios': self._calculate_ratios(info, financials, balance_sheet),
                    'technical_indicators': self._calculate_technical_indicators(hist),
                    'analyst_data': self._extract_analyst_data(info),
                    'data_source': 'yahoo_finance'
                }
                
                logger.info(f"Yahoo Finance数据获取成功: {symbol} (尝试 {i+1})")
                
                # 缓存数据并返回
                self.cache[cache_key] = {'data': enhanced_data, 'timestamp': datetime.now()}
                return enhanced_data

            except (RequestException, SSLError, ValueError) as e:
                last_error = e
                logger.warning(f"Yahoo Finance获取失败 (尝试 {i+1}/3): {e}")
                if self.yahoo_limiter: self.yahoo_limiter.record_failure()
                time.sleep(i + 1) # 简单的线性退避
        
        # 如果Yahoo Finance最终失败
        logger.error(f"Yahoo Finance在3次尝试后最终失败: {last_error}")
        
        # 如果主要数据源失败，启动备用方案
        logger.warning(f"Yahoo Finance失败: {last_error}")
        return self._get_akshare_fallback_data(symbol)
    
    def _get_akshare_fallback_data(self, symbol: str) -> Dict[str, Any]:
        """使用AkShare作为备用数据源 (重构版)"""
        if not self.akshare_adapter:
            return {}
        
        logger.info(f"尝试AkShare备用方案获取 {symbol} 数据...")
        try:
            # 直接调用增强后的 get_stock_data 方法
            ak_data = self.akshare_adapter.get_stock_data(symbol)
            
            if not ak_data:
                logger.warning(f"AkShare未能获取到 {symbol} 的数据")
                return {}

            logger.info(f"AkShare备用方案成功获取 {symbol} 数据")

            # 将AkShare数据格式转换为yfinance兼容格式
            return self._format_akshare_to_yfinance(ak_data)

        except Exception as e:
            logger.error(f"AkShare备用方案也失败: {e}")
            return {}

    def _format_akshare_to_yfinance(self, ak_data: Dict[str, Any]) -> Dict[str, Any]:
        """将AkShare返回的数据转换为yfinance的格式"""
        realtime = ak_data.get("realtime", {})
        history_df = pd.DataFrame(ak_data.get("history", []))

        # 基础信息映射
        info = {
            'symbol': ak_data.get('symbol'),
            'shortName': realtime.get('name'),
            'longName': realtime.get('name'),
            'currency': realtime.get('currency', 'USD'),
            'market': ak_data.get('market'),
            'exchangeName': realtime.get('exchange'),
            'marketCap': realtime.get('market_cap'),
            'previousClose': realtime.get('previous_close'),
            'open': realtime.get('open'),
            'dayHigh': realtime.get('high'),
            'dayLow': realtime.get('low'),
            'volume': realtime.get('volume'),
            'fiftyTwoWeekHigh': realtime.get('52_week_high'),
            'fiftyTwoWeekLow': realtime.get('52_week_low'),
            'regularMarketPrice': realtime.get('current_price'),
        }

        # K线数据
        if not history_df.empty:
            history_df = history_df.rename(columns={
                '日期': 'Date', '开盘': 'Open', '收盘': 'Close', 
                '最高': 'High', '最低': 'Low', '成交量': 'Volume'
            })
            if 'Date' in history_df.columns:
                history_df['Date'] = pd.to_datetime(history_df['Date'])
                history_df = history_df.set_index('Date')
        
        return {
            "info": info,
            "history": history_df,
            "news": [],  # AkShare适配器目前不提供新闻
            "source": "AkShare"
        }
    
    def _is_cached(self, key: str) -> bool:
        """检查数据是否在缓存中且未过期"""
        if key not in self.cache:
            return False
        
        cache_time = self.cache[key]['timestamp']
        return (datetime.now() - cache_time).seconds < self.cache_duration
    
    def _extract_basic_info(self, info: Dict) -> Dict[str, Any]:
        """提取基本股票信息"""
        return {
            'company_name': info.get('longName'),
            'sector': info.get('sector'),
            'industry': info.get('industry'),
            'market_cap': info.get('marketCap'),
            'enterprise_value': info.get('enterpriseValue'),
            'trailing_pe': info.get('trailingPE'),
            'forward_pe': info.get('forwardPE'),
            'price_to_book': info.get('priceToBook'),
            'debt_to_equity': info.get('debtToEquity'),
            'current_ratio': info.get('currentRatio'),
            'quick_ratio': info.get('quickRatio')
        }
    
    def _extract_price_data(self, hist: pd.DataFrame) -> Dict[str, Any]:
        """提取价格数据"""
        if hist.empty:
            return {}
        
        current_price = hist['Close'][-1]
        price_52w_high = hist['High'].max()
        price_52w_low = hist['Low'].min()
        
        return {
            'current_price': current_price,
            '52_week_high': price_52w_high,
            '52_week_low': price_52w_low,
            'price_change_52w': ((current_price - hist['Close'][0]) / hist['Close'][0]) * 100,
            'volatility': hist['Close'].pct_change().std() * (252 ** 0.5),  # 年化波动率
            'average_volume': hist['Volume'].mean()
        }
    
    def _calculate_ratios(self, info: Dict, financials: pd.DataFrame, balance_sheet: pd.DataFrame) -> Dict[str, Any]:
        """计算财务比率"""
        try:
            ratios = {
                'profit_margin': info.get('profitMargins'),
                'operating_margin': info.get('operatingMargins'),
                'return_on_assets': info.get('returnOnAssets'),
                'return_on_equity': info.get('returnOnEquity'),
                'gross_margin': info.get('grossMargins')
            }
            
            # 从财务报表计算额外比率
            if not financials.empty and not balance_sheet.empty:
                try:
                    net_income = financials.loc['Net Income'].iloc[0]
                    total_assets = balance_sheet.loc['Total Assets'].iloc[0]
                    shareholders_equity = balance_sheet.loc['Stockholders Equity'].iloc[0]
                    
                    ratios.update({
                        'calculated_roa': net_income / total_assets if total_assets else None,
                        'calculated_roe': net_income / shareholders_equity if shareholders_equity else None
                    })
                except:
                    pass
            
            return ratios
            
        except Exception as e:
            logger.error(f"计算财务比率时出错: {e}")
            return {}
    
    def _calculate_technical_indicators(self, hist: pd.DataFrame) -> Dict[str, Any]:
        """计算技术指标"""
        if hist.empty:
            return {}
        
        try:
            close_prices = hist['Close']
            
            # 简单移动平均线
            sma_20 = close_prices.rolling(window=20).mean().iloc[-1]
            sma_50 = close_prices.rolling(window=50).mean().iloc[-1]
            sma_200 = close_prices.rolling(window=200).mean().iloc[-1]
            
            # RSI计算
            delta = close_prices.diff()
            gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
            loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
            rs = gain / loss
            rsi = 100 - (100 / (1 + rs)).iloc[-1]
            
            return {
                'sma_20': sma_20,
                'sma_50': sma_50,
                'sma_200': sma_200,
                'rsi': rsi,
                'current_vs_sma_20': ((close_prices.iloc[-1] - sma_20) / sma_20) * 100 if sma_20 else None,
                'current_vs_sma_50': ((close_prices.iloc[-1] - sma_50) / sma_50) * 100 if sma_50 else None
            }
            
        except Exception as e:
            logger.error(f"计算技术指标时出错: {e}")
            return {}
    
    def _extract_analyst_data(self, info: Dict) -> Dict[str, Any]:
        """提取分析师数据"""
        return {
            'target_high_price': info.get('targetHighPrice'),
            'target_low_price': info.get('targetLowPrice'),
            'target_mean_price': info.get('targetMeanPrice'),
            'target_median_price': info.get('targetMedianPrice'),
            'recommendation_mean': info.get('recommendationMean'),
            'number_of_analyst_opinions': info.get('numberOfAnalystOpinions')
        }


class FreeNewsAggregator:
    """免费新闻聚合器 - 支持增强新闻聚合器"""
    
    def __init__(self):
        self.sources = {
            'yahoo_finance': 'https://feeds.finance.yahoo.com/rss/2.0/headline',
            'marketwatch': 'https://feeds.marketwatch.com/marketwatch/topstories/',
            'reuters_business': 'https://feeds.reuters.com/reuters/businessNews',
            'sec_rss': 'https://www.sec.gov/cgi-bin/browse-edgar?action=getcurrent&type=8-K&output=atom'
        }
        
        # 保持此部分不变
        if False: # ENHANCED_MODULES_AVAILABLE
            try:
                from .enhanced_news_aggregator import EnhancedNewsAggregator
                self.enhanced_aggregator = EnhancedNewsAggregator()
                logger.info("增强新闻聚合器已初始化。")
            except Exception as e:
                logger.warning(f"增强新闻聚合器初始化失败: {e}")
                self.enhanced_aggregator = None
        else:
            self.enhanced_aggregator = None
    
    def get_stock_news(self, symbol: str, limit: int = 10) -> List[Dict[str, Any]]:
        """获取特定股票的新闻 - 优先使用增强聚合器"""
        try:
            # 优先使用增强新闻聚合器
            if self.enhanced_aggregator:
                try:
                    enhanced_news = self.enhanced_aggregator.get_stock_news(symbol, limit)
                    if enhanced_news:
                        # 转换格式以保持兼容性
                        return [
                            {
                                'title': news.title,
                                'summary': news.summary,
                                'url': news.url,
                                'published': news.published,
                                'source': news.source,
                                'sentiment': news.sentiment
                            }
                            for news in enhanced_news
                        ]
                except Exception as e:
                    logger.warning(f"增强新闻聚合器失败，使用传统方法: {e}")
            
            # 传统方法作为备用
            all_news = []
            
            # Yahoo Finance股票特定新闻
            yahoo_news = []
            last_error = None
            for i in range(2): # 新闻只重试2次
                try:
                    yahoo_news = self._get_yahoo_stock_news(symbol, limit)
                    break
                except (RequestException, SSLError, ValueError) as e:
                    last_error = e
                    logger.warning(f"获取Yahoo新闻失败 (尝试 {i+1}/2): {e}")
                    time.sleep(1)
            if not yahoo_news:
                 logger.error(f"获取Yahoo新闻最终失败: {last_error}")

            all_news.extend(yahoo_news)
            
            # SEC公告
            sec_news = self._get_sec_news(symbol, limit)
            all_news.extend(sec_news)
            
            # 按时间排序
            all_news.sort(key=lambda x: x.get('published', ''), reverse=True)
            
            return all_news[:limit]
            
        except Exception as e:
            logger.error(f"获取股票新闻时出错: {e}")
            return []
    
    def _get_yahoo_stock_news(self, symbol: str, limit: int) -> List[Dict[str, Any]]:
        """获取Yahoo Finance股票新闻"""
        ticker = yf.Ticker(symbol)
        news_data = ticker.news
        
        if not news_data:
            # yfinance在找不到新闻时返回空列表，这不应算作一个需要重试的错误
            return []

        news_list = []
        for item in news_data[:limit]:
            news_list.append({
                'title': item.get('title', ''),
                'summary': item.get('summary', ''),
                'url': item.get('link', ''),
                'published': item.get('providerPublishTime', ''),
                'source': 'Yahoo Finance',
                'sentiment': 'neutral'  # 可以后续添加情感分析
            })
        
        return news_list
            
    def _get_sec_news(self, symbol: str, limit: int) -> List[Dict[str, Any]]:
        """获取SEC相关公告"""
        try:
            # 这里可以实现SEC Edgar RSS解析
            # 由于篇幅限制，先返回空列表
            return []
            
        except Exception as e:
            logger.error(f"获取SEC新闻时出错: {e}")
            return []


class FreeDataManager:
    """免费数据源管理器 - 统一接口，支持美股专用适配器"""
    
    def __init__(self, alpha_vantage_key: Optional[str] = None):
        self.sec_edgar = SECEdgarAPI()
        self.alpha_vantage = AlphaVantageAPI(alpha_vantage_key) if alpha_vantage_key else None
        self.yahoo_finance = EnhancedYahooFinance()
        self.news_aggregator = FreeNewsAggregator()
        
        # 保持此部分不变
        if False: # ENHANCED_MODULES_AVAILABLE
            try:
                from .us_stock_adapter import USStockDataAdapter
                self.us_stock_adapter = USStockDataAdapter(alpha_vantage_key)
                logger.info("美股专用数据适配器已初始化。")
            except Exception as e:
                logger.warning(f"美股专用适配器初始化失败: {e}")
                self.us_stock_adapter = None
        else:
            self.us_stock_adapter = None
    
    def get_comprehensive_data(self, symbol: str) -> Dict[str, Any]:
        """获取综合股票数据 - 优先使用美股专用适配器"""
        try:
            logger.info(f"开始获取{symbol}的综合免费数据...")
            
            # 检测是否为美股并优先使用美股专用适配器
            if self.us_stock_adapter and self._is_us_stock(symbol):
                try:
                    logger.info(f"使用美股专用适配器获取 {symbol} 数据")
                    us_stock_data = self.us_stock_adapter.get_us_stock_data(symbol)
                    
                    if us_stock_data and us_stock_data.metadata.get('data_quality') != 'error':
                        # 转换为兼容格式
                        return {
                            'symbol': symbol,
                            'timestamp': us_stock_data.timestamp,
                            'data_sources': [us_stock_data.data_source],
                            'basic_info': us_stock_data.basic_info,
                            'price_data': us_stock_data.price_data,
                            'financial_ratios': us_stock_data.financial_ratios,
                            'technical_indicators': us_stock_data.technical_indicators,
                            'analyst_data': us_stock_data.analyst_data,
                            'news': [
                                {
                                    'title': news.get('title', ''),
                                    'summary': news.get('summary', ''),
                                    'url': news.get('url', ''),
                                    'published': news.get('published', ''),
                                    'source': news.get('source', ''),
                                    'sentiment': news.get('sentiment', 'neutral')
                                }
                                for news in us_stock_data.news
                            ],
                            'metadata': us_stock_data.metadata,
                            'mode': 'us_stock_adapter'
                        }
                except Exception as e:
                    logger.warning(f"美股专用适配器失败，使用传统方法: {e}")
            
            # 传统方法作为备用
            data = {
                'symbol': symbol,
                'timestamp': datetime.now().isoformat(),
                'data_sources': [],
                'mode': 'traditional'
            }
            
            # Yahoo Finance增强数据
            yahoo_data = self.yahoo_finance.get_enhanced_data(symbol)
            if yahoo_data:
                data['yahoo_finance'] = yahoo_data
                data['data_sources'].append(yahoo_data.get('data_source', 'Yahoo Finance'))
            
            # SEC Edgar基本面数据
            sec_data = self.sec_edgar.get_company_facts(symbol)
            if sec_data:
                data['sec_edgar'] = sec_data
                data['data_sources'].append('SEC Edgar')
            
            # Alpha Vantage数据（如果可用）
            if self.alpha_vantage:
                av_data = self.alpha_vantage.get_overview(symbol)
                if av_data:
                    data['alpha_vantage'] = av_data
                    # 仅在yahoo失败时，才将Alpha Vantage作为主要数据源
                    if not data['data_sources']:
                        data['data_sources'].append('Alpha Vantage')
                    else:
                        # 作为补充数据源
                        data['data_sources'].append('Alpha Vantage (supplemental)')
            
            # 新闻数据
            news_data = self.news_aggregator.get_stock_news(symbol)
            if news_data:
                data['news'] = news_data
                data['data_sources'].append('News Aggregator')
            
            logger.info(f"成功获取{symbol}数据，数据源: {', '.join(data['data_sources'])}")
            
            return data
            
        except Exception as e:
            logger.error(f"获取{symbol}综合数据时出错: {e}")
            return {'error': str(e)}
    
    def _is_us_stock(self, symbol: str) -> bool:
        """简单判断是否为美股"""
        # 美股代码通常为1-5个字母，不包含数字
        return symbol.isalpha() and len(symbol) <= 5
    
    def get_fallback_data(self, symbol: str) -> Dict[str, Any]:
        """降级数据获取 - 仅使用最可靠的免费源"""
        try:
            logger.info(f"使用降级模式获取{symbol}数据...")
            
            # 仅使用Yahoo Finance（最可靠的免费源）
            yahoo_data = self.yahoo_finance.get_enhanced_data(symbol)
            
            if yahoo_data:
                return {
                    'symbol': symbol,
                    'timestamp': datetime.now().isoformat(),
                    'yahoo_finance': yahoo_data,
                    'data_sources': ['Yahoo Finance (Fallback Mode)'],
                    'mode': 'fallback'
                }
            else:
                return {'error': 'All data sources failed'}
                
        except Exception as e:
            logger.error(f"降级模式获取{symbol}数据时出错: {e}")
            return {'error': str(e)}


# 导出主要类
__all__ = [
    'SECEdgarAPI',
    'AlphaVantageAPI', 
    'EnhancedYahooFinance',
    'FreeNewsAggregator',
    'FreeDataManager'
] 