"""Stock historical list interface.

Fetch daily stock list from Tushare bak_basic API.
Data available from 2016 onwards.
"""

import pandas as pd
from typing import Optional

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


def get_bak_basic(
    trade_date: Optional[str] = None,
    ts_code: Optional[str] = None,
) -> pd.DataFrame:
    """Fetch historical stock list from Tushare.

    This interface retrieves the daily stock list including basic information
    for all stocks on a specific trade date. Data is available from 2016 onwards.

    Args:
        trade_date: Specific trade date in YYYYMMDD format
        ts_code: Stock code filter (optional, e.g., '000001.SZ')

    Returns:
        pd.DataFrame with columns:
        - trade_date: Trade date (YYYYMMDD)
        - ts_code: TS stock code
        - name: Stock name
        - industry: Industry
        - area: Region
        - pe: P/E ratio (dynamic)
        - float_share: Float shares (100 million)
        - total_share: Total shares (100 million)
        - total_assets: Total assets (100 million)
        - liquid_assets: Liquid assets (100 million)
        - fixed_assets: Fixed assets (100 million)
        - reserved: Reserve fund
        - reserved_pershare: Reserve per share
        - eps: Earnings per share
        - bvps: Book value per share
        - pb: P/B ratio
        - list_date: Listing date
        - undp: Undistributed profit
        - per_undp: Undistributed profit per share
        - rev_yoy: Revenue YoY (%)
        - profit_yoy: Profit YoY (%)
        - gpr: Gross profit ratio (%)
        - npr: Net profit ratio (%)
        - holder_num: Number of shareholders

    Example:
        >>> # Get all stocks for a single date
        >>> data = get_bak_basic(trade_date='20240101')
        >>>
        >>> # Get specific stock data
        >>> data = get_bak_basic(ts_code='000001.SZ', trade_date='20240101')
    """
    client = TushareClient()

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

    # Fetch data
    data = client.query("bak_basic", **params)

    return data


class BakBasicSync(DateBasedSync):
    """历史股票列表批量同步管理器，支持全量/增量同步。

    继承自 DateBasedSync，按日期顺序获取数据。
    数据从 2016 年开始可用。

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

    table_name = "bak_basic"
    default_start_date = "20160101"

    # 表结构定义
    TABLE_SCHEMA = {
        "trade_date": "DATE NOT NULL",
        "ts_code": "VARCHAR(16) NOT NULL",
        "name": "VARCHAR(50)",
        "industry": "VARCHAR(50)",
        "area": "VARCHAR(50)",
        "pe": "DOUBLE",
        "float_share": "DOUBLE",
        "total_share": "DOUBLE",
        "total_assets": "DOUBLE",
        "liquid_assets": "DOUBLE",
        "fixed_assets": "DOUBLE",
        "reserved": "DOUBLE",
        "reserved_pershare": "DOUBLE",
        "eps": "DOUBLE",
        "bvps": "DOUBLE",
        "pb": "DOUBLE",
        "list_date": "VARCHAR(8)",
        "undp": "DOUBLE",
        "per_undp": "DOUBLE",
        "rev_yoy": "DOUBLE",
        "profit_yoy": "DOUBLE",
        "gpr": "DOUBLE",
        "npr": "DOUBLE",
        "holder_num": "DOUBLE",
    }

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

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

    def fetch_single_date(self, trade_date: str) -> pd.DataFrame:
        return get_bak_basic(trade_date=trade_date)


def sync_bak_basic(
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    force_full: bool = False,
) -> pd.DataFrame:
    """Sync historical stock list to DuckDB with intelligent incremental sync.

    Logic:
    - If table doesn't exist: create table + composite index (trade_date, ts_code) + full sync
    - If table exists: incremental sync from last_date + 1

    Args:
        start_date: Start date for sync (YYYYMMDD format, default: 20160101 for full, last_date+1 for incremental)
        end_date: End date for sync (YYYYMMDD format, default: today)
        force_full: If True, force full reload from 20160101

    Returns:
        pd.DataFrame with synced data
    """
    sync_manager = BakBasicSync()
    return sync_manager.sync_all(
        start_date=start_date,
        end_date=end_date,
        force_full=force_full,
    )


if __name__ == "__main__":
    # Test sync
    result = sync_bak_basic(end_date="20240102")
    print(f"Synced {len(result)} records")
    if not result.empty:
        print("\nSample data:")
        print(result.head())
