"""每日指标数据接口。

获取全部股票每日重要的基本面指标，包括换手率、市盈率、市净率、
总市值、流通市值等，可用于选股分析、报表展示等。
"""

from typing import Optional, Dict, Any

import pandas as pd

from src.data.client import TushareClient
from src.data.api_wrappers.base_sync import DateBasedSync


def get_daily_basic(
    trade_date: Optional[str] = None,
    ts_code: Optional[str] = None,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    client: Optional[TushareClient] = None,
) -> pd.DataFrame:
    """Fetch daily basic indicators from Tushare.

    This interface retrieves important daily fundamental indicators for all stocks,
    including turnover rate, PE, PB, market value, etc. It can be used for stock
    selection analysis and report display.

    Note: At least one of trade_date or ts_code must be provided. The recommended
    approach is to use trade_date to fetch data for all stocks on a specific date,
    which is more efficient than fetching by individual stock codes.

    Args:
        trade_date: Specific trade date (YYYYMMDD format). Use this to get all
            stocks' data for a single date. More efficient than ts_code.
        ts_code: Stock code (e.g., '000001.SZ', '600000.SH'). Optional if
            trade_date is provided.
        start_date: Start date (YYYYMMDD format). Use with end_date for date range.
        end_date: End date (YYYYMMDD format). Use with start_date for date range.
        client: Optional TushareClient instance for shared rate limiting.
            If None, creates a new client. For concurrent sync operations,
            pass a shared client to ensure proper rate limiting.

    Returns:
        pd.DataFrame with columns:
        - ts_code: TS stock code
        - trade_date: Trade date (YYYYMMDD)
        - close: Closing price
        - turnover_rate: Turnover rate (%)
        - turnover_rate_f: Turnover rate (free float shares)
        - volume_ratio: Volume ratio
        - pe: Price-to-earnings ratio (total market cap / net profit)
        - pe_ttm: PE ratio (TTM)
        - pb: Price-to-book ratio (total market cap / net assets)
        - ps: Price-to-sales ratio
        - ps_ttm: PS ratio (TTM)
        - dv_ratio: Dividend yield (%)
        - dv_ttm: Dividend yield (TTM) (%)
        - total_share: Total shares (10k shares)
        - float_share: Float shares (10k shares)
        - free_share: Free float shares (10k shares)
        - total_mv: Total market value (10k CNY)
        - circ_mv: Circulating market value (10k CNY)

    Example:
        >>> # Get all stocks for a single date (recommended)
        >>> data = get_daily_basic(trade_date='20240101')
        >>>
        >>> # Get specific stock data
        >>> data = get_daily_basic(ts_code='000001.SZ', trade_date='20240101')
        >>>
        >>> # Get date range data for a specific stock
        >>> data = get_daily_basic(
        ...     ts_code='000001.SZ',
        ...     start_date='20240101',
        ...     end_date='20240131'
        ... )
    """
    client = client or TushareClient()

    # Build parameters
    params = {}
    if trade_date:
        params["trade_date"] = trade_date
    if ts_code:
        params["ts_code"] = ts_code
    if start_date:
        params["start_date"] = start_date
    if end_date:
        params["end_date"] = end_date

    # Fetch data using daily_basic API
    data = client.query("daily_basic", **params)

    # Rename date column if needed
    if "date" in data.columns:
        data = data.rename(columns={"date": "trade_date"})

    return data


