from __future__ import annotations

import argparse
import json
from collections import defaultdict
from decimal import Decimal, InvalidOperation
from pathlib import Path
from typing import Any

BRIDGE_ID = "tradingview_paper_bridge"


def _read_jsonl(path: Path) -> list[dict[str, Any]]:
    if not path.exists():
        return []
    rows: list[dict[str, Any]] = []
    for line in path.read_text(encoding="utf-8", errors="replace").splitlines():
        if not line.strip():
            continue
        try:
            rows.append(json.loads(line))
        except json.JSONDecodeError:
            continue
    return rows


def _decimal(value: Any) -> Decimal:
    try:
        return Decimal(str(value))
    except (InvalidOperation, ValueError, TypeError):
        return Decimal("0")


def _fmt(value: Decimal, places: str = "0.01") -> str:
    return str(value.quantize(Decimal(places)))


def _empty_bucket() -> dict[str, Any]:
    return {"closed_trades": 0, "wins": 0, "losses": 0, "net_pnl": Decimal("0")}


def _finalize(bucket: dict[str, Any]) -> dict[str, Any]:
    closed = int(bucket["closed_trades"])
    wins = int(bucket["wins"])
    losses = int(bucket["losses"])
    net = bucket["net_pnl"]
    winrate = (Decimal(wins) / Decimal(closed) * Decimal("100")) if closed else Decimal("0")
    return {
        "closed_trades": closed,
        "wins": wins,
        "losses": losses,
        "winrate_pct": _fmt(winrate),
        "net_pnl_usd": _fmt(net),
    }


def summarize_strategy_performance(runtime_dir: str | Path = "runtime") -> dict[str, Any]:
    journal = Path(runtime_dir) / "experiments" / BRIDGE_ID / "trade_journal.jsonl"
    exits = [row for row in _read_jsonl(journal) if row.get("event") == "paper_exit"]
    overall = _empty_bucket()
    by_strategy: dict[str, dict[str, Any]] = defaultdict(_empty_bucket)
    by_coin: dict[str, dict[str, Any]] = defaultdict(_empty_bucket)
    for row in exits:
        pnl = _decimal(row.get("net_pnl_usd"))
        strategy = str(row.get("strategy_id") or "unknown")
        coin = str(row.get("coin") or "UNKNOWN").upper()
        for bucket in (overall, by_strategy[strategy], by_coin[coin]):
            bucket["closed_trades"] += 1
            bucket["net_pnl"] += pnl
            if pnl > 0:
                bucket["wins"] += 1
            elif pnl < 0:
                bucket["losses"] += 1
    return {
        "overall": _finalize(overall),
        "strategies": {k: _finalize(v) for k, v in sorted(by_strategy.items())},
        "coins": {k: _finalize(v) for k, v in sorted(by_coin.items())},
    }


def recommend_strategy_actions(summary: dict[str, Any], *, min_closed_trades: int = 20) -> dict[str, str]:
    recs: dict[str, str] = {}
    for strategy, stats in summary.get("strategies", {}).items():
        closed = int(stats.get("closed_trades") or 0)
        pnl = _decimal(stats.get("net_pnl_usd"))
        winrate = _decimal(stats.get("winrate_pct"))
        if closed < min_closed_trades:
            recs[strategy] = "continue_paper_too_few_trades"
        elif pnl > 0 and winrate >= Decimal("50"):
            recs[strategy] = "shadow_candidate_not_live"
        elif pnl < 0 or winrate < Decimal("35"):
            recs[strategy] = "pause_or_rework"
        else:
            recs[strategy] = "continue_paper_watch"
    return recs


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Summarize TradingView paper strategy performance.")
    parser.add_argument("--runtime-dir", default="runtime")
    parser.add_argument("--min-closed-trades", type=int, default=20)
    args = parser.parse_args(argv)
    summary = summarize_strategy_performance(args.runtime_dir)
    summary["recommendations"] = recommend_strategy_actions(summary, min_closed_trades=args.min_closed_trades)
    print(json.dumps(summary, indent=2, sort_keys=True))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
