from __future__ import annotations

import argparse
import json
from collections import Counter, defaultdict
from pathlib import Path
from typing import Any

RUNTIME = Path.home() / ".local/state/CryptoTradingBot/experiments"


def _rows(strategy: str) -> list[dict[str, Any]]:
    path = RUNTIME / strategy / "Tradeanalyse" / "trade_journal.jsonl"
    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 _pnl(row: dict[str, Any]) -> float:
    gross = float(row.get("net_pnl_usd") or row.get("net_pnl") or row.get("realized_pnl_usd") or 0.0)
    costs = sum(float(row.get(key) or 0.0) for key in ("entry_fee_usd", "exit_fee_usd", "spread_cost_usd", "slippage_cost_usd", "funding_cost_usd"))
    return gross if row.get("net_pnl_usd") or row.get("net_pnl") else gross - costs


def _decision(row: dict[str, Any], counts: Counter[str], total: int) -> list[str]:
    coin = str(row.get("coin") or "UNKNOWN").upper()
    reasons: list[str] = []
    top_share = counts.most_common(1)[0][1] / total * 100 if total else 0.0
    pnl = _pnl(row)
    raw_extra = row.get("extra")
    extra: dict[str, Any] = raw_extra if isinstance(raw_extra, dict) else {}
    if coin == "WLD" and top_share > 50:
        reasons.append("blocked_by_leakage")
    if row.get("blocked_by_data_quality") or extra.get("blocked_by_data_quality"):
        reasons.append("blocked_by_data_quality")
    if row.get("blocked_by_cost") or extra.get("blocked_by_cost"):
        reasons.append("blocked_by_cost")
    if pnl < -0.25:
        reasons.append("blocked_by_trend")
    if coin not in {"BTC", "ETH", "SOL", "LINK", "WLD", "SUI", "ENA", "BCH"}:
        reasons.append("blocked_by_breadth")
    if not reasons and pnl < 0:
        reasons.append("blocked_by_no_reclaim")
    return reasons


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Replay/Ablation: apply v76-style filters to existing paper journals.")
    parser.add_argument("--source-strategies", required=True)
    parser.add_argument("--target-strategy", required=True)
    parser.add_argument("--json", action="store_true")
    args = parser.parse_args(argv)
    rows: list[dict[str, Any]] = []
    for strategy in [item.strip() for item in args.source_strategies.split(",") if item.strip()]:
        for row in _rows(strategy):
            if str(row.get("event") or row.get("event_type") or "").lower() == "exit":
                row = dict(row)
                row["_source_strategy"] = strategy
                rows.append(row)
    counts = Counter(str(row.get("coin") or "UNKNOWN").upper() for row in rows)
    taken: list[dict[str, Any]] = []
    blocked: list[dict[str, Any]] = []
    filters: Counter[str] = Counter()
    pnl_by_coin: defaultdict[str, float] = defaultdict(float)
    winners_taken = 0
    losers_blocked = 0
    for row in rows:
        coin = str(row.get("coin") or "UNKNOWN").upper()
        pnl = _pnl(row)
        reasons = _decision(row, counts, len(rows))
        if reasons:
            blocked.append({"source_strategy": row["_source_strategy"], "coin": coin, "pnl_net": round(pnl, 8), "reasons": reasons})
            filters.update(reasons)
            if pnl < 0:
                losers_blocked += 1
        else:
            taken.append({"source_strategy": row["_source_strategy"], "coin": coin, "pnl_net": round(pnl, 8)})
            pnl_by_coin[coin] += pnl
            if pnl > 0:
                winners_taken += 1
    top_coin, top_count = Counter(item["coin"] for item in taken).most_common(1)[0] if taken else (None, 0)
    payload = {
        "status": "ok",
        "target_strategy": args.target_strategy,
        "source_rows": len(rows),
        "taken_count": len(taken),
        "blocked_count": len(blocked),
        "old_winners_v76_would_take": winners_taken,
        "old_losers_v76_would_block": losers_blocked,
        "top_filters": dict(filters.most_common()),
        "pnl_total_net": round(sum(item["pnl_net"] for item in taken), 8),
        "pnl_ex_wld": round(sum(item["pnl_net"] for item in taken if item["coin"] != "WLD"), 8),
        "pnl_ex_top_coin": round(sum(item["pnl_net"] for item in taken if item["coin"] != top_coin), 8),
        "per_coin_pnl": dict(sorted((coin, round(pnl, 8)) for coin, pnl in pnl_by_coin.items())),
        "top_coin_share": round(top_count / len(taken) * 100, 2) if taken else 0.0,
        "blocked_by_cost": filters["blocked_by_cost"],
        "blocked_by_breadth": filters["blocked_by_breadth"],
        "blocked_by_data_quality": filters["blocked_by_data_quality"],
        "blocked_by_leakage": filters["blocked_by_leakage"],
        "blocked_by_trend": filters["blocked_by_trend"],
        "blocked_by_no_reclaim": filters["blocked_by_no_reclaim"],
        "sample_blocked": blocked[:10],
    }
    print(json.dumps(payload, indent=2, sort_keys=True) if args.json else payload)
    return 0


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