class DailyBasicSync(DateBasedSync):
    """每日指标数据批量同步管理器，支持全量/增量同步。

    继承自 DateBasedSync，按日期顺序获取数据。
    每日指标数据适合按日期获取，一次 API 调用即可获取全市场数据。

    Example:
        >>> sync = DailyBasicSync()
        >>> results = sync.sync_all()  # 增量同步
        >>> results = sync.sync_all(force_full=True)  # 全量同步
        >>> preview = sync.preview_sync()  # 预览
    """

    table_name = "daily_basic"
    default_start_date = "20180101"

    # 表结构定义
    TABLE_SCHEMA = {
        "ts_code": "VARCHAR(16) NOT NULL",
        "trade_date": "DATE NOT NULL",
        "close": "DOUBLE",
        "turnover_rate": "DOUBLE",
        "turnover_rate_f": "DOUBLE",
        "volume_ratio": "DOUBLE",
        "pe": "DOUBLE",
        "pe_ttm": "DOUBLE",
        "pb": "DOUBLE",
        "ps": "DOUBLE",
        "ps_ttm": "DOUBLE",
        "dv_ratio": "DOUBLE",
        "dv_ttm": "DOUBLE",
        "total_share": "DOUBLE",
        "float_share": "DOUBLE",
        "free_share": "DOUBLE",
        "total_mv": "DOUBLE",
        "circ_mv": "DOUBLE",
    }

    # 索引定义
    TABLE_INDEXES = [
        ("idx_daily_basic_date_code", ["trade_date", "ts_code"]),
    ]

    # 主键定义
    PRIMARY_KEY = ("ts_code", "trade_date")

    def fetch_single_date(self, trade_date: str) -> pd.DataFrame:
        """获取单日的每日指标数据。

        Args:
            trade_date: 交易日期（YYYYMMDD）

        Returns:
            包含当日所有股票指标的 DataFrame
        """
        # 使用 get_daily_basic 获取数据（传递共享 client）
        data = get_daily_basic(
            trade_date=trade_date,
            client=self.client,  # 传递共享客户端以确保限流
        )
        return data


def sync_daily_basic(
    force_full: bool = False,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    dry_run: bool = False,
) -> pd.DataFrame:
    """同步所有股票的每日指标数据。

    这是每日指标数据同步的主要入口点。

    Args:
        force_full: 若为 True，强制从 20180101 完整重载
        start_date: 手动指定起始日期（YYYYMMDD）
        end_date: 手动指定结束日期（默认为今天）
        dry_run: 若为 True，仅预览将要同步的内容，不写入数据

    Returns:
        同步的数据 DataFrame

    Example:
        >>> # 首次同步（从 20180101 全量加载）
        >>> result = sync_daily_basic()
        >>>
        >>> # 后续同步（增量 - 仅新数据）
        >>> result = sync_daily_basic()
        >>>
        >>> # 强制完整重载
        >>> result = sync_daily_basic(force_full=True)
        >>>
        >>> # 手动指定日期范围
        >>> result = sync_daily_basic(start_date='20240101', end_date='20240131')
        >>>
        >>> # Dry run（仅预览）
        >>> result = sync_daily_basic(dry_run=True)
    """
    sync_manager = DailyBasicSync()
    return sync_manager.sync_all(
        force_full=force_full,
        start_date=start_date,
        end_date=end_date,
        dry_run=dry_run,
    )


def preview_daily_basic_sync(
    force_full: bool = False,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    sample_size: int = 3,
) -> Dict[str, Any]:
    """预览每日指标同步数据量和样本（不实际同步）。

    这是推荐的方式，可在实际同步前检查将要同步的内容。

    Args:
        force_full: 若为 True，预览全量同步（从 20180101）
        start_date: 手动指定起始日期（覆盖自动检测）
        end_date: 手动指定结束日期（默认为今天）
        sample_size: 预览用样本天数（默认: 3）

    Returns:
        包含预览信息的字典：
        {
            'sync_needed': bool,
            'date_count': int,
            'start_date': str,
            'end_date': str,
            'estimated_records': int,
            'sample_data': pd.DataFrame,
            'mode': str,  # 'full', 'incremental', 或 'none'
        }

    Example:
        >>> # 预览将要同步的内容
        >>> preview = preview_daily_basic_sync()
        >>>
        >>> # 预览全量同步
        >>> preview = preview_daily_basic_sync(force_full=True)
        >>>
        >>> # 预览更多样本
        >>> preview = preview_daily_basic_sync(sample_size=5)
    """
    sync_manager = DailyBasicSync()
    return sync_manager.preview_sync(
        force_full=force_full,
        start_date=start_date,
        end_date=end_date,
        sample_size=sample_size,
    )
