"""Futures indicators (Track B).

期货衍生指标（Track B，本地计算），包含历史波动率、波动率锥、HV-IV Spread、
持仓量分析、VWAP、期限结构、跨合约价差、多空比等功能。
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import pandas as pd

from .modules.derivatives.volatility.base import HVMethod

if TYPE_CHECKING:
    from .modules.derivatives.futures.base import FuturesIndicatorCalculator
    from .modules.derivatives.volatility.base import VolatilityCalculator


def _get_futures_indicator_calculator() -> FuturesIndicatorCalculator:
    """Create a FuturesIndicatorCalculator via factory."""
    from .modules.derivatives.futures.factory import FuturesIndicatorFactory

    return FuturesIndicatorFactory.get_calculator()


def _get_volatility_calculator() -> VolatilityCalculator:
    """Create a VolatilityCalculator via factory."""
    from .modules.derivatives.volatility.factory import VolatilityFactory

    return VolatilityFactory.get_calculator()


def get_historical_volatility(
    ohlc_df: pd.DataFrame,
    method: HVMethod = "close_to_close",
    window: int = 20,
    annualization: int = 252,
) -> pd.DataFrame:
    """Calculate historical volatility.

    计算历史波动率，支持 C2C/Parkinson/Garman-Klass/Yang-Zhang。

    Args:
        ohlc_df: OHLC DataFrame.
        method: HV estimation method, default 'close_to_close'.
        window: Rolling window, default 20.
        annualization: Trading days per year, default 252.

    Returns:
        pd.DataFrame: [timestamp, hv]
    """
    return _get_volatility_calculator().get_hv(
        ohlc_df=ohlc_df, method=method, window=window, annualization=annualization,
    )


def get_volatility_cone(
    ohlc_df: pd.DataFrame,
    windows: tuple[int, ...] = (5, 10, 20, 60, 120),
    percentiles: tuple[float, ...] = (0.1, 0.25, 0.5, 0.75, 0.9),
    method: HVMethod = "close_to_close",
    annualization: int = 252,
) -> pd.DataFrame:
    """Calculate volatility cone.

    计算波动率锥，输出不同窗口下 HV 的分位数分布。

    Args:
        ohlc_df: OHLC DataFrame.
        windows: Window lengths, default (5,10,20,60,120).
        percentiles: Percentiles (0-1), default (0.1,0.25,0.5,0.75,0.9).
        method: HV method, default 'close_to_close'.
        annualization: Trading days per year, default 252.

    Returns:
        pd.DataFrame: [window, percentile, hv]
    """
    return _get_volatility_calculator().get_volatility_cone(
        ohlc_df=ohlc_df, windows=list(windows), percentiles=list(percentiles),
        method=method, annualization=annualization,
    )


def get_hv_iv_spread(hv_df: pd.DataFrame, iv_df: pd.DataFrame) -> pd.DataFrame:
    """Calculate HV-IV spread.

    计算 HV-IV Spread（历史波动率与隐含波动率差）。

    Args:
        hv_df: DataFrame with [timestamp, hv].
        iv_df: DataFrame with [timestamp, iv].

    Returns:
        pd.DataFrame: [timestamp, hv, iv, hv_iv_spread]
    """
    return _get_volatility_calculator().get_hv_iv_spread(hv_df=hv_df, iv_df=iv_df)


def get_futures_oi_change(oi_df: pd.DataFrame) -> pd.DataFrame:
    """Calculate open interest change.

    计算持仓量变化。

    Args:
        oi_df: DataFrame with [timestamp, open_interest].

    Returns:
        pd.DataFrame: [timestamp, open_interest, open_interest_change]
    """
    return _get_futures_indicator_calculator().get_oi_change(oi_df)


def get_futures_price_oi_divergence(
    close_df: pd.DataFrame, oi_df: pd.DataFrame
) -> pd.DataFrame:
    """Analyze price vs open interest divergence.

    分析价格与持仓量背离信号。

    Args:
        close_df: Price series with [timestamp, close].
        oi_df: OI series with [timestamp, open_interest].

    Returns:
        pd.DataFrame: [timestamp, close, open_interest, signal]
    """
    return _get_futures_indicator_calculator().get_price_oi_divergence(close_df, oi_df)


def get_futures_vwap(ohlcv_df: pd.DataFrame) -> pd.DataFrame:
    """Calculate VWAP.

    计算成交量加权平均价。

    Args:
        ohlcv_df: OHLCV DataFrame.

    Returns:
        pd.DataFrame: [timestamp, vwap]
    """
    return _get_futures_indicator_calculator().get_vwap(ohlcv_df)


def get_futures_term_structure(quotes_df: pd.DataFrame) -> pd.DataFrame:
    """Calculate term structure metrics.

    计算期限结构指标。

    Args:
        quotes_df: Multi-contract quotes with [contract, price, timestamp].

    Returns:
        pd.DataFrame: [timestamp, curve_slope, curve_level]
    """
    return _get_futures_indicator_calculator().get_term_structure(quotes_df)


def get_futures_spread(near_df: pd.DataFrame, far_df: pd.DataFrame) -> pd.DataFrame:
    """Calculate inter-contract spread.

    计算跨合约价差。

    Args:
        near_df: Near contract with [timestamp, close].
        far_df: Far contract with [timestamp, close].

    Returns:
        pd.DataFrame: [timestamp, spread]
    """
    return _get_futures_indicator_calculator().get_spread(near_df, far_df)


def get_futures_long_short_ratio(rank_df: pd.DataFrame) -> pd.DataFrame:
    """Calculate long/short ratio from position ranking data.

    根据持仓排名计算多空比。

    Args:
        rank_df: Position ranking DataFrame.

    Returns:
        pd.DataFrame: [date, exchange, variety, contract, long_short_ratio]
    """
    return _get_futures_indicator_calculator().get_long_short_ratio(rank_df)
