"""
Fallback, parameter adaptation, and slow-function protection for akshare functions.

Provides:
- FALLBACK_MAP: degradation chains for broken functions
- PARAM_ADAPTERS: parameter transformers for changed signatures
- SLOW_FUNCTIONS: warnings for full-market functions (>30s)
- SINGLE_STOCK_REDIRECT: redirect full-market calls when a symbol is given
"""

import sys
from typing import Any, Callable, Dict, List, Optional, Tuple


# ---------------------------------------------------------------------------
# Parameter Adapters — fix changed function signatures
# ---------------------------------------------------------------------------

def _adapt_gdfx_symbol(kw: Dict[str, Any]) -> Dict[str, Any]:
    """Convert pure digit codes (e.g. '600519') to prefixed format ('sh600519')."""
    result = dict(kw)
    symbol = result.get("symbol", "")
    if symbol and symbol.isdigit():
        if symbol.startswith("6"):
            result["symbol"] = f"sh{symbol}"
        elif symbol.startswith("0") or symbol.startswith("3"):
            result["symbol"] = f"sz{symbol}"
        elif symbol.startswith("4") or symbol.startswith("8"):
            result["symbol"] = f"bj{symbol}"
        else:
            result["symbol"] = f"sh{symbol}"
    return result


PARAM_ADAPTERS: Dict[str, Callable[[Dict[str, Any]], Dict[str, Any]]] = {
    # stock_lhb_detail_em: symbol parameter removed
    "stock_lhb_detail_em": lambda kw: {k: v for k, v in kw.items() if k != "symbol"},
    # stock_circulate_stock_holder: 'stock' renamed to 'symbol'
    "stock_circulate_stock_holder": lambda kw: (
        {**{k: v for k, v in kw.items() if k != "stock"}, "symbol": kw["stock"]}
        if "stock" in kw
        else kw
    ),
    # stock_hold_management_detail_em: no longer accepts any parameters
    "stock_hold_management_detail_em": lambda kw: {},
    # stock_gdfx_top_10_em: symbol needs prefix format
    "stock_gdfx_top_10_em": _adapt_gdfx_symbol,
    # stock_gdfx_free_top_10_em: same
    "stock_gdfx_free_top_10_em": _adapt_gdfx_symbol,
}


# ---------------------------------------------------------------------------
# Fallback Map — degradation chains for disabled functions
# ---------------------------------------------------------------------------

def _identity(kw: Dict[str, Any]) -> Dict[str, Any]:
    """Pass kwargs through unchanged."""
    return kw


def _drop_all(kw: Dict[str, Any]) -> Dict[str, Any]:
    """Drop all kwargs (for functions that take no params)."""
    return {}


def _keep_symbol(kw: Dict[str, Any]) -> Dict[str, Any]:
    """Keep only the symbol parameter."""
    return {"symbol": kw["symbol"]} if "symbol" in kw else {}


FALLBACK_MAP: Dict[str, List[Tuple[str, Callable[[Dict[str, Any]], Dict[str, Any]]]]] = {
    # 东财财务 → 同花顺
    "stock_financial_analysis_indicator_em": [
        ("stock_financial_analysis_indicator", _identity),
        ("stock_financial_abstract_new_ths", _keep_symbol),
    ],
    "stock_profit_sheet_by_report_em": [
        ("stock_financial_benefit_new_ths", _keep_symbol),
    ],
    "stock_balance_sheet_by_report_em": [
        ("stock_financial_debt_new_ths", _keep_symbol),
    ],
    "stock_cash_flow_sheet_by_report_em": [
        ("stock_financial_cash_new_ths", _keep_symbol),
    ],
    "stock_profit_sheet_by_yearly_em": [
        ("stock_financial_benefit_new_ths", _keep_symbol),
    ],
    # 美股 → 新浪
    "stock_us_hist": [
        ("stock_us_daily", _identity),
    ],
    "stock_us_spot_em": [
        ("stock_us_spot", _drop_all),
    ],
    "stock_us_famous_spot_em": [
        ("stock_us_spot", _drop_all),
    ],
    # 指数
    "stock_zh_index_spot_sina": [
        ("index_global_spot_em", _drop_all),
    ],
    "index_zh_a_hist": [
        ("stock_zh_index_daily_em", _identity),
    ],
    # ETF
    "fund_etf_spot_em": [
        ("fund_etf_category_sina", _identity),
    ],
    # 日内分时
    "stock_intraday_sina": [
        ("stock_intraday_em", _identity),
    ],
    # 新闻
    "stock_telegraph_cls": [
        ("stock_news_main_cx", _drop_all),
    ],
    # 板块
    "stock_sector_spot": [
        ("stock_board_industry_name_em", _drop_all),
    ],
    # 深市代码
    "stock_info_sz_name_code": [
        ("stock_info_sh_name_code", _identity),
    ],
    "stock_info_a_code_name": [
        ("stock_info_sh_name_code", _identity),
    ],
    # THS 资金流 → 东财
    "stock_fund_flow_individual": [
        ("stock_individual_fund_flow_rank", _identity),
    ],
    "stock_fund_flow_concept": [
        ("stock_sector_fund_flow_rank", _identity),
    ],
    # 东财 spot 系列：全量接口无合适降级，依赖 --retry 重试
    # stock_zh_a_spot_em / stock_sh_a_spot_em / stock_sz_a_spot_em
    # stock_bj_a_spot_em / stock_hk_spot_em → 不降级
}


# ---------------------------------------------------------------------------
# Slow Functions — warn when calling full-market APIs
# ---------------------------------------------------------------------------

SLOW_FUNCTIONS: Dict[str, int] = {
    "stock_zh_a_spot": 31,
    "stock_main_fund_flow": 62,
    "stock_market_fund_flow": 45,
    "stock_sector_fund_flow_rank": 40,
    "stock_individual_fund_flow_rank": 55,
    "stock_board_concept_name_em": 35,
    "stock_board_industry_name_em": 30,
}


def warn_if_slow(func_name: str) -> None:
    """Print a stderr warning if the function is known to be slow."""
    seconds = SLOW_FUNCTIONS.get(func_name)
    if seconds:
        print(
            f"Warning: {func_name} is a full-market API, typically takes ~{seconds}s",
            file=sys.stderr,
        )


# ---------------------------------------------------------------------------
# Single Stock Redirect — avoid full-market pull when only one stock is needed
# ---------------------------------------------------------------------------

# Single Stock Redirect — reserved for future single-stock fast paths
# Currently empty: no redirect targets available that are faster than primary
SINGLE_STOCK_REDIRECT: Dict[str, str] = {}
