from __future__ import annotations

import json
from pathlib import Path

import paper_scorecard_report
from paper_scorecard_report import build_paper_scorecard_report


def _write_journal(path: Path, strategy_id: str, pnls: list[float]) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    lines: list[str] = []
    for i, pnl in enumerate(pnls):
        coin = ["BTC", "ETH", "SOL", "HYPE"][i % 4]
        lines.append(json.dumps({"event_type": "entry", "coin": coin, "price": 100, "size": 1, "extra": {"strategy_id": strategy_id, "risk_usd": 2.0}}))
        lines.append(json.dumps({"event_type": "exit", "coin": coin, "realized_pnl_usd": pnl, "extra": {"strategy_id": strategy_id}}))
    path.write_text("\n".join(lines) + "\n", encoding="utf-8")


def test_paper_scorecard_report_is_read_only_and_ranks_by_score(tmp_path: Path) -> None:
    runtime = tmp_path / "state"
    _write_journal(runtime / "experiments" / "weak" / "Tradeanalyse" / "trade_journal.jsonl", "weak", [-0.2, 0.1, -0.1, -0.3, 0.1])
    _write_journal(runtime / "experiments" / "strong" / "Tradeanalyse" / "trade_journal.jsonl", "strong", [0.8, 0.6, -0.1, 0.5, 0.7, -0.1] * 5)

    report = build_paper_scorecard_report(runtime_dir=runtime)

    assert report.startswith("Paper Strategy Scorecard")
    assert "Mode: read-only" in report
    assert report.index("strong") < report.index("weak")
    assert "Live-preview-ready" in report
    assert "Blocked" in report
    assert "global_policy=Blocked" in report
    assert "expected_move_below_cost_hurdle" in report
    assert "orders" not in report.lower()


def test_paper_scorecard_report_can_mark_global_policy_tiny_ready_with_explicit_evidence(tmp_path: Path) -> None:
    runtime = tmp_path / "state"
    _write_journal(runtime / "experiments" / "strong" / "Tradeanalyse" / "trade_journal.jsonl", "strong", [0.8, 0.6, -0.1, 0.5, 0.7, -0.1] * 5)
    signal_path = runtime / "experiments" / "strong" / "Tradeanalyse" / "signal_journal.jsonl"
    signal_path.write_text("\n".join(json.dumps({"expected_move_vs_cost": "4.5", "final_decision": "paper_entered"}) for _ in range(30)) + "\n", encoding="utf-8")
    evidence = runtime / "strategy_policy_context.json"
    evidence.write_text(json.dumps({"reconcile_clean": True, "stops_confirmed": True, "alerts_confirmed": True, "kill_switch_active": False, "market_regime": {"btc_trend": "bullish", "eth_trend": "bullish", "choppy": False}}), encoding="utf-8")

    report = build_paper_scorecard_report(runtime_dir=runtime)

    assert "global_policy=Tiny-live-preview-ready" in report
    assert "recommended_mode=tiny_live_preview" in report


def test_v76_learning_block_reports_tradingview_impulse_categories(tmp_path: Path, monkeypatch) -> None:
    runtime = tmp_path / "runtime" / "experiments"
    anti = runtime / "candidate_v76_fee_aware_anti_chase"
    anti.mkdir(parents=True)
    rows = [
        {"coin": "BTC", "would_enter": True, "expected_move_vs_cost": "5", "tradingview_impulse": {"category": "buy_opportunity", "action": "paper_candidate_if_other_gates_pass"}},
        {"coin": "ETH", "would_enter": False, "block_reason": ["tv_bias_bearish"], "expected_move_vs_cost": "1", "tradingview_impulse": {"category": "avoid_long", "action": "block_or_demote"}},
    ]
    (anti / "signal_journal.jsonl").write_text("\n".join(json.dumps(row) for row in rows) + "\n", encoding="utf-8")
    (anti / "trade_journal.jsonl").write_text("\n".join([
        json.dumps({"event": "entry", "coin": "BTC", "net_pnl_usd": "0", "extra": {"tradingview_impulse": {"category": "buy_opportunity"}}}),
        json.dumps({"event": "exit", "coin": "BTC", "net_pnl_usd": "0.42", "extra": {"tradingview_impulse": {"category": "buy_opportunity"}}}),
    ]) + "\n", encoding="utf-8")
    monkeypatch.setattr(paper_scorecard_report, "V76_RUNTIME_ROOT", runtime)

    report = build_paper_scorecard_report(runtime_dir=tmp_path / "empty_state")

    assert "v76 anti_chase" in report
    assert "tradingview_impulse_categories={'buy_opportunity': 1, 'avoid_long': 1}" in report
    assert "paper_candidate_if_other_gates_pass" in report
    assert "tv_impulse_exit_pnl={'buy_opportunity': 0.42}" in report
    assert "tv_impulse_exits={'buy_opportunity': 1}" in report
