"""shadow_audit.py — Compare expected PnL vs actual PnL per strategy×regime.

Phase 7: Detects execution drift — when actual trade outcomes deviate
significantly from what the strategy's historical edge would predict.

Usage::

    from src.learning.shadow_audit import audit_strategy_drift
    drifts = audit_strategy_drift()
"""

from __future__ import annotations

from typing import Any


def audit_strategy_drift(min_samples: int = 5, drift_threshold_pct: float = 30.0) -> list[dict[str, Any]]:
    """Compare expected vs actual PnL for each strategy×regime pair.

    Expected = historical avg_pnl from edge_sizer (or brain baseline)
    Actual   = recent trade outcomes from trading_brain

    Returns list of drifts where |actual - expected| > threshold.
    """
    drifts: list[dict[str, Any]] = []

    try:
        from src.learning.trading_brain import get_brain
        brain = get_brain()
    except Exception:
        return drifts

    # Get per-regime×strategy actual performance
    try:
        by_rs = brain.query_by_regime_session()
    except Exception:
        by_rs = []

    for g in by_rs:
        n = g.get("n", 0)
        if n < min_samples:
            continue
        regime_label = g.get("regime", "unknown")
        session_label = g.get("session", "unknown")
        actual_wr = g.get("win_rate", 0.5)
        actual_pnl = g.get("avg_pnl", 0)

        # Get expected from baseline
        baseline = brain.query_win_rate()
        expected_wr = baseline.get("win_rate", 0.5)
        expected_pnl = baseline.get("avg_pnl", 0)

        wr_drift = abs(actual_wr - expected_wr) * 100
        pnl_drift = abs(actual_pnl - expected_pnl) / max(0.01, abs(expected_pnl)) * 100 if expected_pnl != 0 else 0

        if wr_drift > drift_threshold_pct or pnl_drift > drift_threshold_pct:
            drifts.append({
                "regime": regime_label,
                "session": session_label,
                "n": n,
                "expected_wr": round(expected_wr, 4),
                "actual_wr": round(actual_wr, 4),
                "wr_drift_pct": round(wr_drift, 1),
                "expected_pnl": round(expected_pnl, 2),
                "actual_pnl": round(actual_pnl, 2),
            })

    # Generate knowledge base entries for significant drifts
    for d in drifts[:3]:
        try:
            from src.learning.knowledge_writer import _ensure_subdir
            import time as _time
            lesson_dir = _ensure_subdir("lessons")
            strategy = d["strategy"]
            regime = d["regime"]
            fname = f"EXECUTION_DRIFT_{strategy}_{regime}.md"
            fp = lesson_dir / fname
            if not fp.exists():
                wr_d = d["wr_drift_pct"]
                ew = d["expected_wr"]
                aw = d["actual_wr"]
                ep = d["expected_pnl"]
                ap = d["actual_pnl"]
                ts = _time.strftime('%Y-%m-%dT%H:%M:%S')
                content = f"""---
lesson_type: EXECUTION_DRIFT_{strategy}_{regime}
strategy: {strategy}
regime: {regime}
wr_drift_pct: {wr_d}
expected_wr: {ew}
actual_wr: {aw}
discovered: {ts}
tags: [lesson, execution_drift, {strategy}, {regime}]
---

# Execution Drift: {strategy} in {regime}

## Stats
- Expected win rate: {ew*100:.1f}%
- Actual win rate: {aw*100:.1f}%
- Drift: {wr_d:.1f}% deviation

## Expected PnL: ${ep:.2f} | Actual: ${ap:.2f}

## Action
- If drift > 30%: consider pausing {strategy} in {regime}
- Review recent trades for external factors (news, spread anomaly)
- Back to [[INDEX]]
"""
                fp.write_text(content, encoding="utf-8")
        except Exception:
            pass

    return drifts
