from __future__ import annotations

import argparse
import json
from decimal import Decimal, InvalidOperation
from typing import Any

from src.tools.tradingview_strategy_performance import summarize_strategy_performance

REQUIRED_OPERATIONAL_GATES = (
    "reconcile_clean",
    "alerts_proven",
    "loss_gates_active",
    "kill_switch_ready",
    "stop_handling_ready",
)


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


def evaluate_promotion_gates(
    performance_summary: dict[str, Any],
    *,
    operational_gates: dict[str, bool] | None = None,
    lifecycle_scorecard: dict[str, Any] | None = None,
    min_closed_trades: int = 20,
    min_net_pnl_usd: Decimal = Decimal("0"),
    min_winrate_pct: Decimal = Decimal("50"),
) -> dict[str, Any]:
    gates = operational_gates or {}
    overall = performance_summary.get("overall", {})
    evidence_source = "tradingview_closed_trades"
    closed = int(overall.get("closed_trades") or 0)
    net_pnl = _decimal(overall.get("net_pnl_usd"))
    winrate = _decimal(overall.get("winrate_pct"))
    lifecycle_blockers: list[str] = []
    if lifecycle_scorecard is not None:
        evidence_source = str(lifecycle_scorecard.get("evidence_source") or "true_lifecycle_exits_only")
        closed = int(lifecycle_scorecard.get("closed_trades") or 0)
        net_pnl = _decimal(lifecycle_scorecard.get("net_pnl_usd"))
        winrate = _decimal(lifecycle_scorecard.get("winrate_pct"))
        lifecycle_blockers = [str(item) for item in (lifecycle_scorecard.get("blockers") or [])]
    blockers: list[str] = []
    for gate in REQUIRED_OPERATIONAL_GATES:
        if gates.get(gate) is not True:
            blockers.append(f"{gate}_missing")
    blockers.extend(lifecycle_blockers)
    if closed < min_closed_trades:
        blockers.append("sample_too_small")
    if net_pnl <= min_net_pnl_usd:
        blockers.append("net_pnl_not_positive")
    if winrate < min_winrate_pct:
        blockers.append("winrate_below_threshold")
    blockers = list(dict.fromkeys(blockers))
    shadow_candidate = not blockers
    return {
        "final_status": "shadow_candidate_not_live" if shadow_candidate else "paper_only",
        "shadow_candidate": shadow_candidate,
        "live_allowed": False,
        "evidence_source": evidence_source,
        "blockers": blockers,
        "closed_trades": closed,
        "net_pnl_usd": str(net_pnl),
        "winrate_pct": str(winrate),
        "required_operational_gates": list(REQUIRED_OPERATIONAL_GATES),
    }


def format_promotion_gate_report(result: dict[str, Any]) -> str:
    blockers = result.get("blockers") or []
    blocker_text = ",".join(blockers[:4]) if blockers else "keine"
    return (
        "Promotion Gates: "
        f"status={result.get('final_status')}, "
        f"source={result.get('evidence_source', 'tradingview_closed_trades')}, "
        f"closed={result.get('closed_trades')}, "
        f"net_pnl={result.get('net_pnl_usd')} USDC, "
        f"winrate={result.get('winrate_pct')}%, "
        f"blocker={blocker_text}, "
        "live=nein"
    )


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Evaluate TradingView paper promotion gates.")
    parser.add_argument("--runtime-dir", default="runtime")
    parser.add_argument("--json", action="store_true")
    args = parser.parse_args(argv)
    perf = summarize_strategy_performance(args.runtime_dir)
    result = evaluate_promotion_gates(perf)
    if args.json:
        print(json.dumps(result, indent=2, sort_keys=True))
    else:
        print(format_promotion_gate_report(result))
    return 0


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