import math


def max_drawdown_pct(equities):
    peak, worst = None, 0.0
    for e in equities:
        peak = e if peak is None or e > peak else peak
        if peak:
            worst = max(worst, (peak - e) / peak * 100)
    return worst


def sharpe_ratio(pnl_series, risk_free=0.0, periods_per_year=252):
    """Annualised Sharpe ratio from a list of per-trade P&L values."""
    if len(pnl_series) < 2:
        return 0.0
    import math
    mean = sum(pnl_series) / len(pnl_series)
    variance = sum((x - mean) ** 2 for x in pnl_series) / (len(pnl_series) - 1)
    std = math.sqrt(variance) if variance > 0 else 0.0
    if std == 0:
        return 0.0
    # Annualise: assume each trade is 1 period
    return round((mean - risk_free) / std * math.sqrt(periods_per_year), 2)


def win_streak(trades):
    """Return (current_streak, max_win_streak, max_loss_streak).
    Positive streak = wins, negative = losses."""
    if not trades:
        return 0, 0, 0
    cur = max_w = max_l = 0
    for t in trades:
        if t.get("pnl") is None:
            continue
        if t["pnl"] > 0:
            cur = max(cur + 1, 1)
        else:
            cur = min(cur - 1, -1)
        max_w = max(max_w, cur)
        max_l = min(max_l, cur)
    return cur, max_w, abs(max_l)


def summarize(trades, start_equity=None, equities=None):
    cl = [t for t in trades if t.get("status") == "closed"]
    wins = [t for t in cl if t["pnl"] > 0]
    losses = [t for t in cl if t["pnl"] <= 0]
    gp = sum(t["pnl"] for t in wins)
    gl = -sum(t["pnl"] for t in losses)
    pf = gp / gl if gl > 0 else (999.0 if gp > 0 else 0.0)
    rs = [t["pnl"] / t["risk_amount"] for t in cl if t.get("risk_amount")]
    if not equities and start_equity:
        run, equities = start_equity, [start_equity]
        for t in cl:
            run += t["pnl"]
            equities.append(run)

    streak, max_win_s, max_loss_s = win_streak(cl)

    # Average bars held
    bars_list = [t["bars_held"] for t in cl if t.get("bars_held")]
    avg_bars = round(sum(bars_list) / len(bars_list), 1) if bars_list else 0.0

    # Exit reason breakdown
    exit_counts: dict = {}
    for t in cl:
        r = t.get("exit_reason") or "?"
        exit_counts[r] = exit_counts.get(r, 0) + 1

    pnl_list = [t["pnl"] for t in cl]
    return {
        "trades":           len(cl),
        "wins":             len(wins),
        "losses":           len(losses),
        "win_rate":         round(len(wins) / len(cl), 3) if cl else 0.0,
        "net_pnl":          round(sum(t["pnl"] for t in cl), 2),
        "fees":             round(sum(t["fees"] or 0 for t in cl), 2),
        "profit_factor":    round(pf, 2),
        "expectancy_r":     round(sum(rs) / len(rs), 3) if rs else 0.0,
        "avg_win":          round(gp / len(wins), 2) if wins else 0.0,
        "avg_loss":         round(-gl / len(losses), 2) if losses else 0.0,
        "max_drawdown_pct": round(max_drawdown_pct(equities), 2) if equities else 0.0,
        "sharpe":           sharpe_ratio(pnl_list),
        "streak":           streak,
        "max_win_streak":   max_win_s,
        "max_loss_streak":  max_loss_s,
        "avg_bars_held":    avg_bars,
        "exit_reasons":     exit_counts,
    }
