"""绩效计算模块。

根据资金曲线计算收益、年化收益、夏普比率、最大回撤等指标。
"""
from __future__ import annotations

import numpy as np
import pandas as pd

from utils.logger import setup_logger

logger = setup_logger(__name__)


def calc_performance(
    equity_df: pd.DataFrame,
    trade_count: int = 0,
    trade_history: list = None,
    trading_days_per_year: int = 252,
) -> dict:
    """根据资金曲线计算常用绩效指标。

    参数：
    - equity_df: 包含列 ['trade_date', 'total_asset', 'cash', 'market_value'] 的 DataFrame；
    - trade_count: 总交易次数（买入+卖出）；
    - trade_history: 交易历史记录（用于计算胜率和盈亏比）；
    - trading_days_per_year: 年化使用的交易日数，默认 252。

    返回：
    - dict，包含累积收益、年化收益、夏普比率、最大回撤、资金利用率、胜率、盈亏比等。
    """
    if equity_df.empty:
        logger.warning("资金曲线为空，无法计算绩效")
        return {}

    df = equity_df.copy()
    df = df.sort_values("trade_date").reset_index(drop=True)
    df["ret"] = df["total_asset"].pct_change().fillna(0.0)

    # 累积收益
    cum_return = df["total_asset"].iloc[-1] / df["total_asset"].iloc[0] - 1

    # 年化收益
    n = len(df)
    if n <= 1:
        ann_return = 0.0
        years = 0.0
    else:
        ann_return = (1 + cum_return) ** (trading_days_per_year / n) - 1
        years = n / trading_days_per_year

    # 夏普比率（假设无无风险利率）
    ret_mean = df["ret"].mean()
    ret_std = df["ret"].std(ddof=1)
    if ret_std == 0:
        sharpe = 0.0
    else:
        sharpe = (ret_mean * trading_days_per_year) / (ret_std * (trading_days_per_year**0.5))

    # 最大回撤
    cummax = df["total_asset"].cummax()
    drawdown = df["total_asset"] / cummax - 1
    max_drawdown = float(drawdown.min())

    # 资金利用率统计（每日持仓市值 / 总资产）
    if "market_value" in df.columns and "total_asset" in df.columns:
        df["capital_utilization"] = df["market_value"] / df["total_asset"]
        avg_capital_utilization = df["capital_utilization"].mean()
    else:
        avg_capital_utilization = 0.0

    # 交易次数统计
    total_trades = trade_count
    if years > 0:
        avg_trades_per_year = total_trades / years
    else:
        avg_trades_per_year = 0.0
    
    # 计算胜率和盈亏比（从交易历史中获取）
    win_rate = 0.0
    profit_loss_ratio = 0.0
    win_count = 0
    loss_count = 0
    total_win_pct = 0.0
    total_loss_pct = 0.0
    
    if trade_history and len(trade_history) > 0:
        for trade in trade_history:
            if trade.get("is_win", False):
                win_count += 1
                total_win_pct += trade.get("profit_pct", 0.0)
            else:
                loss_count += 1
                total_loss_pct += abs(trade.get("profit_pct", 0.0))
        
        total_complete_trades = win_count + loss_count
        if total_complete_trades > 0:
            win_rate = win_count / total_complete_trades
        
        # 计算平均盈亏比：平均盈利 / 平均亏损
        avg_win = total_win_pct / win_count if win_count > 0 else 0.0
        avg_loss = total_loss_pct / loss_count if loss_count > 0 else 0.0
        
        if avg_loss > 0:
            profit_loss_ratio = avg_win / avg_loss
        else:
            profit_loss_ratio = 0.0 if avg_win == 0 else float('inf')

    res = {
        "cum_return": float(cum_return),
        "ann_return": float(ann_return),
        "sharpe": float(sharpe),
        "max_drawdown": max_drawdown,
        "avg_capital_utilization": float(avg_capital_utilization),
        "total_trades": int(total_trades),
        "avg_trades_per_year": float(avg_trades_per_year),
        "backtest_years": float(years),
        "win_rate": float(win_rate),
        "profit_loss_ratio": float(profit_loss_ratio),
        "win_count": int(win_count),
        "loss_count": int(loss_count),
    }

    # 格式化输出绩效指标（中文、分行、百分比）
    logger.info("=" * 60)
    logger.info("回测绩效指标汇总")
    logger.info("=" * 60)
    logger.info(f"回测年数:        {years:.2f} 年")
    logger.info(f"总交易次数:      {total_trades} 次")
    logger.info(f"年平均交易次数:  {avg_trades_per_year:.2f} 次/年")
    logger.info("-" * 60)
    logger.info(f"累计收益率:      {cum_return * 100:+.2f}%")
    logger.info(f"年化收益率:      {ann_return * 100:+.2f}%")
    logger.info(f"夏普比率:        {sharpe:.4f}")
    logger.info(f"最大回撤:        {max_drawdown * 100:.2f}%")
    logger.info(f"平均资金利用率:  {avg_capital_utilization * 100:.2f}%")
    logger.info("-" * 60)
    logger.info(f"胜率:            {win_rate * 100:.2f}% ({win_count}胜 / {loss_count}败)")
    if profit_loss_ratio == float('inf'):
        logger.info(f"平均盈亏比:      ∞ (无亏损交易)")
    else:
        logger.info(f"平均盈亏比:      {profit_loss_ratio:.2f}")
    logger.info("=" * 60)

    return res
