from __future__ import annotations

from src.tools.tradingview_promotion_gates import evaluate_promotion_gates, format_promotion_gate_report


def _perf(closed: int = 30, pnl: str = "1.25", winrate: str = "55.00") -> dict:
    return {
        "overall": {"closed_trades": closed, "net_pnl_usd": pnl, "winrate_pct": winrate},
        "strategies": {"gaussian_channel_v1": {"closed_trades": closed, "net_pnl_usd": pnl, "winrate_pct": winrate}},
        "coins": {"BTC": {"closed_trades": closed, "net_pnl_usd": pnl, "winrate_pct": winrate}},
    }


def test_promotion_gates_keep_strategy_in_paper_when_sample_too_small():
    result = evaluate_promotion_gates(_perf(closed=5), operational_gates={"reconcile_clean": True, "alerts_proven": True, "loss_gates_active": True, "kill_switch_ready": True, "stop_handling_ready": True})

    assert result["final_status"] == "paper_only"
    assert "sample_too_small" in result["blockers"]
    assert result["live_allowed"] is False


def test_promotion_gates_allow_shadow_candidate_but_never_live():
    result = evaluate_promotion_gates(_perf(), operational_gates={"reconcile_clean": True, "alerts_proven": True, "loss_gates_active": True, "kill_switch_ready": True, "stop_handling_ready": True})

    assert result["final_status"] == "shadow_candidate_not_live"
    assert result["live_allowed"] is False
    assert result["shadow_candidate"] is True


def test_promotion_gates_block_when_operational_gate_missing():
    result = evaluate_promotion_gates(_perf(), operational_gates={"reconcile_clean": False, "alerts_proven": True, "loss_gates_active": True, "kill_switch_ready": True, "stop_handling_ready": True})

    assert result["final_status"] == "paper_only"
    assert "reconcile_clean_missing" in result["blockers"]


def test_promotion_gate_report_is_short_and_explicit():
    result = evaluate_promotion_gates(_perf(closed=30), operational_gates={"reconcile_clean": True, "alerts_proven": True, "loss_gates_active": True, "kill_switch_ready": True, "stop_handling_ready": True})

    line = format_promotion_gate_report(result)

    assert "Promotion Gates:" in line
    assert "shadow_candidate_not_live" in line
    assert "source=tradingview_closed_trades" in line
    assert "live=nein" in line


def test_promotion_gates_use_lifecycle_scorecard_when_provided():
    lifecycle = {
        "evidence_source": "true_lifecycle_exits_only",
        "closed_trades": 2,
        "net_pnl_usd": "0.15",
        "winrate_pct": "50.00",
        "blockers": ["lifecycle_sample_too_small"],
    }
    result = evaluate_promotion_gates(
        _perf(closed=99, pnl="99", winrate="99"),
        operational_gates={"reconcile_clean": True, "alerts_proven": True, "loss_gates_active": True, "kill_switch_ready": True, "stop_handling_ready": True},
        lifecycle_scorecard=lifecycle,
        min_closed_trades=30,
    )

    assert result["evidence_source"] == "true_lifecycle_exits_only"
    assert result["closed_trades"] == 2
    assert result["net_pnl_usd"] == "0.15"
    assert result["final_status"] == "paper_only"
    assert "lifecycle_sample_too_small" in result["blockers"]
    assert "sample_too_small" in result["blockers"]
    assert result["live_allowed"] is False
